IISにPHPアプリを配置してアクセスしたら、
このページが見つかりません HTTP ERROR 404
と表示された。
このとき、いきなりRewriteやPHPの設定を片っ端から触るより、
「どこまで正常に動いているか」
を順番に確認した方が切り分けやすい。
今回、Windows Server + IIS + PHP + CodeIgniterの環境を構築したときに実際に404でハマったので、そのときの確認方法を整理しておく。
実際にハマった流れはこちら。
まず確認する順番
今回の構成では、大きく分けるとこうなっていた。
ブラウザ↓IIS↓FastCGI↓PHP↓index.php↓CodeIgniter↓DB404が出たときに重要なのは、
この中のどこで止まっているのかを確認すること。
自分の場合、最初はIIS周辺をかなり調べたけど、最終的には index.php まで正常に到達していた。
なので今なら、次の順番で確認する。
1. 静的ファイルが表示できるか2. PHP単体が動くか3. index.phpまで到達しているか4. アプリ側を確認する5. DB接続など外部依存を確認する順番に見ていく。
1. 静的ファイルが表示できるか
まずPHPは置いておいて、IISが普通のファイルを配信できるか確認する。
たとえばIISの公開ディレクトリが、
C:\inetpub\wwwrootなら、そこにテストファイルを作る。
PowerShellなら、
Set-Content -Path "C:\inetpub\wwwroot\iis-test.txt" -Value "IIS TEST"ブラウザから、
http://localhost/iis-test.txtへアクセスする。
IIS TEST と表示されれば、少なくともIISからそのファイルまでは到達できている。
ここで表示できないなら、まだPHPを疑う段階ではない。
IISのサイト設定、物理パス、ファイルの存在など、IIS側から確認する。
2. 本当にそのファイルは存在するか
かなり基本的な話だけど、先にやっておいた方がいい。
PowerShellで、
Test-Path C:\inetpub\wwwroot\index.phpを実行する。
存在すれば、
Trueが返る。
今回の調査では、PHPの確認用ファイルを、
info.phpという名前で作っていたのに、
http://localhost/phpinfo.phpへアクセスしていた。
当然404になる。
IISの詳細エラーには、
404.00x80070002と出ていた。
いろいろ設定を疑う前に、
「そのURLのファイル、本当にその名前で存在する?」
は確認しておいた方がいい。
地味だけど、ここで結構な時間を溶かした。
3. PHP単体が動くか
静的ファイルが表示できたら、次はPHP。
たとえば、
C:\inetpub\wwwroot\info.phpを作って、
<?php phpinfo();とする。
ブラウザから、
http://localhost/info.phpへアクセス。
PHP情報が表示されれば、
IIS↓FastCGI↓PHPまでは動いていると判断できる。
ここでPHPが動かない場合は、アプリ側へ進む前にIISのPHP設定を確認する。
今回の環境では、IISのハンドラーマッピングを次のように設定していた。
要求パス: *.phpモジュール: FastCgiModule実行可能ファイル: C:\PHP\7.3.33\php-cgi.exePHP自体が起動するかは、コマンドでも確認できる。
php.exe -v今回、この時点でも一度ハマった。
PHP 7.3.33のWindows版を配置した直後は php.exe -v が正常に動かず、Visual C++ Redistributableをインストールすると起動するようになった。
なのでPHP単体が動いていないなら、FastCGIだけでなくPHPそのものが実行できるかも確認する。
4. index.phpまで届いているか
PHP単体は動く。
index.php も存在する。
それでもアプリへアクセスすると、
ページが見つかりません
となる。
ここでIISの設定を延々と調べる前に、
本当に index.php まで届いていないのか
を確認する。
一時的に index.php の先頭へ、
<?phpecho 'INDEX OK';exit;を入れる。
ブラウザからアクセスして、
INDEX OKと表示されたら、
IIS↓FastCGI↓PHP↓index.phpまでは正常。
つまり、少なくとも、
「IISがindex.phpを見つけられない」
という問題ではない。
この確認は今回かなり効いた。
404を見てIIS周辺を調べていたけど、実際には index.php まで普通に処理が来ていた。
確認が終わったら、追加した echo と exit は戻しておく。
5. ここまで通ったらアプリ側を見る
index.php まで正常に届いているなら、次はCodeIgniterなどアプリ側の確認へ進む。
今回なら、
IIS↓FastCGI↓PHP↓index.php ← ここまで確認済み↓CodeIgniterという状態。
この時点でIISの物理パスやPHPハンドラーを何度確認しても、原因には近づきにくい。
アプリのルーティングや設定、ログなど、index.php より後ろを見る。
CodeIgniter 3なら、ログの出力先として、
application/logs/も確認対象になる。
ログが出ない場合は、application/config/config.php の、
$config['log_threshold']や、IISのApplication Poolからログディレクトリへ書き込める権限があるかも確認する。
6. DB接続なども確認する
アプリ自体が動き始めたら、DBなどアプリが依存している先も確認する。
今回の環境では、最終的にDB接続まわりがうまくいっていなかった。
そこを修正すると、アプリの画面まで表示されるようになった。
ただし今回については、
DB接続エラーそのものが404を返していたのか、DB接続に失敗した結果としてアプリ側の別処理が404を返していたのかまでは確認できていない。
なので、
IISで404が出たらDBを直せばいい
という話ではない。
重要なのは、index.php まで届いていると分かった時点で、
IISの問題だけを追うのをやめて、
アプリDBその他の依存先まで調査範囲を移すこと。
web.configで500.19が出る場合
今回、404になる前には、
500.19も発生した。
原因は web.config にRewriteの設定があるのに、IISへURL Rewrite Moduleを入れていなかったことだった。
web.config に、
<rewrite> ...</rewrite>がある場合、IIS側でURL Rewrite Moduleが利用できる状態か確認する。
今回の場合はURL Rewrite Moduleをインストールすると500.19は解消した。
ただし、その後に404が出た。
つまり、
500.19が消えた=アプリまで正常に動いたではない。
一個先へ進んだだけだった。
web.configを外して403.14になる場合
切り分けの途中で web.config を無効化すると、
403.14になったこともあった。
このときは、ディレクトリまでは見えているものの、既定のドキュメントが決まっていない状態だった。
今回試した設定は、
<defaultDocument> <files> <clear /> <add value="index.php" /> </files></defaultDocument>これで / へのアクセス時に index.php を既定のドキュメントとして扱わせる。
Rewriteを調査するときは、
IISそのものの問題なのかweb.configの問題なのかRewrite後のアプリ側の問題なのかを分けて考えると整理しやすい。
404が出たときの確認順まとめ
今回の経験から、同じ構成ならこの順番で見る。
① 静的ファイル /iis-test.txt ↓② PHP単体 /info.php ↓③ index.php echo + exit で到達確認 ↓④ アプリ ルーティング・設定・ログ ↓⑤ DBなどの依存先ポイントは、
404の原因をいきなり当てにいかないこと。
「IISかな?」
「Rewriteかな?」
「権限かな?」
と予想して設定を触り始めるより、
どこまで正常に通っているかを一段ずつ確定させる。
info.php が表示されるならPHPより前はかなり絞れる。
index.php の echo が表示されるなら、さらに先へ進める。
そうやって正常な範囲を確定していけば、調べる場所も自然に狭くなる。
実際にこれを逆方向から疑いまくって遠回りした話は、こっちに書いた。
手順だけ知りたい人はこの記事で十分。
遠回りまで追体験したい人は本編へどうぞ。