Web事業部実績紹介
Web事業部実績紹介
2010.10.28

重複したコントローラを使う

まっちー

以前、コントローラの中身をフォルダ分けするという記事を書いたことがあるのですが、実はこいつにはちょっとしたくせ(弱点)があったようです。

というのも、例えば管理画面とフロント画面(表示画面)でコントローラーを分けて、両者に同じ名前を持つコントローラーを作った場合、まあ、users_controller.phpとしときましょうか、その場合、残念ながらどちらか片方しか呼ばれなくなるみたいなんです。

//ディレクトリ構造
app/   
  └controllers/   
    ├admin/   
    │  └users_controller.php   
    └users_controller.php

//bootstrap.php
App::build(array(
    'controllers' => array(   
        ROOT.DS.APP_DIR.DS.'controllers'.DS.'admin'.DS,   
        ROOT.DS.APP_DIR.DS.'controllers'.DS,     
    ),
));

こういう風に書くと、/admin/users/indexにアクセスしても/users/indexにアクセスしても、先に見つかった方のusers_controller.phpが呼ばれるみたいで、だから/admin/users/indexに先にアクセスしていれば、/users/indexにアクセスしたときは、そんなアクションありませんよっていうエラーが出てしまいます。

あ、ちなみにCake1.3になったらパスを通す書き方がちょっと変わったみたいです。上記のようにApp::build()ってのを使うみたいです。

まあ、同じコントローラー名を持つファイルを作るというやり方自体がよくないのかもしれません。別の一つのコントローラーでindex()とadmin_index()を両方作ってしまえば問題は解決ですからね。

でも、管理画面とフロント画面を別々の人が開発してる場合とかも、あるかもしれない。そういうときには、コントローラーは分かれてた方がいいですよね。

なので、上記みたいに同じコントローラーを持つファイルが二つ以上あってもちゃんと動くようにしてみましょう。

いじるのは、bootstrap.phpとcore.phpです。

//bootstrap.php
if(preg_match('/admin/i', $_SERVER['REQUEST_URI'])) {
    App::build(array(
        'controller' => array(
            ROOT.DS.APP_DIR.DS.'controllers'.DS.'admin'.DS,
            ROOT.DS.APP_DIR.DS.'controlers'.DS,
        ),
    ));
}

//core.php
if(preg_match('/admin/i', $_SERVER['REQUEST_URI'])) {
    Cache::config('default', array(
        'engine' => 'File',
        'duration'=> 3600,
        'probability'=> 100,
        'path' => dirname(CACHE) . DS . 'admin' . DS,
        'prefix' => 'cake_',
        'lock' => false,
        'serialize' => true
    ));
} else {
    Cache::config('default', array(
        'engine' => 'File',
        'duration'=> 3600,
        'probability'=> 100,
        'path' => CACHE,
        'prefix' => 'cake_',
        'lock' => false,
        'serialize' => true
    ));
}

要するに、/admin/~のときだけ、必要なパスを指定してあげるってやり方ですね。core.phpの方は、ファイルを見ると一番下にキャッシュの設定みたいなのが書いてあると思うんですけど(↓こんなの)

Cache::config('default', array('engine' => 'File'));

それを上記の何かよく分からないやつに書き直します。

僕はいまいち理解できてないですけど、CakePHPってページアクセスしたりすると、tmp/cacheの下に何かキャッシュファイルができるじゃないですか。まあ、そこに何やら必要なファイルのパスとか何とか、いろんな情報がキャッシュされているみたいなんですわ。

で、一度/admin/~が読み込まれるとそのパスがキャッシュに書きこまれるので、キャッシュがある限りはそっちを呼びに行っちゃう。なので、管理画面にアクセスしたときとフロント画面にアクセスしたときで、書きこまれるキャッシュのディレクトリを分けてあげる必要があります。それが上のcore.phpに書いた処理。

あまりスマートなやり方ではないような気もしますが、とりあえずこれで動くようにはなりました。

めでたしめでたし。