phpをApacheで動かす際に気になったこと

php公式推奨の方法は

AddType application/x-httpd-php php

のようだ。(Ref: PHP: Apache 2.0 (Unixシステム用) - Manual)

例えばmod_pythonなら、

AddHandler mod_python .py

である。(Ref: 3.1 A Quick Start with the Publisher Handler)

phpも実際はmod_pythonのように.phpファイルを読み込んで処理して返すわけで、ハンドラとしての機能を内蔵しているはずである。 なのに、なぜAddHandlerでないのだろうということ、また、AddHandlerで指定するハンドラ名がGoogleで調べるとばらばらなのはなぜか、ということが気になったのでちょっと調べてみた。

phpはなぜAddHandlerを使わないか

実際、

AddType application/x-httpd-php php
AddHandler application/x-httpd-php php
AddHandler php5-script php

これらのどれを指定しても動作する。 phpのマニュアルにはこれらを一覧して、特に最初のAddTypeの書式を用いるべし、という内容の項目はない。

ただ、「Apache のコンテントネゴシエーション(!MultiViews オプション)を PHP で使用することはできますか?」という項目で、

# PHP 4
AddHandler php-script php
AddType text/html php

# PHP 5
AddHandler php5-script php
AddType text/html php

という記述をすることで、MultiViews下で正しく動作する、と書かれている。

これは例えば http://example.com/ をホストしているApacheで、

DocumentRoot "/usr/local/www/apache22/data"

LoadModle php5_module libexec/apache22/libphp5.so

<Directory /usr/local/www/apache22/data >
	Options +MultiViews
	AddHandler php5-script php
	AddType text/html php
</Directory>

となっているとき、/usr/local/www/apache22/data/foo.php があれば、http://example.com/foo というURLでアクセスすると自動的に foo.php が表示される、という機能である。 もし、

<Directory /usr/local/www/apache22/data >
	Options +MultiViews
	AddType application/x-httpd-php php
</Directory>

であると、例えばGoogleBotなどで406になってしまうようだ。 (Ref: drry+@-> 406 Not Acceptable on MultiViews with PHP)

但し、このAddHandler php5-script phpを使う方法はApache1では使えないと書かれている。

また、phpには

AddType application/x-httpd-php-source phps

と書くことで、.phpsのphpソースコードを色付けして表示する機能も提供している。

Apache1でも動作し、AddTypeで統一できるという観点からAddType application/x-httpd-php phpという記法をベースにマニュアルがかかれているのかもしれない。

AddHandlerで指定するハンドラの名前が一定しないのはなぜか

phpなら、

AddType application/x-httpd-php php
AddHandler application/x-httpd-php php
AddHandler php5-script php

mod_pythonなら、

AddHandler python-program py
AddHandler mod_python py

これらどれでも動いてしまうため、AddHandlerに指定すべきhandler-nameをGoogleなどで調べていると正直混乱する。

基本的にAddHandlerで指定するhandler-nameはモジュールが提供するハンドラであればモジュールに組み込まれている。 ので、そのモジュールのマニュアルに書いてあるはずである。

ただ、pythonとphpのマニュアルを見た範囲では、「AddHandlerで指定すべき名前」という直球の項目はない。 両者とも、チュートリアルには一応書かれているので、今後、こういうときには、マニュアルのチュートリアルに書かれているApacheのディレクティブの書式に従うのがよいようだ。

phpの場合は基本AddType式、MultiViewsを使うときはAddHandler php5-script式というのは前述のとおり。 pythonの場合はmod_pythonを使うべきで、python-programは古い形式のようだ。 (Ref: [mod_python] mod_python or python-program)

マニュアルにも書かれていないような場合は、LoadModuleされているモジュールファイルをstringしてそれっぽい名前を使ってみれば動くかもしれない。