My Daily Programming Life...

ApacheとSSIとPHP

PHPをSSIでインクルードしたい場合にはどうしたらよいのか。今回いろいろ試したので書いておこうと思う。Apacheのバージョンは2.2.3で試した。foo.html内にfoo.phpをインクルードするとする。

---Apacheの関係する設定---
OptionsにIncludesは必須。これは普通のSSIと同じ。さて、ここで二つの場合がある。
Includesが指定されている場合 - すべてのSSIコマンドが使える。重要なのは<!--#exec cmd=... -->、<!--#exec cgi=...-->、<!--#include virtual=...-->の三つ。これらすべてが使える。 IncludesNoExecが指定されている場合 - 上記三つのうち、<!--#exec ...-->の二つのコマンドは利用できない。<!--#include virtual=...-->のみが使える。共用サーバーではよくある設定。

--- foo.htmlの設定---
SSI を利用するためには、どこかでAddHandlerを指定しないといけない。共用サーバーなら、.htaccessに書くことになる。パフォーマンス上は 良くないらしいけど、僕はshtmlという拡張子が好きじゃないので、.htmlをすべてSSI有効にしている。つまり以下のようになっている。アクセス のある程度多いWebならshtmlにして別にしたほうがいいと思う。 AddHander server-parsed .html これで.htmlファイルはすべてSSIが有効になって、<!--#....-->の部分が解析されるようになる。 foo.htmlの中身については後述。

--- foo.phpの設定とその中身 ---
.htaccess にAddHander php-script .phpとか書いておけば、通常PHPファイルはApacheがそれを.phpをPHPモジュールで処理してくれる。重要なのはこの場合実行属性は必要な いということ。ただし、今回は、CGIとして実行するわけで、PHPモジュールは動かない。と言うわけで、コマンドラインのPHPを使うことになる。 つまり、コマンドラインで
>./foo.php [ENTER]
として実行ときの実行結果が返されることになる。さて、普通の PHPファイルは実行属性はついていないので当然実行することはできない。なので755あたりのパーミションに変更する。これでうまくいくかというとそう いうわけにもいかず、スクリプトの最初の行に必要に#!/usr/bin/phpが必要になる。これがないとこのスクリプトを何で処理して良いのか分から ないので、うまくいかない。 というわけで、foo.phpはパーミッション755を付けて、中身はたとえばこんな感じ #!/usr/bin/php

--- foo.htmlの中身---
PHPのファイルをSSIでインクルードするにはどの方法が使えるのか。考えられるのはだいたい次のコマンド。 <!--#exec cgi="foo.php" -->
<!--#exec cmd="./foo.php" -->
<!--#exec cmd="php foo.php" -->
<!--#include virtual="foo.php" --> さて、まずはこれらすべてのコマンドが使えるという状況で、それぞれの違いについて。細かい違いはバージョンやプラットフォームで違うらしいので、重要なところだけ。
<!--#exec cgi="foo.php" -->の場合、PHPでContent-type: text/htmlを出力しないといけない。そうでないと失敗する。
<!--#exec cmd="foo.php"-->の場合は、Content-type: text/htmlの出力は必要ない。さらに引数を取ることもプラットフォームによっては可能らしい。<!--#exec cmd="foo.php arg1 arg2" -->のように。ただしSuexecを使っているUNIXやWin32では利用不可らしい・・・。
<!--#exec cmd="php foo.php" -->は、一応利用可能っぽいが、やっぱりSuexecが有効の場合にはつかえないっぽい。
<!--#include virtual="foo.php" -->はContent-typeの出力は必要ない。さらに引数も<!--#include virtual="foo.php?arg1=var1"-->というように指定可能らしい。

--- さらに設定が・・・ ---
こ れですべてうまくいくはずが、まだ考えなくてはいけないことがあった。IncludesNoExecを指定されている場 合、<!--#include virtual="foo.php"-->でしていするファイルのMimeタイプが重要になってくる。普通.phpファイルはMimeタイプとして

AddType application/x-httpd-php .php

の ように指定されている。ApacheはIncludesNoExecを処理するとき、その対象ファイルのMimeタイプを見て、それがtext/*でない とエラーにするというようになっている。なぜかは分からないがセキュリティ上の都合だろうか。そのままfoo.phpをvirtualに指定すると
unable to include potential exec
というエラーが出てしまう。直訳すると「潜在的なExecはインクルードできない」となる。これの対処方法は二つ。一つはfoo.phpをfoo.cgiにしてしまうこと。こうするとfoo.cgiは普通に実行されてその結果が返る。た だ、どうしてもphpファイルの拡張子は.phpがよいと感じたので、その方法も探った。まあ、簡単なことだけど、foo.phpのあるフォルダ の.htaccessに AddHander cgi-script .php
AddType text/html .php の2行を書く。ただしこうすると、そのフォルダ内のPHPは普通のPHPとしては動かなくなるので注意。

--- まとめ ---
PHPをSSIでインクルードするにはCGIでPHPを動かす。
PHPファイルには#!/usr/bin/phpといった1行目が必要。
PHPファイルには実行権限を付ける
IncludesNoExec下で、<!--#include virtual=...-->でインクルードする場合は、拡張子を.cgiにするか、AddHander,AddTypeの二つを用いて、.phpの扱いを変更する。

--- その後追記 ---
こちらをご覧ください

0 コメント:

Post a Comment

feedSubscribe to my feed