この記事の結論
PHPのソースがそのままブラウザに表示されるのは、.htaccessのSetHandlerで、そのサーバーに無いハンドラ名を指定したためでした。当社のフォーム公開時の実例と、指定を消して直す手順、公開直後の3点確認をまとめました。
目次6項目
PHPのファイルを開くと、実行結果ではなくソースがそのまま表示される。この症状は、.htaccess の SetHandler で、そのサーバーに無いハンドラ名を指定したときに起きます。当社は2026年5月、問い合わせフォームのPHPでこれを起こしました。指定を消せば直ります。公開直後の確認手順もまとめます。
.htaccessのSetHandlerでPHPのソースが表示される原因:サーバーに無いハンドラ名を指定している
当社で起きた例では、.htaccess に次の3行を書いたことが原因でした。
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
.htaccessとは、Apache(Webサーバーのソフト)で、フォルダごとに設定を書き足すためのファイルのことです。レンタルサーバーでは、サーバー全体の設定を触れない代わりに、このファイルで一部の設定を変えられます。
ハンドラとは、Apacheが、呼ばれたファイルに対して「何をするか」を表す内部の名前のことです。Apacheの公式ドキュメントは、ふつうファイルはそのまま送られ、一部の種類のファイルだけが別に「処理」される、と説明しています。PHPのファイルを「中身を送る」のではなく「実行する」には、PHPを実行するハンドラに渡す必要があります。
SetHandler は、条件に合うファイルを、指定したハンドラで処理させる命令です。Apacheの公式ドキュメントによると、.htaccess にも書けます。<FilesMatch> は、ファイル名を正規表現で絞り込む囲みです。上の3行は「名前が .php で終わるファイルを、application/x-httpd-php というハンドラで処理せよ」という意味になります。
ややこしいのは、この3行が、Apacheの公式ドキュメントの SetHandler の説明に、例としてそのまま載っていることです。PHPの公式マニュアルでも、同じ形がインストール手順の中に出てきます。ただしPHPのマニュアルでは、PHPをApacheのモジュールとして読み込む(LoadModule)構成の手順の一部です。
mod_phpとは、PHPをApacheの中に組み込み、Apacheの一部として実行する方式のことです。上の書き方は、この方式のサーバーで意味を持ちます。一方、当社が使ったレンタルサーバーは、PHPをApacheの外の別のプログラム(php-cgi)として動かすFastCGI方式でした。FastCGI方式とは、Apacheが受けたリクエストを、常駐しているPHPのプログラムに渡して実行させる方式のことです。
当社が使ったサーバーには、application/x-httpd-php という名前のハンドラがありませんでした。当社の例では、Apacheは実行せずに、PHPのファイルを中身のまま返しました。存在しないハンドラ名を書いたときにApacheがどう振る舞うかは、Apacheの公式ドキュメントには書かれていません。ここは当社のサーバーで起きた結果として読んでください。
書き方ごとに、起きうることを整理します。
.htaccess の書き方 | 当社の環境で起きたこと・判断 | どうするか |
|---|---|---|
| PHPの指定を何も書かない | .php が実行された(サーバーの標準の動き) | これが正解。何も足さない |
SetHandler application/x-httpd-php(mod_php向けの書き方) | PHPのソースがそのまま返り、送信処理も止まった | 消す |
AddHandler で別の名前を指定する | 試していない。ハンドラ名がサーバーと合わなければ同じ種類の事故になりうる | 「念のため」で書かない |
別のサーバーから .htaccess を丸ごと持ってくる | 今回の事故の入口 | PHPに関わる行を消してから使う |
.htaccess が原因で起きるのは、ソースの表示だけではありません。同じファイルの書き方で 403 が出ることもあります。レンタルサーバーで 403 が出たときの切り分けは、さくらのレンタルサーバでWordPressの保存が403になる原因の早見表にまとめました。
PHPのソースが表示されたときの対処手順:ハンドラ指定を消して確かめ直す
- 今すぐ、該当の
.htaccessからPHPのハンドラ指定を消す。SetHandlerやAddHandlerで.phpを指定している行と、それを囲む<FilesMatch>です。ソースが外から読める状態なので、原因の調査より先に止めます。 - 消したファイルを、FTPソフトかサーバーの管理画面で上書きする。
.htaccessは名前が.で始まる隠しファイルです。Macでは見えないことがあり、当社ではFinderで⌘+Shift+.(ピリオド)を押して表示しています。FTPソフトも、隠しファイルを表示する設定にしないと、送ったつもりで送られていないことがあります。 - ブラウザか
curlでPHPのURLを開き直し、ソースが返らないことを確かめる。 本文に<?phpが見えたら、まだ直っていません。 - フォームを実際に送り、処理が通ることを確かめる。 確かめ方は、下の「公開直後の3点確認」に書きました。
- ソースが見えていた間に、外に出た情報を洗い出す。 ファイルに書いていた送信先のアドレスや、鍵・パスワードがあれば、それも見えたものとして扱います。
当社のサーバーで最終的に置いた .htaccess は、PHPについては何も指定しない形です。PHPの部分は、なぜ書かないのかをコメントで残しています。
# PHP の実行はサーバーの標準の動きに任せる。
# SetHandler / AddHandler は書かない(ハンドラ名が違うとソースが表示される)。
AddDefaultCharset UTF-8
コメントを残しているのは、後から触った人が「PHPの指定が抜けている」と思って足し直さないようにするためです。AddDefaultCharset は、Apacheの公式ドキュメントで .htaccess に書けると確かめた命令です。
裏方で実際に起きた例:問い合わせフォームのPHPが丸見えになった2026年5月
ここからは、僕の会社(株式会社UrakaTA)の社内の記録からの転記です。お客さんの案件なので、サイトが分かる情報は伏せています。
2026年5月、クライアントのLP(問い合わせフォーム付き)を公開しました。フォームの送信は、同じサーバーに置いたPHPのファイル1本で受けて、メールで知らせる作りです。
公開のとき、.htaccess に冒頭の3行を入れてアップしました。別の環境(mod_phpのサーバー)向けに書いていた設定を、そのまま持ち込んだ形です。「PHPが確実に動くように」という、念のための1行のつもりでした。
アップしたあと、フォームを受けるPHPのURLをブラウザで開いたところ、PHPのソースが全文そのまま返ってきました。ソースには、送信先のメールアドレスなどの内部の情報も入っていました。PHPが実行されていないので、入力の確認も、メールの送信も止まっていました。
原因を調べると、そのサーバーはPHPをphp-cgi(FastCGI方式)で動かしていて、application/x-httpd-php というハンドラが無いことが分かりました。直し方は、.htaccess からPHPの指定を消すだけです。消したあとは、.php がサーバーの標準の動きで実行され、フォームも動きました。
調べ始めてから直るまでにかかった時間は、記録に残していないので書きません。
この件で一番まずかったのは、「念のため」に足した設定が、何もしないより悪い結果を生んだことです。動いている環境の設定は、そのサーバーで動いた設定でしかありません。
PHPのソース露出を再発させない:公開直後の3点確認
この件のあと、当社ではPHPのフォームを公開したら、必ず次の3点を curl で確かめるようにしました。curl は、コマンドからURLを開き、返ってきた中身とステータスを表示する道具です。URLとフォームの項目名は例です。
# 1. 開いただけでソースが返らないか(ステータスと Content-Type も表示する)
curl -s -w "\n%{http_code} %{content_type}\n" https://example.com/contact.php
# 2. 空で送ったときに、入力エラーが返るか
curl -s -w "\n%{http_code}\n" -X POST https://example.com/contact.php
# 3. 必須の項目を入れて送ったときに、成功の応答が返るか
curl -s -w "\n%{http_code}\n" -X POST -d "name=TEST&tel=000" https://example.com/contact.php
| 確認 | 合格 | 不合格の例 |
|---|---|---|
| 1. 開くだけ | ソースが出ない。当社のフォームはJSONの応答とその Content-Type が返る作り | 本文に <?php が見える |
| 2. 空で送る | 入力エラーの応答が返る(当社のフォームは 422) | ソースが返る・成功と返る |
| 3. 正しく送る | 成功の応答が返り、知らせのメールが届く | エラーが返る・メールが届かない |
1だけでは足りません。ソースが返らなくても、処理の途中で止まっていることがあるからです。2と3まで通して、初めて「動いている」と言えます。3の送信は本物のメールが飛ぶので、送信先が自分たちの宛先になっているときに行います。
あわせて、次の2つも運用ルールにしました。
.htaccessにPHPのハンドラ指定を書かない。SetHandlerだけでなくAddHandlerも同じです。サーバーが標準で.phpを実行するなら、足すものはありません。- 別のサーバーの
.htaccessを持ち込むときは、1行ずつ意味を確かめる。 特に、ハンドラ・リダイレクト・アクセス制限の行です。
業務でレンタルサーバーの .htaccess を触るときの注意
ソースが見える事故は、情報の事故として扱う。 画面が崩れるのとは違い、外から読めた中身が残ります。送信先のアドレス、鍵やパスワードが書かれていたら、変更が要るかを判断します。お客さんのサイトなら、サーバーの契約者とフォームの持ち主に、何が・いつからいつまで見えていたかを報告します。
秘密の値を、公開フォルダのPHPに直接書かない。 今回のように、何かの拍子にPHPが実行されずに中身が返ることがあります。そうなっても困らない置き方を、作る段階で考えておきます。
.php 以外の拡張子のファイルを、公開フォルダに残さない。 作業の控えや、.php 以外の名前にした設定ファイルも、PHPとしては実行されず、中身がそのまま読めることがあります。当社は別の案件で、これを実際に起こしています(WAFの403をFTPで回避したときの記録の「業務でWAFを切る・FTPで回避するときの注意」に書きました)。
サーバーの仕様は、使っているサーバーの案内で確かめる。 PHPをどの方式で動かしているか、.htaccess で何を変えてよいかは、サーバーごとに違います。この記事に書いた挙動は、当社が使った1つのレンタルサーバーでの結果です。ほかのサーバーで同じ書き方をした記録はありません。
AIに .htaccess を書かせるときも、PHPの行は消して確かめる。 SetHandler application/x-httpd-php は公式ドキュメントにも例として載っている書き方なので、どこから持ってきても混ざりやすい1行です。AIに作らせた設定で起きたほかの困りごとは、Claude Codeのエラー・困りごと一覧から引けます。
「PHPのソースが表示される」「フォームを送っても何も起きない」というときは、下のフォームからご相談ください。.htaccess とサーバーの方式の確認から一緒に見ます。
よくある質問
SetHandlerを消したら、PHPは動かなくなりませんか?
当社の例では、消したことでPHPが実行されるようになりました。レンタルサーバーの多くは、サーバー側の設定で .php を実行する形になっていて、.htaccess での指定は要りません。消したあとに、ブラウザで開いてソースが返らないか、フォームの送信が通るかを必ず確かめてください。
AddHandlerなら書いても安全ですか?
安全とは言えません。Apacheの公式ドキュメントでは、AddHandlerは拡張子を指定したハンドラ名に結びつける命令です。ハンドラ名はサーバーの構成ごとに違うため、合わない名前を書けば同じ事故の元になります。当社は「念のため」で書かないことをルールにしています。
ソースが見えていた時間があった場合、何をすればいいですか?
まず指定を消して、ソースが返らないことを確かめます。そのうえで、ファイルに書いていた値(送信先のアドレスや、鍵・パスワードがあればそれも)は外に見えたものとして扱い、変更が必要かを判断します。サーバーの契約者と、フォームの持ち主への報告もします。