ホームページ制作覚書

その他

futomi’s CGI Cafeさんの高機能アクセス解析 CGI Professional 版を使い続けるための修正

futomi’s CGI Cafeさんのアクセス解析を20年ほど使い続けているのですが、このほどエックスサーバーの新サーバに移行したら500エラーになってしまいました。パーミッションの設定は問題なさそう。

GA4も使っているけど、長年使ってきて愛着もあるアクセス解析を使えなくなるのは悲しい。

結論を先に述べると、新サーバーに移行してPerlのバージョンが変わったことで、これまでのコードが非推奨になったようです。(従来のPerlバージョンは5.16。新サーバーは5.26、5.16。試していないけど、/usr/bin/perlを/usr/bin/perl516にするだけでも良かったっぽい。/usr/bin/perlだと5.26)

まずはサーバーのエラーログを確認してみました。

  • Compilation failed in require at acc.cgi line 11
  • Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?) at lib/CGI.pm line 451

この2つの記述ありました。

acc.cgi line 11にあるのは use CGI; という記述だけ。
そうやらuse CGI; の行で読み込まれている CGI.pm モジュール内で、問題のある require ステートメントがある可能性があるっぽい。

lib/CGI.pm line 451

if (defined(@QUERY_PARAM) && !defined($initializer)) {

新しいPerlバージョンでは非推奨とされているdefined(@array)の形式が使われています。Perl 5.22以降でこの形式を使用すると、エラーが発生します。Perlのドキュメントによると、配列やハッシュに対してdefined()を使用することは推奨されません。この関数はスカラー値に対してのみ使用するべきです。

この問題を解決するには、defined(@QUERY_PARAM)の使用を削除または変更する必要があります。@QUERY_PARAMが要素を持つかどうかのみをチェックする場合は、以下のように修正できます:

下記のとおり修正。

if (@QUERY_PARAM && !defined($initializer)) {

この変更により、@QUERY_PARAMが空でないことを確認し、$initializerが定義されていないことを確認します。これはdefined(@array)の使用を削除することで、新しいバージョンのPerlでもエラーなく動作するようになります。

これで500エラーは解消されましたが、次に下記のようなエラーが。

oftware error:

Can’t use ‘defined(%hash)’ (Maybe you should just omit the defined()?) at ./lib/jcode.pl line 684.
For help, please send mail to the webmaster (XXXX), giving this error message and the time and date of the error.

Software error:

[Fri Jul 19 21:42:17 2024] acc.cgi: Can’t use ‘defined(%hash)’ (Maybe you should just omit the defined()?) at ./lib/jcode.pl line 684.
Compilation failed in require at acc.cgi line 14.
For help, please send mail to the webmaster (xxxx), giving this error message and the time and date of the error.

今度は./lib/jcode.plファイルの684行目でdefined(%hash)を使用しているために問題が発生しています。Perlの新しいバージョンでは、ハッシュに対してdefined()を使うことが非推奨とされ、エラーを引き起こす原因となっています。

修正前(./lib/jcode.plファイルの684行目)

&init_z2h_euc unless defined %z2h_euc;

修正後(./lib/jcode.plファイルの684行目)

&init_z2h_euc unless %z2h_euc;

この変更により、ハッシュ%z2h_eucが空(キーが一つもない)場合にのみ、init_z2h_eucサブルーチンが呼び出されます。ハッシュが空の場合、条件は真と評価され、サブルーチンが実行されます。

次も同じようなエラーが出ました。

Software error:

Can’t use ‘defined(%hash)’ (Maybe you should just omit the defined()?) at ./lib/jcode.pl line 693.
For help, please send mail to the webmaster (XXXX), giving this error message and the time and date of the error.

Software error:

[Fri Jul 19 21:44:11 2024] acc.cgi: Can’t use ‘defined(%hash)’ (Maybe you should just omit the defined()?) at ./lib/jcode.pl line 693.
Compilation failed in require at acc.cgi line 14.
For help, please send mail to the webmaster (XXXX), giving this error message and the time and date of the error.

次に示されたエラーも同様の問題で、defined(%hash) の使用が非推奨とされているために発生しています。これも修正する必要があります。修正するには、defined(%hash)の部分を削除または適切な形に変更する必要があります。

defined(%hash)if (%hash) のように変更することで、ハッシュが空でないかどうかをチェックします。これは684行目で行った修正と同じアプローチです。

修正前(./lib/jcode.plファイルの693行目)

&init_h2z_euc unless defined %h2z_euc;

修正後(./lib/jcode.plファイルの693行目)

&init_h2z_euc unless %h2z_euc;

この変更により、%z2h_sjisハッシュが空(つまり要素を持たない)場合にのみ、init_z2h_sjisサブルーチンが呼び出されます。ハッシュが空でない場合(つまり一つ以上のキーを持つ場合)は、サブルーチンは実行されません。

これで無事に使えるようになりました!

TAG : 

CATEGORY : 

Arrival