tohokuaikiのチラシの裏

技術的ネタとか。

PHPをモジュール版で動いてるところにpcntl拡張を使いたくてCGIでも動かそうとしたら、結構大変であわゎとなった

なんでCGI版でPHPを動かそうとしたかというと・・・

今どき、PHPCGIでもモジュール版でもどっちでも動くようなスクリプトを書けよって感じで開発環境による違いを意識したことは無かったんだけど、d:id:minahito_carpの日記になぜ私たちはRuby版XOOPS Cubeを開発したか (3) - minahitoの鯉日記という面白いエントリがあって、まぁネタばらしをしてしまうと、「PHPはスレッドが使えないのでRubyで検証しました」っていう話なんですが、

あれ?PHPってマルチスレッド使えるなんかなかったっけ?

っていう。

すると、pcntl extensionを使って一定個数の子プロセスに作業させる方法 - Blog::koyhogeっていう記事が見つかって「あぁ、この拡張モジュール入れれば」ってなったんですが、これCGIとしてPHPを動かしてないとダメっていう、そりゃApacheでやるにはちょーっと難しそうだなぁって素人ながらに思ったり。

ということで、CGI版でPHPを使えるようにしてみようと、手元のCentOS5でやってみました。

試行錯誤

普通に、CentOS5でPHPをインストールすると/usr/bin/php-cgiってのができる。んー、じゃあこれを使ってみる。

とりあえずプリミティブに動かしてみよう・・・ってことで
.htaccess

AddHandler cgi-script .php

cgi-test.php

#!/usr/bin/php-cgi
<?php
echo "hello";
?>

とかしてみた。・・・ら、普通に500エラーが出て動かない。。。・・・と、ファイルを755にし忘れてたのを思い出して、やってみると動いた・・が

#!/usr/bin/php-cgi
<?php
phpinfo();
?>

とかすると、また500・・・・。うーん、どうしようかなー・・・だいたいいちいち755とか#!〜って書くの面倒だし・・・思って違う方法を調べてみる。

とりあえずログとマニュアル読めよ

ってことで、ApacheErrorログを見てみる。こんなのが出てた。

[Mon Jun 01 **] [error] [client 192.**] Security Alert! The PHP CGI cannot be accessed directly.
[Mon Jun 01 **] [error] [client 192.**]
[Mon Jun 01 **] [error] [client 192.**]

This PHP CGI binary was compiled with force-cgi-redirect enabled. This
[Mon Jun 01 **] [error] [client 192.**] means that a page will only be served up if the REDIRECT_STATUS CGI variable is
[Mon Jun 01 **] [error] [client 192.**] set, e.g. via an Apache Action directive.

[Mon Jun 01 **] [error] [client 192.**]

For more information as to why this behaviour exists, see the manual page for CGI security.

[Mon Jun 01 **] [error] [client 192.**]

For more information about changing this behaviour or re-enabling this webserver,
[Mon Jun 01 **] [error] [client 192.**] consult the installation file that came with this distribution, or visit
[Mon Jun 01 **] [error] [client 192.**] the manual page.

[Mon Jun 01 **] [error] [client 192.**] Premature end of script headers: php.cgi

ありゃ、なんかPHPのマニュアル読めとか言われてる・・・。

ここらあたりから読んでると、ケース 2: --enable-force-cgi-redirect を使用っていうところで

Apache が標準ではないCGI 環境変数 REDIRECT_STATUS をセットすることを前提にしています。

って記述がある。この環境変数なんじゃねん?っておもってググると、cgi.force_redirect って何? - ぐらめぬ・ぜぷつぇんのはてダっていうエントリが見つかって、なるほどなるほどと熟読。

.htaccessでなんとかしよう

ということで、.htaccess

Action php-script /usr/bin/php-cgi
AddHandler php-script .php

って書いてみた。こうすると、自動的にリダイレクトされてPHPスクリプトをParseしてくれるらしい・・・なんて便利!って思ったんだけど、これで実行すると

Not Found
The requested URL /usr/bin/php-cgi/ドキュメントディレクトリ/test.php was not found on this server.

ってなる。

ん〜って思って、php-cgiをそのままドキュメントルート/usr/bin/php-cgiとかに置いたら、ブラウザに延々とバイナリが表示されちゃった。(苦笑)


あれ〜そういえば、CGIってどこでも動くのかなぁ・・・とか思って、Perlでちょろっと書いたらどこでも動く・・・。うーん???ま、そりゃドキュメントルートで+ExecCGIしてるから当然と言えば当然か。

マニュアル通りにやってみるとうまくいった

マニュアルには、

Action php-script /cgi-bin/php
AddHandler php-script .php

って書いてある。

これでやると、/cgi-bin/は普通にDocumentRoot/cgi-binかな〜って思ったんだけど、httpd.confで

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

ってやってるから、DocumentRoot内にはいかない(デフォルトの/var/www/はDocumentRootにしていない)。なんで、/var/www/cgi-binにphp-cgiをコピーしてやる。

すると、上手くいった。何でなんか、よくわからん。

動作原理からすると

結局、/var/www/cgi-bin/php-cgiを動作させていて、その動作対象ファイルはURLから取ってくるんだけど、じゃあっていうので、
http://*********/cgi-bin/php-cgi
とか直接はアクセスできないようになっている。そりゃ、それができたら、PHP

pcntlをインストール

簡単にPeclとかPearでインストールできるんかな〜って思ったら出来ない。

phprmpsというプロジェクトも過去にあったみたいだけど、今は無いみたい。

PHPマニュアルのインストール手順を読むと

プロセス制御機能を有効にするには、 configure のオプションに --enable-pcntl を付け、CGI 版あるいは CLI 版の PHPコンパイルする必要があります。

ってある。


んー、って思ってPHPの過去のアーカイブからCentOSで使ってる5.1.6を落としてきてソースのextからphpizeして・・・ってこれ、モジュール版のやり方じゃん!って思って今一度CGI版のPHPINFOを見てみると

あ・・・。すでに入ってた。。。。