PHPで正しく404エラーページにリダイレクトする方法

CMSで作成したWebサイトやシステムで検索エンジンに悪い評価をもらわないようにするポイントとして、404(Not Found)ページを正しく伝えるというものがあります。
正しく404ページを表示させる方法には、Webサーバーの「ErrorDocument」を指定する方法がありますが、システムの柔軟性を考えるとPHPでエラーページを表示させてなんらかのカスタムメッセージなどを表示させたいもの。
ところが、実際にネット上を検索してみると「PHPで404ページをリダイレクト表示させる」としながらも、実際にはそう作られていない例が多数見受けられました。 そこで、今回は正しくステータスコード404を返しながら、柔軟にエラーページを表示させる方法について書いてみたいと思います。
404ページを表示させているつもりで、実際に異なるステータスコードを返している状態を「ソフト404エラー」と呼びます。 正しい404ステータスコードが返せないと、検索エンジンが「存在するページ」として認識してしまい、サイトの評価を下げられてしまう可能性があります。 これはSEOで上位表示したいサイトにとって良くない傾向です。
404ステータスコードの返し方が間違っている例
一見、合っているようで実際は間違っている例。
$redirectUrl = "http://www.example.com/404.html"; header("HTTP/1.0 404 Not Found"); header("Location: $redirectUrl"); exit;
最初にheader()で「HTTP/1.0 404 Not Found」を設定しているのは良いのですが、次のheader() で「Location」指定をしているのが良くない。 これだと実際はステータスコードとして302(Moved Temporarily)が返されてしまいます。
しかもそのリダイレクト先にはページが存在するため、ステータスコード200(OK)が返されてしまいます。 これでは検索エンジンに「お、URLが一時的にこっちに変わったのね。」と間違って解釈されてしまいます。
よく使われるHTTPステータスコード一覧
コード番号 | ステータス | 意味 |
---|---|---|
200 | OK | 成功(問題なし) |
301 | Moved Permanently | リダイレクト先のURLにページが(永久的に)移動した |
302 | Moved Temporarily | リダイレクト先のURLにページが(一時的に)移動した |
403 | Forbidden | ページへのアクセスがサーバーによって禁止されている |
404 | Not Found | ページが見つからなかった |
404ステータスコードの返し方が正しい例
正しい例でもheader() で「HTTP/1.0 404 Not Found」を返しますが、そのままエラーページのHTMLをfile_get_contents() で読み込んで表示させます。
$redirectUrl = "http://www.example.com/404.html"; header("HTTP/1.0 404 Not Found"); print(file_get_contents($redirectUrl)); exit;
正確に言うと「リダイレクト」という呼び方は適切ではなく、404ページを読み込んで表示しているということですね。
一つ注意しないといけないのは、Locationのリダイレクトと違ってURLが変わらないので、エラーページに表示させる画像やスタイルシートなどの外部ファイルを相対パスで指定していると、mod_rewrite の場合と同じように階層がずれてリンク切れになってしまうおそれがあります。
それを防ぐためには、エラーページに表示させる画像やスタイルシートファイル等を絶対パスで指定しておくように変更しましょう。
<img src="../img/header.gif" ... /> ↓ <img src="/path/to/img/header.gif" ... />
2011-05-10