あーさーの備忘録

ゆっくり自由に生きてます

FuelPHPの404でちゃんとステータスコード404を返す

FuelPHPで404の時のページを自作する

まずは、FuelPHPで404の際にデフォルトの404ページ(welcome/404)が表示されないようにします。

APPPATH/config/routes.php

<?php
return array(
    '_root_'  => 'index',  // The default route
    '_404_'   => '404',    // The main 404 route
    
    'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'),
);

welcome/404となっていたころをを404にしました。これで404のときには、http://hoge.com/404とアクセスしたときに表示されるページが表示されるようになります。 (URLはもとのまま)

ControllerとViewを作ります。templateを使う場合も同様にできるはずです。

APPPATH/classes/controller/404.php

<?php
class Controller_404 extends Controller
{
    public function action_index()
    {
        return View::forge('404');
    }
}

APPPATH/views/404.php

<h1>404 Not Found.</h1>
<p>お探しのページは見つかりません。残念でした。</p>

これで、404の場合にはviews/404.phpの内容が表示されるはずです。

ステータスコードが普通に200だった

ところが、この方法だとステータスコードが404にならないわけです。実際にブラウザのコンソールでヘッダを見ると分かりますが、Error Handling - General - FuelPHP Documentationを見ると、

Note that Fuel doesn’t set the 404 status, your response must set this. Return Response::forge(Presenter::forge(‘welcome/404’), 404); in order to send the correct status header.

FuelPHPでは404ステータスを設定してないことに注意して、と言ってます。見た目上は404ページなのですが、レスポンスが200なのでブラウザやクローラーにはページが存在しないことは分かりません。

ステータスコードを404にする

それなら自分で404に設定しましょう。

APPPATH/classes/controller/404.php

<?php
class Controller_404 extends Controller
{
    public function action_index()
    {
        return View::forge('404');
    }

    //以下追記
    public function after($response)
    {
        $response = parent::after($response);
        $response->status = 404;
        return $response;
    }
}

これでステータスコードがちゃんと404になります。やったぜ。

ちなみにwelcome/404の方はちゃんと404返すようになってて、action_index()内でResponseオブジェクト作ってそのときにコードを指定しています。

APPPATH/classes/controller/welcome.php

<?php
public function action_404()
{
    return Response::forge(Presenter::forge('welcome/404'), 404);
}

あれ、こっちのほうが100倍ぐらいシンプルでは…。Response::forge()の第2引数にステータスコードぶち込めるらしい。

まぁでもあっちの方が404スーパークラス作って継承できるんで便利ですね。いや404ページそんなにたくさん作らないけど。それにactionの中は普段と同じ書き方できるんでtemplateとか使う場合も混乱せずに済みます。

技術系ブログ書くの初めてだけどこんな感じでいいのかな。