CakePHP アプリケーションの環境設定は cake の一部です。 CakePHP をインストールした後、基本的なウェブアプリケーションを作成するのに必要なことは、データベースの環境設定だけです。
とはいえ、 CakePHP の柔軟なアーキテクチャの利点を生かすためにオプションの環境設定がいくつか存在します。CakePHP コアを継承しての機能性の倍増、独自のURLマッピングの設定(Route)、そして独自の語形変化の定義などが簡単に行えます。
CakePHP は、データベース設定の詳細が、app/config/database.php にあることを期待します。データベースの設定例のファイルは app/config/database.php.default にあります。設定が終わると次のようになります。
var $default = array('driver' => 'mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'cakephpuser',
'password' => 'c4k3roxx!',
'database' => 'my_cakephp_project',
'prefix' => '');
モデルの $useDbConfig プロパティで別の接続が定義されない限り、$default という配列が接続に使用されます。例えば、アプリケーションがデフォルトのデータベースに加えて、既存(legacy)のデータベースも使用しなければいけないとしましょう。その場合、$default 配列と同形式で $legacy というデータベース接続用の配列を作成します。そして該当するモデルの中で var $useDbConfig = ‘legacy’ とすると、$legacy 接続が使用されるようになります。
必要に合わせて、設定配列の中に、キー/値のペアを書き込んでください。
キー |
値 |
---|---|
driver |
この設定用配列は、データベースのドライバ名を入力する場所です。例えば、mysql, postgres, sqlite, pear-drivername, adodb-drivername, mssql, oracle, odbc などです。LDAPやTwitterの様な、データベースではないものに接続する場合は"driver"を指定せず、代わりに"datasource"というキーを設定します。 |
persistent |
持続的接続(persistent connection)を使うかどうか設定します。 |
host |
データベースサーバのホスト名(または IP アドレス)。 |
login |
アカウントユーザ名。 |
password |
アカウントのパスワード。 |
database |
この接続が利用するデータベース名。 |
prefix (オプション) |
データベース内のすべてのテーブルの頭に付ける接頭辞(prefix)。もしテーブルに接頭辞が付いていないのであれば、空の文字列を指定してください。 |
port (オプション) |
サーバに接続するための TCP ポート、または Unix ソケット。 |
encoding |
サーバにSQLステートメントを送信する際に使用するキャラクターセット。 この項目のデフォルト値は、DB2 を除く全てのデータベースのデフォルトのエンコーディングになります。もし mysql/mysqli 接続において UTF-8 のエンコーディングを使用したい場合は、「utf8」というようにハイフン抜きで指定してください。 |
schema |
PostgreSQL データベースの設定時に、どのスキーマを使うかを指定します。 |
datasource |
non-DBO datasource用に設定します。例えば、ldap, twitter などです。 |
prefixの 設定は、モデルではなく、テーブルに対するものです。例えば、 Apple モデルと Flavor モデルの join テーブルを作成する場合、 prefix_apples_flavors という名前になり(prefix_apples_prefix_flavors ではありません)、prefix の設定は、「prefix_」となります。
この点については、このマニュアルの付録部分の一覧にある CakePHP の規約を少し読んでおくのも良いかもしれません。テーブル(そして幾つかのフィールド名)の正しい命名方法を知っておくと、幾つかの機能をすぐに使えるようになり、設定を省く手助けになるかもしれません。例えば、データベーステーブル名を big_boxes 、モデル名を BigBox 、コントローラ名を BigBoxesController とすると、全てが自動的に協調して機能します。慣習的に、データベーステーブルの名前は、アンダースコアと小文字を使った複数形にします。例えば、 boxers, pastry_stores, savory_cakes というようになります。
CalePHPのアプリケーション設定は、/app/config/core.phpの中にあります。このファイルは、アプリケーションの動作を決める、Configureクラスの変数定義と定数定義の集まりです。この各変数について設定する前に、CakePHPの環境設定レジストリクラス、Configureについてある程度知っておく必要があります。
CakePHPで設定しなければいけないことはそれほど多くありませんが、アプリケーションの中に独自のルールを設定できるようにしておくと、便利なことがあります。これまではカスタム設定に関する変数や定数をいくつかのファイルの中に定義していたかもしれませんが、そうすると、値が必要になるたびに、毎回、設定ファイルをincludeしなくてはならなくなります。
CakePHPの新しいConfigureクラスを使うと、アプリケーション、またその実行時に必要な特定の値の保存と取り出しに使うことができます。このクラスの中には何でも保存でき、コード内のあらゆる場所で使用できるので、CakePHPのMVCパターンを崩してしまう誘惑には注意しましょう。Configureクラスの主要な目標は、各変数を集中保管して、各オブジェクトから使用できるようにすることです。“設定より規約”(convention over configuration)を遵守するようにして、MVC構造を壊してしまうことがないようにしましょう。
このクラスは singleton として動作し、メソッドは静的なコンテキストとして、アプリケーション内のどこからでも呼ぶことができます。
<?php Configure::read('debug'); ?>
write(string $key, mixed $value)
write()
を使って、アプリケーションの設定データを保存します。
Configure::write('Company.name','株式会社ピザ');
Configure::write('Company.slogan','体と心にピザを');
$key
のパラメータとして、ドットを使っていることに注意してください。このドットを使って、論理グループごとに設定を整理することができます。
Configure::write(
'Company',array('name'=>'株式会社ピザ','slogan'=>'体と心にピザを')
);
Configure::write('debug', $int)
を使って、デバッグと運用モードをすぐに切り替えることができます。AMFやSOAPなどとの連携の際、デバッグ情報のためにパースに問題が生じるような場合に特に便利に使うことができます。
read(string $key = 'debug')
アプリケーションから、環境設定データを読み込むために使います。デフォルトでは、CakePHPの重要なデバッグ値が設定されています。keyが指定されると、そのデータが返されます。上のwrite()の例を使うと、返される次のようなデータを取得できます。
Configure::read('Company.name'); //出力は: '株式会社ピザ'
Configure::read('Company.slogan'); //出力は: '体と心にピザを'
Configure::read('Company');
//出力は:
array('name' => '株式会社ピザ', 'slogan' => '体と心にピザを');
delete(string $key)
アプリケーションの環境設定から情報を削除するのに使います。
Configure::delete('Company.name');
load(string $path)
指定したファイルから環境設定をloadするためにこのメソッドを使ってください。
// /app/config/messages.php:
<?php
$config['Company']['name'] = '株式会社ピザ';
$config['Company']['slogan'] = '体と心にピザを';
$config['Company']['phone'] = '555-55-55';
?>
<?php
Configure::load('messages');
Configure::read('Company.name');
?>
ファイルの中では、 $config
配列のキーと配列のペアで設定されます。ファイル内のその他の変数は、
load()
では無視されます。
version()
現在のアプリケーションのCakePHPのバージョンを返します。
Configure クラスは、CakePHP の一連の環境設定変数を管理するために使用されます。これらの変数は、app/config/core.php の中にあります。下記では、各変数の詳細と CakePHP アプリケーションにどのように影響するかを説明します。
環境変数設定
説明
debug
CakePHP のデバッグ出力を変更します。 0 = 運用モード。出力しません。 1 = エラーと警告を表示します。 2 = エラー、警告、SQLを表示します。
App.baseUrl
CakePHP で Apache の mod_rewrite を使用しないのであれば、この定義のコメントアウトを外してください。.htaccess ファイルを削除するのも忘れないようにしてください。
Routing.prefixes
CakePHP の(adminのような)プレフィックスルーティングを活用する場合にはコメントアウトを外してください。使用したいプレフィックスの配列をこの変数に設定してください。詳細は後述します。
Cache.disable
true に設定すると、サイト全体のキャッシュが無効になります。
Cache.check
true に設定すると、ビューのキャッシュが有効になります。有効にするためにコントローラ内の設定も必要ですが、この変数によって、これらの設定を調べるようになります。
Session.save
CakePHP がどのセッションストレージを使用するかを指定します。 php = PHP のデフォルトのセッションストレージを使用します。 cache = Cache::config() で設定されたキャッシュエンジンを使用する。キャッシュしたデータとセッションを格納するために、複数のアプリケーションサーバから使えるようセットアップした Memcache を利用する場合にとても便利です。 cake = セッションデータを /app/tmp に格納します。 database = セッションデータをデータベーステーブルの中に保存します。/app/config/sql/sessions.sql にある SQL ファイルを使用して、テーブルを設定しておいてください。
Session.model
セッションモデルとして使われるモデルの名前です。ここで設定したモデルの名前はアプリケーションのいかなる他の場所でも使われるべきではありません。
Session.table
現在CakePHP1.3ではこの値は非推奨となっています。
Session.database
セッション情報を保存するデータベース名。
Session.cookie
セッションを追跡するのに用いられるクッキー名。
Session.timeout
セッションタイムアウトの基本時間を秒で指定します。実際の時間は、 Security.level に依存します。
Session.start
trueに設定すると、セッションが自動的に始まります。
Session.checkAgent
false に設定すると、リクエストの間にユーザエージェントが変更されていないかを CakePHP のセッションが確認しなくなります。
Security.level
CakePHP のセキュリティレベルを設定します。'Session.timeout' で設定されたセッションタイムアウトの基本時間に、この設定による値をかけたものが最終的な値になります。 有効な値: 'high' = x 10 'medium' = x 100 'low' = x 300 'high' と 'medium' は、両方とも session.referer_check が有効になります。 'Security.level' が 'high' にセットされていた場合、 CakePHP のセッション ID はリクエストごとに再生成されます。
Security.salt
セキュリティを考慮したハッシングのために利用されるランダムな文字列です。
Security.cipherSeed
文字列の符号化・復号化に使われるランダムな数を表す文字列(数字だけで構成される)。 A random numeric string (digits only) used to encrypt/decrypt strings.
Asset.timestamp
正規のヘルパーを使用する場合、個々のファイルの最終更新時刻のタイムスタンプをアセットファイル(CSS, JavaScript, 画像)のURLの最後に付与します。
(bool) false - 何もしない(デフォルト) (bool) true - debug > 0 のときタイムスタンプを付与する (string) 'force' - debug >= 0 のときタイムスタンプを付与する
Acl.classname, Acl.database
CakePHP の ACL(アクセス制御リスト)機能で利用される定数です。詳細はアクセス制御リストの章を見てください。
キャッシュの設定は、core.php にもあります。この点については後の章にもありますので参考にしてください。
Configure クラスは、サイトの動作中に、コアの環境設定を読み書きすることができます。たとえば、アプリケーションの中で、ある特定の部分だけデバッグ設定を変えたいというような場合などに特に便利です。
ほとんどの環境設定はConfigureで行いますが、CakePHPが実行時に使用する定数がほかにもあります。
定数 |
説明 |
---|---|
LOG_ERROR |
エラーに関する定数。エラーログどデバッグに用いられます。現在、PHPはLOG_DEBUGをサポートしています。 |
CakePHPにおけるクラスのロード処理はさらに合理化されました。前のバージョンでは、ロードしたいクラスの型に基づいて必要なクラスのロード処理に対して様々な関数群が存在しました。この関数群の使用は推奨されなくなりました。あらゆるクラスおよびライブラリのロードするには現在、App::import()を使用します。App::import()は次のことを保証します。クラスが1度しかロードされないこと。適切な親クラスがロードされること。そして数多のケースで自動的にパスを解決することです。
必ず、ファイルやクラス名の規約に従ってください。
App::import($type, $name, $parent, $search, $file, $return)
初めて App::import
を見ると複雑に見えるかもしれません。でも、多くの場合は2つの引数だけが必須になっています。
SanitizeやXmlといったコアのライブラリは、次の方法で読み込みます。
<?php App::import('Core', 'Sanitize') ?>
これで、Sanitizeクラスが使えるようになります。
アプリケーションに関連するすべてのクラスをApp::import()で読み込めます。以下の例を参照してください。
App::import('Controller', 'MyController');
App::import
のコールは、ファイルを require
で読み込むことと同じです。その後にクラスを初期化する必要があるということを意識しておいてください。
<?php
// これは、require('controllers/users_controller.php'); と同じです。
App::import('Controller', 'Users');
// クラスをロードします
$Users = new UsersController;
// モデルのアソシエーション、コンポーネントその他をロードするには次のようにします。
$Users->constructClasses();
?>
App::import('Model', 'MyModel')
App::import('Component', 'Auth')
<?php
App::import('Component', 'Mailer');
// このクラスを読み込む必要がある
$Mailer = new MailerComponent();
?>
App::import('Behavior', 'Tree');
App::import('Helper', 'Html');
App::import('Helper', 'Html');
プラグインのクラスを読み込むのは、appとコアのクラスを読み込むのとほぼ同じです。しかし、読み込み元のプラグイン名を指定してください。
App::import('Model', 'PluginName.Comment');
APP/plugins/plugin_name/vendors/flickr/flickr.php を読み込むには、次のようにします:
App::import('Vendor', 'PluginName.flickr/flickr');
vendor() 関数は非推奨になりました。vendor ファイルはこれまでと同様に App::import() を使用して読み込むようになりました。構文はわずかに異なり、引数が追加されています。これは vendor ファイルの構造は大きく異なっていたり、すべての vendor ファイルにクラスが含まれているとは限らないためです。
以下は、いくつかのパス構造から vendor ファイルをどのように読み込むかという例です。vendor ファイルは、vendor フォルダにあると仮定します。
vendors/geshi.php を読み込むには
App::import('Vendor', 'geshi');
vendors/flickr/flickr.php を読み込むには
App::import('Vendor', 'flickr/flickr');
vendors/some.name.php を読み込むには
App::import('Vendor', 'SomeName', array('file' => 'some.name.php'));
vendors/services/well.named.php を読み込むには
App::import('Vendor', 'WellNamed', array('file' => 'services'.DS.'well.named.php'));
ベンダーファイルが/app/vendorsディレクトリの内部にあっても、違いはありません。Cakeは自動的に検出します。
app/vendors/vendorName/libFile.php を読み込むには
App::import('Vendor', 'aUniqueIdentifier', array('file' =>'vendorName'.DS.'libFile.php'));
ルーティングは、URLをコントローラのアクションに結びつける(map) する機能です。URL の見ばえをよくし(pretty URL)、より柔軟に設定できるよう、CakePHP に備わっています。ルートを使うために Apache の mod_rewrite が必ず必要というわけではありませんが、mod_rewrite を使用すると、アドレスバーに表示される URL が整ったものになります。
独自のルートを学ぶ前に、CakePHP のデフォルトのルートについて知っておく必要があります。CakePHP のデフォルトルーティングによって、どんなアプリケーションでもうまく動くようになっています。URL の中に、アクション名を置くことで、アクションに直接アクセスすることができます。コントローラのアクションに URL を使うことでパラメータを渡すこともできます。
デフォルトのroutesのURLパターン:
http://example.com/コントローラ名/アクション名/パラメータ1/パラメータ2/パラメータ3
/posts/view という URL は、PostsController の view() アクションにマップされます。 /products/view_clearance は、ProductsController の view_cearance() アクションにマップされます。URL でアクション名が指定されていない場合には、index() メソッドが用いられます。
デフォルトのルーティングでは、URLを使ってアクションにパラメータを渡すこともできます。例えば、/posts/view/25 というリクエストは、PostsController 上で view(25) として呼ぶのと同じことになります。
passed引数はリクエストを作り上げるときにその他の引数またはパスセグメントとして使用されます。これらはコントローラのメソッドにパラメータを渡すためによく使われます。
http://localhost/calendars/view/recent/mark
上記の例では、recent
とmark
はCalendarsController::view()
へのpassed引数です。passed引数は二つの方法でコントローラに渡されます。一つは、アクションのメソッドが呼び出されたときの引数としてです。もう一つは、順番付けされた配列として$this->params['pass']
を利用できます。また、カスタムルートを使うとき、passed引数に特定のパラメータを強制させることもできます。更なる情報は、アクションにパラメータを渡すを見てください。
URL
を使ってパラメータに名前を付けて、その値を渡すことができます。/posts/view/title:first+post/category:generalというリクエストでは、PostsController
の view() アクションが呼ばれます。このアクションでは、title と category
というパラメータの値を、それぞれ、$this->passedArgs[‘title’] と
$this->passedArgs[‘category’]
として受け取ることができます。また、名前付きパラメータに$this->params['named']
からアクセスすることもできます。$this->params['named']
には名前付きパラメータの配列がその名前をインデックスとして入っています。
以下のいくつかのデフォルトのルートによる要約例が参考になることでしょう。
デフォルトのルーティングを使用した、URL からコントローラへのアクションマッピング:
URL: /monkeys/jump
Mapping: MonkeysController->jump();
URL: /products
Mapping: ProductsController->index();
URL: /tasks/view/45
Mapping: TasksController->view(45);
URL: /donations/view/recent/2001
Mapping: DonationsController->view('recent', '2001');
URL: /contents/view/chapter:models/section:associations
Mapping: ContentsController->view();
$this->passedArgs['chapter'] = 'models';
$this->passedArgs['section'] = 'associations';
$this->params['named']['chapter'] = 'models';
$this->params['named']['section'] = 'associations';
カスタムルートを作るとき、よくある落とし穴は名前付きパラメータがカスタムルートを破壊してしまうことです。これを解決するためには、ルータにどのパラメータを名前付きパラメータにするつもりかを通知しなくてはなりません。ルータはこれを知らないと、名前付きパラメータが実際に名前付きパラメータとして意図されているかかルーティングされるパラメータとして意図されているかを決定することができません。また、デフォルトではルーティングされるパラメータとして意図されていると決めてかかることになります。ルータで名前付きパラメータに接続するためにはRouter::connectNamed()
を使用してください。
Router::connectNamed(array('chapter', 'section'));
とすると、chapterパラメータとsectionパラメータが正しくリバースルーティングできるようになります。
独自ルートの定義により、アプリケーションを指定した URL
で動作させることができるようになります。独自のルーティングは、/app/config/routes.php
ファイルで Router::connect()
メソッドを使用して定義します。
connect()
メソッドは3つのパラメータからなっています。対応させたい
URL、独自のルート要素のデフォルトの値、要素と対応させるための正規表現ルールです。
ルート定義の基本的な形式は次のようになります。:
Router::connect(
'URL',
array('paramName' => 'デフォルト値'),
array('paramName' => '正規表現')
)
最初のパラメータで、制御する URL をルータに伝えます。URL は、通常のスラッシュで分けられた文字列です。しかし、ワイルドカード(*)や、独自の route 要素(コロンで始まる変数名)を含むことができます。ワイルドカードで対応させたい URL を指定し、route 要素の指定で、コントローラアクションのためのパラメータを集めることができます。
URLを指定した後、connect()
の次の2つのパラメータを使って、リクエストが対応した場合に何を行うのかを
CakePHP に伝えます。2番目のパラメータは連想配列です。配列のキーは、URL
の route 要素にちなんだものか、デフォルト要素 (:controller, :action,
:plugin)
にしてください。配列内の値は、それらのキーに対するデフォルト値です。
connect()
の3番目のパラメータを考える前に、基本的な例をいくつか見てみましょう。
Router::connect(
'/pages/*',
array('controller' => 'pages', 'action' => 'display')
);
CakePHP の routes.php
ファイルの中(40行目)に、このルートが書かれています。このルートは、/pages/
ではじまるすべての URL にマッチし、それを PagesController();
の
display()
メソッドに渡します。例えば、 /pages/products
というリクエストは、PagesController->display('products')
にマップされます。
Router::connect(
'/government',
array('controller' => 'products', 'action' => 'display', 5)
);
この2つ目の例は、connect()
の2番目のパラメータでデフォルトパラメータを定義する方法を示しています。それぞれのお客様向けに異なる製品がある場合などに
route
を作成することを考えることができるでしょう。この例では、/products/display/5
としなくても、/government という URL でアクセスできるようになります。
一般的な Router の他の使い方は、コントローラの別名(alias)を定義することです。通常の /users/someAction/5 という URL の代わりに、/cooks/someAction/5 でアクセスさせたいとしましょう。このようなルートの設定は、次のようにすることで簡単に実現できます。
Router::connect(
'/cooks/:action/*', array('controller' => 'users', 'action' => 'index')
);
この設定は、 Router が /cooks/ で始まる URL を、全て users コントローラに送ることを表しています。
URL
が生成されるときも、ルートの設定が適用されます。上述の例にあるルートが最初にマッチした場合、URL
として array('controller' => 'users', 'action' => 'someAction', 5)
のように指定すると、/cooks/someAction/5 というURL が生成されます。
ルートの中で独自の名前を持つパラメータを使うつもりならば、Router::connectNamed
を用いて Router にそれを伝える必要があります。上述の例にあるルートに
/cooks/someAction/type:chef
のようなURLをマッチさせたい場合は、次のようにします。
Router::connectNamed(array('type'));
Router::connect(
'/cooks/:action/*', array('controller' => 'users', 'action' => 'index')
);
さらに柔軟な追加機能として、カスタム route 要素を指定できます。この機能により、コントローラアクション用のパラメータが、URL のどこにあるのかを定義できるようになります。リクエストがあると、このカスタム route 要素は、コントローラの $this->params の中に入ります。これは、パラメータに名前を付けるのとは異なる仕方で扱われます。違いに注意してください。パラメータに名前を付けた(/コントローラ/アクション/名前:値)ものは、$this->passedArgs の中に入りますが、カスタム route 要素のデータは、$this->params の中に入ります。カスタム route 要素を定義する際には、正規表現によって、URL が正しく作られているか、作られていないかを CakePHP が判断できるようにします。
Router::connect(
'/:controller/:id',
array('action' => 'view'),
array('id' => '[0-9]+')
);
これは、/コントローラ名/id という形で、どんなコントローラからでもモデルを表示(view)できるようにする例です。connect() に指定されている URL には2つの route 要素があります。controller と :id です。:controller 要素は、CakePHP のデフォルト route 要素です。ルータは URL 内のコントローラ名を見つけることができます。:id 要素はカスタム route 要素なので、connect() の3番目のパラメータ内の正規表現で、どうやってマッチさせるのかを明示する必要があります。こうすることで、CakePHP はアクション名ではないと区別でき、URL 内の ID を見つけることができます。
この route が定義されると、/apples/5 というリクエストは、/apples/view/5
としたのと同じことになります。どちらも、ApplesController の view()
メソッドを呼びます。view() メソッド内では、$this->params['id']
を使って渡された ID を知ることができます。
もし、アプリケーション内でコントローラが1つだけで、コントローラ名を URL 中に表示したくない場合 (例えば、 URL を /home/demo の代わりに /demo にしたい場合):
Router::connect('/:action', array('controller' => 'home'));
この例も知れば、routing の達人です。
Router::connect(
'/:controller/:year/:month/:day',
array('action' => 'index', 'day' => null),
array(
'year' => '[12][0-9]{3}',
'month' => '0[1-9]|1[012]',
'day' => '0[1-9]|[12][0-9]|3[01]'
)
);
ややこしいものですが、route が非常に強力であることを示す例です。この URL では、4つの要素があります。最初のものはよく知っているもので、まずコントローラ名が来ることを CakePHP に伝えます。
次に、いくつかのデフォルト値を指定します。コントローラ名に関係なく、index() アクションが呼ばれるようにします。そして、day パラメーター(URL の4つ目の要素)のデフォルト値を null として、これがオプションであることを設定します。
最後に、年(year)、月(month)、日(day)の数値にマッチする正規表現を指定します。
設定すると、この route は、/articles/2007/02/01、/posts/2004/11/16、/products/2001/05 (day パラメータは、オプション)といった URL にマッチするようになります。対応するコントローラの index() アクションに渡し、$this->params の中にはカスタム指定した日付パラメータを入れます。
アクションが次のように定義されていて、$this->params['id']
の代わりに $articleID
を使用して引数を受け取りたいと仮定します。ただ、Router::connect()
の第3引数に特別な配列(array)を追加するだけです。
// some_controller.php
function view($articleID = null, $slug = null) {
// ここに何かしらコードを書く
}
// routes.php
Router::connect(
// E.g. /blog/3-CakePHP_Rocks
'/blog/:id-:slug',
array('controller' => 'blog', 'action' => 'view'),
array(
// これは単にアクション(action)で ":id" を $articleID にマッピングするため、順番は重要です。
'pass' => array('id', 'slug'),
'id' => '[0-9]+'
)
)
これで逆のルーティング機能が追加されたので、以下のようにURL配列に渡すことができます。ルートで定義されているので、CakeはURLをどのように作成したらよいかがわかっています。
// view.ctp
// これは /blog/3-CakePHP_Rocks へのリンクを返すでしょう
<?= $html->link('CakePHP Rocks', array(
'controller' => 'blog',
'action' => 'view',
'id' => 3,
'slug' => Inflector::slug('CakePHP Rocks')
)) ?>
たいていのアプリケーションには、権限のあるユーザだけが情報を変更できる管理画面が必要です。そのために /admin/users/edit/5 のような特別な URL を準備することがよくあります。CakePHP では、コア設定ファイル内の Routing.prefixes にプレフィックスを設定することでプレフィックスルーティングを有効にできます。また、プレフィックスはルータに関連しますが、/app/config/core.phpで設定することに留意してください。
Configure::write('Routing.prefixes', array('admin'));
コントローラ(controller)内では、プレフィックスとして admin_
をメソッドの前につけたすべてのアクション(action)が呼び出されます。users
を例にすると、/admin/users/edit/5
というURLへのアクセスで、UsersController
の admin_edit
メソッドが、引数5で呼び出されます。ビューファイルはapp/views/users/admin_edit.ctpとなります。
URL /admin を、pagesコントローラの
admin_index
アクションにマップするには次のような route を使います。
Router::connect('/admin', array('controller' => 'pages', 'action' => 'index', 'admin' => true));
Routing.prefixes
に値を追加することによって、複数のプレフィックスを使うように
Router を設定することもできます。もし、
Configure::write('Routing.prefixes', array('admin', 'manager'));
と設定すると、Cakeはadminとmanagerの両方のプレフィックスに対するルートを自動的に生成します。各々の設定されたプレフィックスのために、以下のルートが生成されるでしょう。
$this->connect("/{$prefix}/:plugin/:controller", array('action' => 'index', 'prefix' => $prefix, $prefix => true));
$this->connect("/{$prefix}/:plugin/:controller/:action/*", array('prefix' => $prefix, $prefix => true));
Router::connect("/{$prefix}/:controller", array('action' => 'index', 'prefix' => $prefix, $prefix => true));
Router::connect("/{$prefix}/:controller/:action/*", array('prefix' => $prefix, $prefix => true));
adminルーティングのように、全てのプレフィックス付きアクションはプレフィックス名を接頭辞としてつけるべきです。/manager/posts/add
がPostsController::manager_add()
にマッピングされるからです。
プレフィックスルートを使うときに重要な点は、HTML ヘルパーを使用してリンクを作成するなら、プレフィックスを用いた呼び出しの管理も楽になります。HTML ヘルパーを使ったリンクの例は次のようになります。
// プレフィックスがつけられたルートに行く
echo $html->link('Manage posts', array('manager' => true, 'controller' => 'posts', 'action' => 'add'));
// プレフィックスとお別れする
echo $html->link('View Post', array('manager' => false, 'controller' => 'posts', 'action' => 'view', 5));
プラグインルーティングはpluginキーを使います。プラグインを示すリンクを作ることができますが、pluginキーをURL配列に追加してください。
echo $html->link('New todo', array('plugin' => 'todo', 'controller' => 'todo_items', 'action' => 'create'));
逆に、進行中のリクエストがプラグインのリクエストで、プラグイン無しのリンクを生成したいときは、以下のようにできます。
echo $html->link('New todo', array('plugin' => null, 'controller' => 'users', 'action' => 'profile'));
plugin => null
と設定することによって、ルータに作りたいリンクがプラグインの一部ではないということを伝えることができます。
ルートで異なるファイル拡張子を扱う場合は、ルート設定ファイルに特別な1行が必要です。
Router::parseExtensions('html', 'rss');
これは全てのマッチするファイル拡張子を削除して、残りの部分を解析するようにルータに指示します。
もし/page/title-of-page.htmlのようなURLを作りたいのなら、以下に例示するようなルートを作ることになります。
Router::connect(
'/page/:title',
array('controller' => 'pages', 'action' => 'view'),
array(
'pass' => array('title')
)
);
そして、ルートに遡って合致するリンクを作成するには、シンプルに次のようにします。
$html->link('Link title', array('controller' => 'pages', 'action' => 'view', 'title' => Inflector::slug('text to slug', '-'), 'ext' => 'html'))
カスタムルートクラスによって、個々のルートがどうやってリクエストを解析するか、リバースルーティングを扱うかを拡張・変更することができるようになります。ルートクラスはCakeRoute
を継承しmatch()
とparse()
のどちらか一つ、または両方を実装します。parseはリクエストの解析に、matchはリバースルーティングの取り扱いのためのものです。
routeClass
オプションを用いてルートを作成し、使おうとする前にあなたのルートを含んだファイルを読み込めば、カスタムルートクラスを使うことができます。
Router::connect(
'/:slug',
array('controller' => 'posts', 'action' => 'view'),
array('routeClass' => 'SlugRoute')
);
上記のルートはSlugRoute
のインスタンスを作り、カスタムパラメータの取り扱いを実装できるようになります。
Cakeの命名規約は非常に便利です。データベースのテーブルを、big_boxes、モデルをBigBox、コントローラをBigBoxesControllerとすることができ、それですべてが自動的に協調するようになります。CakePHPがすべてをつなぎ合わせることができるのは、単語の単数形と複数形をinflecting(語尾変化、屈折)させているからです。
CakePHPのinflector(複数形化、単数形化、キャメルケース化、アンダースコア化するクラス)がうまく動かない場合があります。(特に英語圏以外)CakePHPがFociをFishだと分からないのであれば、独自のルールを書いて、CakePHPに教えることができます。
カスタムインフレクションの読み込み
app/config/bootstrap.phpでInflector::rules()
を使うことによって、カスタムインフレクションを読み込むことができます。
Inflector::rules('singular', array(
'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
'uninflected' => array('singulars'),
'irregular' => array('spins' => 'spinor')
));
または、
Inflector::rules('plural', array('irregular' => array('phylum' => 'phyla')));
これらは、与えられたルールをコアのルールより優先的にcake/libs/inflector.phpで定義されたインフレクションセットにマージします。
追加の環境設定が必要な場合には、CakePHPのブートストラップファイルを使用しましょう。/app/config/bootstrap.phpです。このファイルは、CakePHPのコアのブートストラップのすぐ後に実行されます。
このファイルは、よくあるブートストラップ作業を行うのに便利です。:
便利関数の定義
グローバル定数を登録
モデル、ビュー、コントローラの追加のパスの定義
ブートストラップファイルに何か追加する際には、MVCのソフトウェアデザインパターンを崩してしまわないように注意しましょう。整形用の関数をここに書いてコントローラの中で使いたくなったりするかもしれないからです。
その衝動に抵抗しましょう。後で良かったと思うことでしょう。
AppControllerクラスの中に何かを置くことを考えても良いでしょう。このクラスは、アプリケーション内のすべてのコントローラの親クラスです。AppControllerは、コントローラのコールバックを使ったり、すべてのコントローラから使える関数を定義したりするのに便利な場所です。