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

  • 21
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

動かしたバージョン: Ver. 1.7.1

自分用に書いた記事をまとめ直し

  • DB を一時的に止めたり、メールの飛び先を変えたり、内部の処理を大きく変える時に、メンテナンス画面を出して、ユーザーの行動をそこでストップしたかったので書きました (蓄積データへの意図しない追記・変更を防ぐため)
  • ちゃんとやる場合は、コントローラーとルーターをちゃんと書いてる方もいるような気もしています。
  • 知り合いは、そっちではなく、 nginxApache の conf の方で切り替えてました (知り合いは Django 使い)。
  • Laravel 用に書いた記事はこちら

出来る事

  • どの URL にアクセスしてもリダイレクトなしにメンテナンス画面を表示する
  • HTTP ステータスコード 503 を返す
  • コントローラーを書かずに済ませる
    • コンフィグとビュー (テンプレート) だけ書く
    • config/routes.php, public/index.php を変更しない

メンテナンス画面表示処理のブロックで出来ない事

  • \Request::active() とかは取得出来ない (Uri::segment() も)
  • コントローラーまで処理が渡らないので、コントローラーが必要な処理は出来ない
  • たぶん、IP ベースでスルーさせる処理とか、 簡単なことしか出来ない と思う (なので「 シンプル メンテナンスモード」)

凝った制御が必要な場合は、別の仕組みが必要…。

用意するもの

  1. メンテナンスフラグ用 config ファイルを作成。
  2. fuel/app/config/event.php というパスでファイルを作成。

要は config ファイルを 2 つ作成する。

メンテナンスフラグ用 config ファイル

メンテナンスモードの切り替えは config ファイルでスイッチしようと思います。
(メンテナンスモードのフラグとなるファイルを touch してスイッチする方法もあると思いますが、今回は array の値でやります…。)

<?php
return array(
    'active' => true,
);

みたいな内容で、 fuel/app/config/app/maintenance.php などのパスに置いておく。

fuel/app/config/event.php を作成

FuelPHP フレームワーク側には、中枢のコードに直接手を入れずに、
任意の処理を介入させるためのイベントというフックのポイントが用意されているみたいで、
公式ドキュメントは下記。

オリジナル: Event - Classes - FuelPHP Documentation
日本語翻訳版: Event - クラス - FuelPHP ドキュメント

上記ページの、 Example In app/config/event.php の内容を参考に作ります。

コード

<?php

\Config::load('app/maintenance.php', 'maintenance');
$maintenance_active = \Config::get('maintenance.active');

return array(
    'fuelphp' => array(
        'app_created' => function()
        {
            // After FuelPHP initialised
        },
        'request_created' => function() use ($maintenance_active)
        {
            // After Request forged
            if ($maintenance_active)
            {
                $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() use ($maintenance_active)
        {
            // Request is requested
            if ($maintenance_active)
            {
                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
        },
    ),
);

上から順に各イベントが実行されるとすると、
「そんなところで、 exit したら、後続の、本来必要な終了処理とかも含めて強制中断しちゃう?」
とも思ったのですが、 response_created 以降のイベントは普通に動いてました。
(多分)
(各イベント中で echo 1234; して簡易的にチェックしました)
(ソースはまだ追ってないです、スミマセン…)

冒頭で \Config::load() が実行されてることについて何らかのディスがあるかも知れません。
とりあえず以上。

追記 2014/07/07

もう少し手を入れた内容を書いた。
(改修) FuelPHP でシンプルメンテナンスモード: 特定 URL や特定 IP 許可 - Qiita