CakePHP/コントローラー

CakePHP/コントローラー

バージョンと製造年月日

  • 2011-04-29
  • CakePHP 1.3.8

設計

controllerはある特定のViewのためにデータのお膳立てをするための場所と思っていいい。

逆に言うとある特定のViewのためにmodelにグチャグチャ何かを書いちゃいかんということ

基本

CakePHP/命名規則に従ってファイルとクラス名を決めて、AppControllerクラスを継承して作る。そして

app/controllers

ディレクトリに配置する。

functionで定義しているのがコントローラ本体の実際のロジック、一般的なフレームワークではこのロジック部をアクションとか言いますな。 クラスはそれの取りまとめという感じか。

hoge_controller.php
class HogeController extends AppController{
    function index(){
        //hogehogehoge
    }
}

AppControllerを継承していればどう作ってもいいということはアプリごとの共通なものはAppControllerを継承したクラスにまとめて記述して、 それを個々のコントローラーのクラスが継承するという設計にするといいだろう。

コントローラへのアクセス

基本

コントローラーの呼び出しは CakePHPのアプリのルートから

コントローラー名(のキャメル化)/アクション名

になる。

http://aaaa.com/bbb/hoge/index

のようになるわけだ。

コントローラーが HogePiyoController のような名前の場合は

http://aaa.com/bbb/hogePiyo/index

のように頭だけ小文字に変化する。URLに大文字が交じるのはちょっとキモイのでコントローラー名はなるべく1単語でシンプルにしたいな。

この記述は

config/routes.php

にデフォルトで書かれている設定に従っているだけで、これを変えられないわけではない。

継承用の共通コントローラーにはアクセスさせたくない

共通処理を書くだけの継承専用のオリジナルコントローラーを作ると思うがこのコントローラーもURLの対象に入ってしまうので当然ブラウザからしかるべきURLでアクセスすればたどりつける。

やってほしくないので共通コントローラーはabstract宣言をくっつけてオブジェクト化を禁止しておく。これでよし。

コントローラークラスのメンバ変数

コントローラー名

後方互換性のためにコントローラー名を明示的に指定することになっている。これは命名規則と同期していれば特に問題ないので思考停止していれておこう。

メンバ変数は name という名前になる

hoge_controller.php
class HogeController extends AppController{
    public $name = 'Hoge';
    function index(){
        //hogehogehoge
    }
}

なのでAction中でコントローラー名を使いたいと思ったら

hoge = $this->name;

だ。

コントローラーで使用するモデル指定

コントローラー内部で使われるモデルは予めCake側がnewしてくれるのでその参考情報としてモデル名の一覧を指定する。

メンバ変数は uses という名前になる。指定は配列で行う。

hoge_controller.php
class HogeController extends AppController{
    public $name = 'Hoge';
    public $uses = array('Piyo', 'Fuga');
    function index(){
        //hogehogehoge
    }
}

モデルを使わないコントローラーでは null を指定しておけばいい。

コントローラーからテンプレートへのルーティングを自動でやるかどうかの指定

通常はアクション名の関係から辿ってテンプレートが自動決定される。これをauto renderと言う。 auto renderの設定がデフォルトでOnになっている。

hoge_controller.php
class HogeController extends AppController{
    public $name = 'Hoge';
    public $uses = array('Piyo', 'Fuga');
    public $autoRender = true;
    function index(){
        //hogehogehoge
    }
}

こいつを明示的にアクション名とは別のテンプレートを呼び出したかったりとか、そういう時に false を指定するとそれを止めることができる。

テンプレートを使う場合レイアウトファイルを使うかどうかの設定

autoLayoutに値を設定するとレイアウトファイルを使うかどうかを切り替えられます

hoge_controller.php
class HogeController extends AppController{
    public $name = 'Hoge';
    public $uses = array('Piyo', 'Fuga');
    public $autoLayout = false;
    public $autoRender = true;
    function index(){
        //hogehogehoge
    }
}

アクションごとに上記の設定値を切り替えたい

設定値は単なるプロパティなので

$this->autoLayout = false;

のようにアクションメソッド中に書き換えてしまえばOK

メソッドのコールタイミング

Actionメソッド開始前

コントローラーの本来のメソッド(indexとかshowとかeditとか)の前に呼ばれるメソッドがbeforeFilterメソッドでこいつをコントローラーのクラスに書いておくと本来の動きの前に処理を割りこませることができる。

つまり全部のActionに共通で使う前処理をここで書いておけばいいのだ。このbeforeFilterは引数が取れないようだ。

beforeFilterメソッドが親でももうすでに定義されていた場合、子で作ると親が呼び出されないので明示的に呼んでおく

function beforeFilter(){  
    parent::beforeFilter();
}

テンプレート呼出前(Actionメソッド終了後)

テンプレートの呼び出し前に動くのがbeforeRenderメソッド。共通の後処理ってことね。

function beforeRender(){
    parent::beforeRender();
}

テンプレート描画後(afterFilter)

テンプレートが全部出力し終わった後にさらにコールされるメソッドがある

function afterFilter(){
    echo "hoge";
}

ここでの出力は標準出力に出てしまうので。テンプレートの出力に対して後付できたりする。

注意しないといけないのはこのメソッドはアクションのメソッド中で

$this->redirect("hoge/piyo");

ってリダイレクトしたり

exit;

ブチッと切ってしまうと実行されないということ。

afterFilterの処理内容をredirectをトラップして行っておくといいかもしれない

テンプレートの出力を加工する

テンプレートの出力をウマイことキャッチすることで最終的な出力を加工できるようになる。

画面の出力直前でob_start関数を呼び出して、出力のキャプチャ準備をする

function beforeRender(){ 
    ob_start(); 
}

出力が全部終わった時点で、出力した内容をob_get_contentsで取得、その後に画面に出力されないようにob_end_cleanでクリアしてしまう。

その後に加工してechoすることで再びリターンとして出力する。

function afterFilter(){
    $hoge = ob_get_contents(); 
    ob_end_clean();
    //ここらへんで出力に対する操作をして
    echo $hoge;
}

外部からの値の受け取り

関連ページ

タグ

php/cakephp/controller.txt · 最終更新: 2017-09-26 19:03 by ore