[初回公開] 2020年05月27日
CGI の Perl は最近ではあまり利用されなくなったプログラム言語だが、今でもウェブサイトやシステムでは稼働中のところがあるものの新しいサーバで動作させるとブラウザに「500 Internal Server Error」が表示され「defined(%hash) is deprecated」のエラーで正常動作しない場合の対応方法について紹介する。
このページの目次
1.Perl で「500 Internal Server Error」が表示されたときの原因調査方法
Perl で「500 Internal Server Error」が表示されたときの原因調査方法としては、ウェブサーバのログを確認する。
同じ CGI の PHP は設定によりブラウザにエラー内容を表示することができるが、Perl はブラウザにエラーが表示されないため調査にはログを参照するか手段がない。
また、ブラウザによっては HTTP のステータスコードが 500 の場合は真っ白になり何も表示されないことがある。
そのため、HTTP ステータスコードが 500 以外のエラーも考えられるため、利用しているブラウザの開発者モードで HTTP ステータスコードを確認することも必要になる。
2.Perl のエラーログの確認方法
Perl のエラーログの確認方法としては、ウェブサーバのログファイルを参照する。
ログファイルは利用しているサーバ環境によって違うが、多くはディレクトリ「httpd」内にアクセスログとエラーログで分かれていることが多い。
ウェブサーバが Apache の場合はディレクトリ「/var/log/httpd/」内にあるエラーログファイル(error_log)を参照する。
エラーログのファイルは FTP でダウンロードしたり、SSH によるコマンド操作で閲覧が可能で、一例として下記のように記述されることがある。
defined(%hash) is deprecated at ./jcode.pl line ***)
エラーログにはエラーになった原因の他、エラーとなったプログラムファイル名とプログラムの箇所(行数)を把握することができる。
3.エラー「defined(%hash) is deprecated」の原因
前述の例に挙げたエラー「defined(%hash) is deprecated」の原因は、プログラムとして記述している関数 defined(%hash) が非推奨になっていることを示している。
これは Perl のバージョンが上がったことにより発生するもので、レンタルサーバなどホスティングではサーバ運営者が Perl をアップデートしたり、新しいサーバ OS に移設する場合は常に最新版の Perl がインストールされるため、これまで動作していたプログラムファイルが対応できずにエラーになる。
4.エラー「defined(%hash) is deprecated」の対応方法
エラー「defined(%hash) is deprecated」の対応方法としては、define を利用しないようにして連想配列の使い方を変更する。
Perl の「連想配列」は hash(ハッシュ)と呼ばれ、変数名の前に % を付与して表す。
Perl に用意されている関数 defined は引数の値が定義されているかを True か False で返すものだが、Perl のバージョンが上がったことで非推奨となった
そのため、文字コードを取り扱うライブラリ jcode.pl のプログラムでは下記の 2 箇所から下記のように削除する。
sub z2h_euc {
local(*s, $n) = @_;
&init_z2h_euc unless defined %z2h_euc;
$s =~ s/($re_euc_c|$re_euc_kana)/$z2h_euc{$1} ? ($n++, $z2h_euc{$1}) : $1/geo;
$n;
}
↓
sub z2h_euc {
local(*s, $n) = @_;
&init_z2h_euc if !%z2h_euc;
$s =~ s/($re_euc_c|$re_euc_kana)/$z2h_euc{$1} ? ($n++, $z2h_euc{$1}) : $1/geo;
$n;
}
sub z2h_sjis {
local(*s, $n) = @_;
&init_z2h_sjis unless defined %z2h_sjis;
$s =~ s/($re_sjis_c)/$z2h_sjis{$1} ? ($n++, $z2h_sjis{$1}) : $1/geo;
$n;
}
↓
sub z2h_sjis {
local(*s, $n) = @_;
&init_z2h_sjis if !%z2h_sjis;
$s =~ s/($re_sjis_c)/$z2h_sjis{$1} ? ($n++, $z2h_sjis{$1}) : $1/geo;
$n;
}
また、jcode.pl の define の前に「unless」があり、これは条件式が偽の場合に処理させたいときに記述する。
unless も Perl の最新バージョンでは利用できなくなる恐れがあるため、if 文で否定条件を示す ! を連想配列の前に付けている。
もし「defined」を消すだけであれば連想配列の前の ! は不要となる。
関連記事
Word や Excel を電子書籍ファイルフォーマットの EPUB へ変換する方法
書籍が電子化されてパソコンやスマートフォンで読むことができる時代になり、書籍を出版する側としても電子化されることで印刷と製本といったコストが大幅に削減できるメリットがある反面、電子書籍の仕組…
Postfix で Illegal address syntax from unknown のエラーが出る場合の対応方法
メールサーバの Postfix は正常に通信できた場合でも何らかの問題で配信できない場合もログ(maillog)に痕跡が残るようになっているが、そのログの中に「Illegal address syntax from unknown」とあり…
【初心者向け】リモート会議や授業・面接に利用される Zoom の基本的な利用方法
コロナ禍の中、企業では出勤や客先への訪問を避けるべく打ち合わせやセミナー、商談に至るまでテレビ会議を用いることが多く、大学や高校の授業でもリモート講義を取り入れているが、Zoom を利用したリモ…