CakePHP3 環境ごとに設定ファイルを分ける方法


CakePHP3 version 3.0.9 で環境ごとに設定ファイルを分ける方法について書きます。 FuelPHP だと app/config/development などの中に 上書きする設定ファイルを記述しますね。

CakePHP3 で環境ごとに設定ファイルを作る場合にも config/development というディレクトリを作って対処するのがいいと思います。 でも、既存のコードではできないので少し手を加えます。

ファイルを書き換えて環境ごとの設定を読み込むようにする方法

環境変数を利用し、且つ環境設定用のファイルを作成します。

bin/cake.php-e オプションを受け付けるように変更します。 -e が設定されている場合に、その値を環境変数に設定するためのスクリプトファイル(env.php)を作成します。

ハイライトされている部分のコードを bin/cake.php に追加します。

次に、 config/bootstrap.php の最初で env.php を読み込み、環境変数を設定します。

そして config/bootstrap.phpConfigure::load を追加します。

env.php.gitignore に入れておくのがいいと思います。

こうすることで、bin/cake xxx -e development などとした場合には、 development 環境の設定ファイルを読み込むようになります。 また、 bin/cake server -e development とすれば開発環境用の設定でビルトインサーバが起動します。 サーバ(Apacheなど)で環境変数 CAKE_ENV を設定すればそれが使えます。

なぜこんなに回りくどいことをするのか

-eオプションをつけるだけではなく、 ファイルを作成してファイルを読み込むということをやっています。 それには理由があります。

cake.php で環境変数を設定してしまうと、 bin/cake server -e development とサーバを起動したとき、 起動時には cake.php が実行されるので環境変数を設定できるのですが、 http リクエスト を受けた場合はcake.phpが実行されないため環境に応じた設定ファイルを読み込むことができません。 (参考: CakePHP 3 コントローラ実行までのプロセスを追う) そこで、 cake.php で環境変数を設定するスクリプトを作り、 リクエストを受けた際にも実行される bootstrap.php で、 作ったスクリプト(env.php)を実行することにしました。

解説

Configure がなにをやっているのか

設定ファイルを読み込むのは bootstrap.php を見ると、 Configure::config, Configure::load が関係していそうだというのがわかります。 これらの関数をまず見てみます。

Configure クラス は vendor/cakephp/cakephp/src/Core/Configure.php で定義されています。

Configure::config

コメントから、エンジンを追加するメソッドだとわかります。 パラメータはひとつめが識別するためのキーとなるもの、 ふたつめがエンジンのインスタンスですね。 また、このメソッドを使って同じ名前のエンジンを2回設定すると、後に設定されたもので上書きされることもわかります。

bootstrap.php では、 Configure::config('default', new PhpConfig()); とありましたので、 デフォルトのエンジンとして new PhpConfig() を追加していることになります。

Configure::load

Configure::config で設定されたエンジンを使って設定値をロードするメソッドです。

ひとつめのパラメータでロードするファイルを指定します。 スラッシュで区切ればディレクトリの階層も表現できます。

ふたつめのパラメータで Configure::config で設定したエンジンを指定してロードします。 エンジンのキーが格納される引数は、Configure::config では $name でしたが、 ここでは $config です。 もしエンジンが設定されていなければ false を返して終了です。

みっつめのパラメータで マージするか完全に上書きするかが決まります。 全環境で共通のものは1箇所に書きたいので、 追加設定を読み込む際は true にしましょう。

以上より、 Configure::load(filepath, 'default', true) で設定ファイルをマージできることがわかりましたね。 細かいところはすっとばして説明しているので、厳密にいうと Hash::merge なども調べないといけませんが。

もし存在しないファイルをロードしたらどうなるか

やってみればわかるわけですが、どんな処理をやっているか見てみましょう。 bootstrap.phpConfigure::load を合わせて見るとわかりますが、 設定ファイルは PhpConfig のメソッド read で読み込んでいます。 PhpConfigvendor/cakephp/cakephp/src/Core/Configure.php にあります。

エラーがでることがわかりますね。 $config はコメントにもあるように過去の遺物と思われます。