プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
FuelPHP1.6、「action_404()」について理解する
どうやらページが無い場合は「action_404」とかいうアクションメソッドが呼ばれるみたいですね。

これって決まり事なの(--?と疑問に感じたので調べてみましたよっと。

ふむふむ(--)

404エラー時の挙動は

app/config/routes.php

に定義されているのですね。

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



'_404_'   => 'welcome/404',    // The main 404 route

部分みたいです。

てことはこれを変えれば404エラー時に呼び出すメソッド変えられるのかな(--?

よいしょっと。
■app/config/routes.php
<?php
return array(
    '_root_'  => 'welcome/index',  // The default route
    '_404_'   => 'hoge/404_2',    // The main 404 route
    
    'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'),
);

ちなみに「fuel/app/classes/controller/hoge.php」の中身はこんなんですφ(--)

■controller/hoge.php
<?php
class Controller_Hoge extends Controller
{
    public function before()
    {
        print "before";
    }

    public function action_index()
    {
        print "action_index";
    }

    public function action_404_2()
    {
        print "404_2";
    }

}

さて、どうなるでしょうか。

適当なURLを入力してみた結果がこちらφ(--)

before404_2

なるほど。
意図して書いてたわけじゃないけど404エラー時でもbefore()メソッドは呼ばれるのね。

てことはafter()メソッドを書いても呼ばれるのかな(--?

よいしょっと。
■controller/hoge.php
<?php
class Controller_Hoge extends Controller
{
    public function before()
    {
        print "before";
    }

    public function after($response)
    {
        return Response::forge("after");
    }


    public function action_index()
    {
        print "action_index";
    }

    public function action_404_2()
    {
        print "404_2";
    }
}

適当なURLを入力してみた結果がこちらφ(--)

beforebefore404_2after

なるほど、afuter()メソッドも実行されちゃうのか。

てことはもしかしてアレかな(--?
after()メソッドで存在しないURLにリダイレクトしたら無限ループするのかな?

ちょっと怖いけど、よいしょっと。
■controller/hoge.php
<?php
class Controller_Hoge extends Controller
{
    public function before()
    {
        print "before";
    }

    public function after($response)
    {
//        return Response::forge("after");
        return Response::redirect('hoge/notfount');
    }

    public function action_index()
    {
        print "action_index";
    }

    public function action_hoge()
    {
        print "action_hoge";
    }

    public function action_404_2()
    {
        print "404_2";
    }
}

適当なURLを入力してみた結果がこちらφ(--)

エラー 310 (net::ERR_TOO_MANY_REDIRECTS): リダイレクトが多すぎます。

なるほど、やっぱ無限ループに入りましたね。

じゃあ404エラー時に呼び出すアクションが無かったらどうなるんだべ?

よいしょっと。
■app/config/routes.php
<?php
return array(
    '_root_'  => 'welcome/index',  // The default route
    '_404_'   => 'hoge/aaa',    // The main 404 route
    
    'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'),
);

こらしょっと
■controller/hoge.php
<?php
class Controller_Hoge extends Controller
{
    public function before()
    {
        print "before";
    }

    public function after($response)
    {
        return Response::forge("after");
//        return Response::redirect('hoge/notfount');
    }

    public function action_index()
    {
        print "action_index";
    }

    public function action_hoge()
    {
        print "action_hoge";
    }

    public function action_404_2()
    {
        print "404_2";
    }
}

適当なURLを入力した結果φ(--)

beforebefore

404 - Page not found!
You can see this page because the URL you are accessing cannot be found.

えっと……まずhogeコントローラのbefore()メソッドが呼ばれて
アクションが無いから404エラーになって、
'hoge/err404_3'が呼ばれてまたhogeコントローラのbefore()メソッドが呼ばれて
アクションが無いから404エラーになって処理が終わった感じですかね。
after()はアクションメソッドがあるときしか動かないから今回はどちらも動いていないと。
404エラー時に指定したアクションメソッドが無い場合はそこで処理終了。
404エラーが再度発生するわけじゃないようです。
てことはリダイレクトの扱いではないのですね。
リダイレクトだったら多分無限ループ入るだろうし。

あっ、そうだ。
404エラー時に呼ぶメソッドってやっぱりアクションメソッドじゃないと駄目なんですかね?
さっきと同じ結果になりそうだけど一応試しておきましょうか。

よいしょっと。
■app/config/routes.php
<?php
return array(
    '_root_'  => 'welcome/index',  // The default route
    '_404_'   => 'hoge/err404_3',    // The main 404 route
    
    'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'),
);

こらしょっと
■controller/hoge.php
<?php
class Controller_Hoge extends Controller
{
    public function before()
    {
        print "before";
    }

    public function after($response)
    {
        return Response::forge("after");
//        return Response::redirect('hoge/notfount');
    }

    public function action_index()
    {
        print "action_index";
    }

    public function action_hoge()
    {
        print "action_hoge";
    }

    public function action_404_2()
    {
        print "404_2";
    }

    public function err404_3()
    {
        print "err404_3";
    }

}

適当なURLを入力した結果φ(--)

beforebefore

404 - Page not found!
You can see this page because the URL you are accessing cannot be found.

うん、やっぱ同じ結果ですね。
アクションメソッドが無いよーってエラー。

じゃあ最後に404エラー時に呼び出す「コントローラ」が無い場合(--)b

よいしょっと。
■app/config/routes.php
<?php
return array(
    '_root_'  => 'welcome/index',  // The default route
    '_404_'   => 'aaa/aaa',    // The main 404 route
    
    'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'),
);

適当なURLを入力した結果φ(--)

before

404 - Page not found!
You can see this page because the URL you are accessing cannot be found.

おっ、「before」の表示が一個減った。
てことは、まずhogeコントローラのbefore()メソッドが呼ばれて
アクションが無いから404エラーになって、
'aaa/aaa'が呼ばれて今度はコントローラ自体が無いからそこで処理が終わった感じですね。

なるほどなるほど。

まとめると

1.404エラー時に呼ばれるアクションは「app/config/routes.php」に定義されている。
  ここの定義を書き換えることで404エラー時に呼び出すアクションメソッドを変えられる。

2.404エラー時に呼ばれるアクションに対してもbefore()、after()メソッドは有効

3.「2.」に付随して、404エラー時に呼ばれるアクションがあるコントローラの
  after()メソッドでリダイレクトしていて、かつリダイレクト先が無い場合は無限ループする。
  ※リダイレクトする度に404エラーが再発生するため

4.404エラー時に指定したアクションメソッドが無い場合、
  該当コントローラのbefore()メソッドまで実行されたあとで
  デフォルト?の404画面が表示されて処理が終了する。
  無限ループには入らない。
  ※404エラー時のアクションメソッド呼出はリダイレクト扱いじゃない?

5.404エラー時に指定したコントローラが無い場合、
  デフォルト?の404画面が表示されて処理が終了する。
  無限ループには入らない。
  ※404エラー時のアクションメソッド呼出はリダイレクト扱いじゃない?

ってな感じですね。
「3.」のケースだけ注意が必要ですかね。
エラー時のアクションメソッドを定義するコントローラは
他の処理から独立させた方が安全かもしれません。
最低限、事前処理や事後処理の影響を受けることは意識しておく必要があります。

長々と書いちゃったけど、取りあえず完了\(--)/
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:FuelPHP  thema:システム開発 - genre:コンピュータ  Posted by ササキマコト 

  関連記事