XAMPPでテスト中、「test.html」というHTMLファイルにPHPを記述したところ、PHPが実行されませんでした。
「あれ?HTMLにPHP書いて動作しなかったっけ?昔のXAMPPは何もせずに動いていた気が…。」と疑問に思ったので調べてみました。
拡張子htmlのファイルでPHPを実行する方法
http.confを編集できる場合
C:\xampp\apache\conf\http.confの最後の行に以下を追加します。
AddType application/x-httpd-php .php .html
これで動作しない場合は以下の記述に変更してみてください。
AddHandler application/x-httpd-php .php .html
あとはXAMPP Control PanelでApacheを再起動すれば、拡張子がhtmlのファイルでPHPが実行できるはずです。
.htaccessしかいじれない場合
「http.conf」をいじることができないレンタルサーバなどで、PHPがCGI版のものを利用している場合は「.htaccess」以下のように書きます。
# PHPのバージョンがが5の場合 AddHandler php5-script .htm .html
「php5-script」の部分はバージョンに合わせて「php5.4-script」等と書き換える。
さくらインターネットの場合
「さくらのレンタルサーバ」の場合は上の記述に加えて、「.htaccess」へ以下の記述を追加する必要がある。
Action myphp-script /php.cgi AddHandler myphp-script .html .php
上記の設定でも動かない場合
.htaccessでAddHandlerやAddTypeが禁止されていることもある。
そのような場合はディレクティブ(ファイル)を限定して以下のようにすると動作する場合もある。
<Files "hoge.html"> AddHandler x-httpd-php5.6 .php .html </Files>
これらの対策で拡張子.htmlのファイルでPHPが実行できるようになります。
と、普通ならここで終わるところですが、このページでは詳しい仕組みと問題点について解説を続けます。
AddTypeディレクティブについて
上の解説で出てきた以下の処理は何を意味するのでしょうか。
AddType application/x-httpd-php .php .html
AddTypeについての解説はApacheの公式ドキュメントにあります。
構文は以下の通り。
AddType MIME-type extension [extension]
「AddType ディレクティブは、 与えられた拡張子を指定されたコンテントタイプにマップします。」とのこと。
指定されたコンテントタイプとは書式でいう「MIME-type」のことで、拡張子は「extension」のことです。マップとはマッピング(関連付け)のことです。
つまり「MIME-typeと拡張子を関連付けます。」という意味です。
上の例で言えばMIMEタイプが「application/x-httpd-php」で、実行する拡張子は「.php」と「.html」という関連付けを行った。ということです。
ちなみに拡張子は大文字小文字を区別せず、ドットもあってもなくても構いません。
MIMEタイプについて
この解説をご覧の方の中には「MIMEタイプって何?」という方も多いのではないでしょうか。
MIMEタイプとはファイルの種類を伝えるための仕組みです。windowsであれば拡張子でファイルの種類を識別できますが、htmlサーバにはそのような仕組みがないため、MIMEタイプでファイルの種類を伝える必要があります。
構文は以下の通り、タイプと、サブタイプで構成されています。
type/subtype
Webでよく使われるタイプは主に以下のものがあります。
type | 説明 | 例 |
---|---|---|
text | テキストファイル | text/plain, text/css, text/html |
image | 画像ファイル | image/gif, image/jpeg, image/png, image/svg+xml |
audio | 音声ファイル | audio/wave, audio/wav, audio/ogg |
video | 動画ファイル | video/webm, video/ogg |
application | バイナリーデータ | application/perl, application/x-httpd-php, application/ruby, application/rdf+xml |
これらMIMEタイプはIANA(アイアナ)というプロジェクトで管理されています。
Media Typesというページで一覧が公開されています。
一覧を見ていただければ分かる通り、膨大な量です。例えばapplicationの項目だけでも2018年2月現在で1200以上の項目があります。
とても網羅できる量ではないので、必要な時にリストを見ながら目的のMIMEタイプを探せれば十分だと思います。
AddHandlerディレクティブについて
AddHandlerの場合は以下の通りでした。
AddHandler application/x-httpd-php .php .html
構文は以下の通り。
AddHandler handler-name extension [extension]
基本的にはAddTypeと同じです。MIME-typeの部分がhandler-nameとなっているだけです。
ハンドラについては「Apache のハンドラの使用」というページがありますが、まるで難解なロシア文学のようで、何度読み返しても理解できません。
要は、Apache独自の関連付けを行う際に利用するのが「ハンドラ」。ファイルとAddTypeとは違うもう一つの関連付けの方法。複数の拡張子を持つもにも対応できる。というもののようです。
デフォルトで以下のものがサポートされているとのこと。
type | 説明 | 例 |
---|---|---|
default-handler | default_handelr() を使ってファイルを送ります。 静的なコンテンツを扱うときにデフォルトで使用されるハンドラです。 | core |
send-as-is | HTTP ヘッダのあるファイルをそのまま送ります。 | mod_asis |
cgi-script | ファイルを CGI スクリプトとして扱います。 | mod_cgi |
imap-file | イメージマップのルールファイルとして解析します。 | mod_imap |
server-info | サーバの設定情報を取得します。 | mod_info |
server-status | サーバの状態報告を取得します。 | mod_status |
type-map | コンテントネゴシエーションのためのタイプマップとして解析します。 | mod_negotiation |
AddTypeやAddHandlerを利用してPHPを実行することの注意点
PHP以外のファイルでPHPを実行する方法を解説してきましたが、実は2つのデメリットがあります。
1つ目は、全てのHTML文章がPHPとして解釈されるためレスポンスが落ちるというものです。ただしこれは微々たる差です。
もう一つの問題が重要で、セキュリティに関するものです。
以下のブログで解説されています。
ApacheのAddHandlerはセキュリティ上の懸念から使用すべきではない – Dマイナー志向
このブログではAddHandlerについてですが、AddTypeも同じです。
AddTypeやAddHandlerには謎の仕様があります。「ドットで繋いだ文章を、拡張子が複数あるファイルと解釈する」というものです。
たとえば「hoge.php.html」というファイルがあると、「.php」と「.html」という2つの拡張子を持つファイルと認識します。つまりPHPとして実行しつつ、HTMLファイルとしても実行します。
それでいて「hoge.php_html.txt」となっていた場合は「.php_html」と「.txt」と解釈されるためPHPは実行されません。間違いを起こしてくれと言わんばかりの実装です。
入力フォームなどで「hoge.php.txt」や「hoge.php.jpg」といったファイルを送られた場合、PHPファイルとして実行してしまうという事故も起きかねません。
公式サイトでは解決策として「foo.html.cgi」をCGIスクリプトとして処理したいけれども、「bar.cgi.html」は CGIスクリプトとしては処理したくない場合は以下のようにしてくださいとのこと。
<FilesMatch \.cgi$> SetHandler cgi-script </FilesMatch>
こうすればファイルの末尾がcgiのときにだけ、cgi-scriptとして実行されます。
上で紹介したサイトの解説にもありましたが、実はこの設定、mod_phpで提供されているデフォルトの設定ファイル「php.conf」でも記述されています。
AddHandler php5-script .php AddType text/html .php
そのため、上の例と同じように、以下のような書き換えが推奨されます。
<FilesMatch "\.php$"> AddHandler php5-script .php AddType text/html .php </FilesMatch>
結論
そもそも全てのhtmlファイルでPHPを実行するのは悪手。セキュリティ上の脅威にもなりかねない。
そのため「ファイル名を変えるのが面倒」といった程度の動機なら、素直に拡張子を.phpに変更するべき。
どうしても使いたいなら以下のように拡張子やディレクトリ・ファイルを限定する。
<FilesMatch "\.html$"> AddType application/x-httpd-php .html </FilesMatch>
<Files "hoge.html"> AddHandler x-httpd-php5.6 .php .html </Files>
ところどころMIMEではなくMINIタイプになってますよ。
ご指摘ありがとうございます。修正しました。
>MINIタイプについて
途中から「MINI」表記が連打されてますが、MIMEタイプの間違いでは?
本当ですね。修正しました。失礼しました。