mod_perl でも動作するCGIを書く

PerlCGIの高速化と言えば mod_perl であるが、たいていは後付けで PerlHandler に Apache::Registry やら Apache::PerlRun を指定する方法が紹介されている。

けれど、すでにオブジェクト指向スタイルでCGIを書いているのであれば、入り口を mod_perl のハンドラにして「CGIとしても動作する mod_perl ハンドラ」としてしまえばよい。通常 mod_perl ハンドラではリクエストの取得に $r オブジェクトを使用するが、CGI.pm を使用すれば、通常のCGI同様に環境変数をセットしてくれるし、CGI.pm の各種メソッドもCGIのときと同じように使用できる。

具体的には、パッケージ My::APP を mod_perl ハンドラにするのであれば、My::App のメソッド handler() を入り口とする以下のようなスタイルでCGIを書く。

#!/usr/bin/perl -Tw

use lib '/path_to_myapp';
use My::APP;

My::APP::handler;

これを mod_perl で動作させるには、Apacheに以下の設定を追加すればよい。

PerlSwitches -Tw
<Perl>
    use lib '/path_to_myapp';
</Perl>
<Location /path_to_cgi>
    SetHandler      perl-script
    PerlHandler     My::App
</Location>

/path_to_myapp は My::App を配置するパス*1、/path_to_cgi は My::App を動作させる Apache 上でのパスを指定する。

これでデバッグ時はCGI、運用時は mod_perl とすることができる。

注意しなければならないことは(Apache::Registry を使った場合も同じだけど)、グローバル変数を使わないことくらいかな。

*1:通常はシステムのパスにはインストールしないだろうから