2134 words
11 minutes
IIS + PHPで404になったときの確認ポイント

IISにPHPアプリを配置してアクセスしたら、

このページが見つかりません HTTP ERROR 404

と表示された。

このとき、いきなりRewriteやPHPの設定を片っ端から触るより、

「どこまで正常に動いているか」

を順番に確認した方が切り分けやすい。

今回、Windows Server + IIS + PHP + CodeIgniterの環境を構築したときに実際に404でハマったので、そのときの確認方法を整理しておく。

実際にハマった流れはこちら。

IISでPHPを動かしたら404になった話


まず確認する順番#

今回の構成では、大きく分けるとこうなっていた。

ブラウザ
↓
IIS
↓
FastCGI
↓
PHP
↓
index.php
↓
CodeIgniter
↓
DB

404が出たときに重要なのは、

この中のどこで止まっているのかを確認すること。

自分の場合、最初はIIS周辺をかなり調べたけど、最終的には index.php まで正常に到達していた。

なので今なら、次の順番で確認する。

1. 静的ファイルが表示できるか
2. PHP単体が動くか
3. index.phpまで到達しているか
4. アプリ側を確認する
5. DB接続など外部依存を確認する

順番に見ていく。


1. 静的ファイルが表示できるか#

まずPHPは置いておいて、IISが普通のファイルを配信できるか確認する。

たとえばIISの公開ディレクトリが、

C:\inetpub\wwwroot

なら、そこにテストファイルを作る。

PowerShellなら、

Terminal window
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で、

Terminal window
Test-Path C:\inetpub\wwwroot\index.php

を実行する。

存在すれば、

True

が返る。

今回の調査では、PHPの確認用ファイルを、

info.php

という名前で作っていたのに、

http://localhost/phpinfo.php

へアクセスしていた。

当然404になる。

IISの詳細エラーには、

404.0
0x80070002

と出ていた。

いろいろ設定を疑う前に、

「その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.exe

PHP自体が起動するかは、コマンドでも確認できる。

Terminal window
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 の先頭へ、

<?php
echo '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 が表示されるなら、さらに先へ進める。

そうやって正常な範囲を確定していけば、調べる場所も自然に狭くなる。

実際にこれを逆方向から疑いまくって遠回りした話は、こっちに書いた。

IISでPHPを動かしたら404になった話

手順だけ知りたい人はこの記事で十分。

遠回りまで追体験したい人は本編へどうぞ。