peketaminの日記

その辺のプログラマーのチラ裏です。

fuelphp でシンプルメンテナンスモード

2014/07/05 追記あり


公式ドキュメントの Event の説明ページ (日本語はこちら) を参考に、

fuel/app/config/events.php

<?php

return array(
    'fuelphp' => array(
        // After FuelPHP initialised
        'app_created' => function()
        {
        },
        // After Request forged
        'request_created' => function()
        {
            if (file_exists(APPPATH.'tmp/down'))
            {
                $data = array(
                    'title' => 'Maintenance 503',
                    'content' => render('template/503'),
                );
                // Set a HTTP 503 output header
                return Response::forge(render('template/default', $data), 503)->send(true);
            }
        },
        // Request is requested
        'request_started' => function()
        {
        },
        // Before controllers before() method called
        'controller_started' => function()
        {
        },
        // After controllers after() method called
        'controller_finished' => function()
        {
        },
        // After Response forged
        'response_created' => function()
        {
        },
        // Request is complete and Response received
        'request_finished' => function()
        {
        },
        // Output has been send out
        'shutdown' => function()
        {
        },
    ),
);

にしたら出来た。(と思う)

メンテナンスモードにしたい場合は

touch fuel/app/tmp/down

して、解除は

rm fuel/app/tmp/down

して使う。 でも手打ちは危ないので、タスクにするのが吉な感じでしょうか。

php oil r maintenance:down

みたいな感じで。 公式フォーラムにもメンテナンスモードのサポート要請はあったようですが、 IPホワイトリストの制御とか、管理者ログイン状態でのメンテナンスモードスルーとか クロージャー内になんでも書けるし、とりあえずこれでいいや…。


2014/07/05 追記

少し改良しました。

上記だと、アクセスURLに該当するコントローラーのアクション自体もそのまま呼ばれてしまいました。
そのアクションの中でビューが呼ばれてると、
メンテナンス画面と本来の画面のビューが縦に2つ積み重なる出力になり、
期待した動作にはなりませんでした。

下記のように手を入れました。

<?php

\Config::load('app/custom.php', 'custom');

return array(
    'fuelphp' => array(
        'app_created' => function()
        {
            // After FuelPHP initialised
        },
        'request_created' => function()
        {
            // After Request forged
            if (\Config::get('custom.maintenance'))
            {
                $data = array(
                    'title' => 'Maintenance 503 (メンテナンス 503)',
                    'content' => render('503'),
                );
                // Set a HTTP 503 output header
                return Response::forge(render('template', $data, false), 503)->send(true);
            }
        },
        'request_started' => function()
        {
            // Request is requested
            if (\Config::get('custom.maintenance'))
            {
                exit;
            }
        },
        'controller_started' => function()
        {
            // Before controllers before() method called
        },
        'controller_finished' => function()
        {
            // After controllers after() method called
        },
        'response_created' => function()
        {
            // After Response forged
        },
        'request_finished' => function()
        {
            // Request is complete and Response received
        },
        'shutdown' => function()
        {
            // Output has been send out
        },
    ),
);
  • 冒頭のように touch down コマンド式でも良かったのですが、コマンドを作るのが手間だったので、 Config ファイルでスイッチするようにしました。
  • request_started のイベントフック中で exit するようにしました。
  • exit したら FuelPHP フレームワークで必要な終了処理とかも含めて強制中断しちゃう?
    とも思ったのですが、 response_created 以降のイベントはちゃんと動いてました。
    (各イベント中で echo 1234; して簡易的にチェックしました)
    (ソースはまだ追ってないです、スミマセン…)