今まで環境に依存するような設定ファイルの切替はbootstrap.phpで処理していた。
でも、それだと1つのbootstrapファイルに複数環境の記述を記載するので、何かあった場合の影響範囲が広い問題があった。
そこで、CakePHP2.2以降から利用できるようになったDispatcher Filtersって機能があったのでこれを使ってみることにした。
Dispatcher Filtersはざっくり言うと、ディスパッチ処理の前後になんか処理を挟めるような機能で、詳しい説明は公式のドキュメント(Dispatcher Filters – CakePHP Cookbook v2.x documentation)を見た方がわかりやすい。
1. 振り分け用のbootstrapファイルを用意する
各環境別に利用したいbootstrapファイルを以下のように用意する
app
∟Config
∟Environment
∟development
∟bootstrap.php
∟stage
∟bootstrap.php
∟production
∟bootstrap.php
2. appディレクトリ配下にRouting/Filterディレクトリを用意する
用意後の構成はこんな感じ。
app
∟Routing
∟Filter
3. フィルター用のクラスを用意する
1.で作成したディレクトリにXXXFilter.phpというファイルを設置する。
(ここではEnvironmentFilter.phpとする)
app
∟Routing
∟Filter
∟EnvironmentFilter.php
4. フィルタリングの中身を記述する
2.で作成したファイルに、環境に依存する設定を環境別に用意したbootstrap.phpに振り分ける処理を記述
<?php App::uses ('DispatcherFilter' , 'Routing' ); class EnvironmentFilter extends DispatcherFilter { /** * 優先度を設定。数字が大きいほど優先度が高い */ public $priority = 12; /** * dispatch前に処理したいので、beforeDispatchに記述 */ public function beforeDispatch($event) { $serverName = getenv('SERVER_NAME'); if (preg_match('/^dev\.hoge\.co\.jp/' , $serverName)) { // development environment $boostrapDirectory = 'development'; } elseif (preg_match('/^stage\.hoge\.co\.jp/' , $serverName)) { // stage environment $boostrapDirectory = 'stage'; } else { // production environment $boostrapDirectory = 'production'; } $bootstrapFilePath = APP . 'Config' . DS . 'Environment' . DS . $boostrapDirectory . DS . 'bootstrap.php' ; if (!file_exists($bootstrapFilePath)) { throw new MissingDispatcherFilterException('boostreap file "' . $bootstrapFilePath . '" not exist. '); } define( 'ENVIRONMENT',$bootstrapFilePath); } }
5. Dispatcher.filtersに設定を追加する
3.で作成したフィルターをDispatcher.filtersに追加して
Configure::write ('Dispatcher.filters' , array( 'AssetDispatcher', 'CacheDispatcher', 'EnvironmentFilter', ));
これでdispatch前に環境依存の設定を読み込むことができるようになった。
この書き方だと、元のbootsrapに影響せずに各環境間の設定を対応することができるので、
保守性が上がりそう。
(まぁbootstrap内でif文を記述すれば同じようなことはできるのだけど、、)