開発環境と本番環境でDBの設定や定数の値を変更したりしますよね。
今までのやり方でもそんなに不便はなかったのですが、database.php以外も切り替えることが多くなったので新しくしてみました。

database.phpだけ切り替えたい方は、下の方に今までの方法も記述しておきました。

環境

      CakePHP2.0.4
      PHP5.3.8

切り替え方法

app/Config/Env/ 配下に存在しているファイルによって対応した環境を設定するという方法です。

環境設定用ファイル準備

app/Config/の中にEnvというフォルダを作成し、その中にファイルを置きます。
ファイルの中身は何も必要ありません。拡張子もなしです。

置くファイルは開発用、本番用ですが、対象となる環境によってファイル名を切り替えてください。
この例でいれば、先頭に#がついていないものが有効です。
ファイル名を変更するのが煩わしい場合は必要ないものを削除してしまいましょう。
Development
#Production

環境用の個別ファイル準備

開発用、本番用のそれぞれの設定ファイルを作成します。
で、置く場所はapp/Config/の中にそれぞれのフォルダを作成して置いておきます。

app/Config/Development

  • bootstrap.php
  • database.php

app/Config/Production

  • bootstrap.php
  • database.php

環境判別用のファイル作成、読み込み

app/Lib/の中にLoadEnv.phpを作成します。
これはapp/Config/Env の中にあるファイルによって読み込む設定ファイルを変更します。

function loadEnv() {
    $environments = array('Development', 'Production');
    foreach ($environments as $env) {
        if (!is_file(APP . 'Config' . DS . 'Env' . DS . $env)) {
            continue;
        }
        Configure::write('CAKE_ENV', $env);
    }
}
function loadBootstrap() {
    $envPath = APP . 'Config' . DS . Configure::read('CAKE_ENV') . DS . 'bootstrap.php';
    if (is_file($envPath)) {
        include_once $envPath;
    }
}

database.phpファイル作成

database.phpをそれぞれのフォルダに配置します。
読み込むファイルが違うので、全部$defaultで大丈夫です。
app/Config/Development/database.php

class DATABASE_CONFIG {
	public $default = array(
		'datasource' => 'Database/Mysql',
		'persistent' => false,
		'host' => 'localhost',
		'login' => 'login',
		'password' => 'password',
		'database' => 'database_name',
		'prefix' => '',
		'encoding' => 'utf8',
	);
	public $test = array(
		'datasource' => 'Database/Mysql',
		'persistent' => false,
		'host' => 'localhost',
		'login' => 'login',
		'password' => 'password',
		'database' => 'database_name',
		'prefix' => '',
		'encoding' => 'utf8',
	);
}

app/Config/Production/database.php

class DATABASE_CONFIG {
	public $default = array(
		'datasource' => 'Database/Mysql',
		'persistent' => false,
		'host' => 'localhost',
		'login' => 'login',
		'password' => 'password',
		'database' => 'database_name',
		'prefix' => '',
		'encoding' => 'utf8',
	);
}

環境別のbootstrap.phpファイル作成

bootstrap.phpは必要なものや、変更したいものだけ記述します。

環境によって変更しないものはapp/Config/bootstrap.phpに記述してしまいましょう。
例えば、Debug のレベルは開発用では「2」にするこはあっても本番で「2」にするこはまず無いと思いますので、ここに記述します。
また、ファイルの有無によって環境を判断するLoadEnv.phpを呼び出す処理も記述しておきます。
app/Config/bootstrap.phpには以下のように記述します。

Configure::write('debug', 0);

require_once(APP . DS . 'Lib' . DS . 'LoadEnv.php');
loadEnv();
loadBootstrap();

で、開発用のapp/Config/Development/bootstrap.phpに「2」を設定します。

Configure::write('debug', 2);

これで開発用だけレベルが「2」になるというわけです。
app/Config/Production/bootstrap.phpには必要がなければ何も記述しなくても大丈夫です。

データベース設定読み込み

最後にデータベースの設定を読み込みます。
通常、データベースの設定を記述しているdatabase.phpに以下の処理を記述して、環境によって読み込む処理を変更します。
app/Config/database.php

require_once Configure::read('CAKE_ENV') . DS . basename(__FILE__);

これで完了。あとは、app/Config/Env/の中にあるファイルを切り替えればOKです。

以下にある環境変数で入れ替える方法を参考にしました。

http://higelog.brassworks.jp/?p=366
http://www.1×1.jp/blog/2006/09/cakephp_db_config.html

 

簡単な切り替え方法

ここからはシンプルで簡単な切り替え方法です。

環境判定用として以下の設定を追加します。
「development」になっている部分を環境によって書き換えます。
app/config/bootstrap.php

Configure::write('CAKE_ENV', 'development');

データベースの接続先を設定します。
app/config/database.php

class DATABASE_CONFIG {
	public $development = array(
		'datasource' => 'Database/Mysql',
		'persistent' => false,
		'host' => 'localhost',
		'login' => 'login',
		'password' => 'password',
		'database' => 'database_name',
		'prefix' => '',
		'encoding' => 'utf8',
	);
	public $production = array(
		'datasource' => 'Database/Mysql',
		'persistent' => false,
		'host' => 'localhost',
		'login' => 'login',
		'password' => 'password',
		'database' => 'database_name',
		'prefix' => '',
		'encoding' => 'utf8',
	);
	public $test = array(
		'datasource' => 'Database/Mysql',
		'persistent' => false,
		'host' => 'localhost',
		'login' => 'login',
		'password' => 'password',
		'database' => 'database_name',
		'prefix' => '',
		'encoding' => 'utf8',
	);
}

AppModelを作成して、コンストラクタを追加
app/Model/AppModel.php

class AppModel extends Model {
    function __construct($id = false, $table = null, $ds = null) {
        $connection = Configure::read('CAKE_ENV');
        if (!empty($connection)) {
            $this->useDbConfig = $connection;
        }
        parent::__construct($id, $table, $ds);
    }
}

これで、データベースを切り替えたいときはbootstrap.phpの設定値を変更するだけで済みます。
「SERVER_ADDR」や「REMOTE_ADDR」を使って判定するのもありなのかもしれませんが、それだとコンソールで使えないので使ってませんでした。
あと、環境を判定するのはDATABASE_CONFIGではなく、AppModelに記述していました。
これは、DATABASE_CONFIGはあくまでも設定ファイルなので、そこに処理を入れるのはちょっと嫌だったので。
(なんでクラスにしたんだろ)

もっとこうした方がよいというものがありましたら教えて頂けると幸いです。