はちゅにっき

こっちのブログはまったり更新

環境変数で config を切替えるためのクラス

id:cho45 さんが作成された Config::ENV という Perl モジュールがとても便利で、最近設定ファイルが必要な場合には、ほとんどのケースでこのモジュールを利用しています。
使い方については Advent Calendar に掲載された、以下の記事を読んでください。

環境変数で config を切替えるためのモジュール
http://perl-users.jp/articles/advent-calendar/2011/hacker/1

ということで、まれによく使う PHP でも同じことが出来たら便利なんじゃないかと思い、作成してみました。

php-Config-ENV
https://github.com/hatyuki/php-Config-ENV

Perl のように DSL っぽい書き方は出来ませんが、だいたい同じようなことができます。

使い方

まずは以下のような感じで config クラスを作成します。

<?php
require_once 'Config/ENV.php';
class MyConfig extends Config_ENV { }  # Config_ENV クラスを継承し MyConfig クラスを作成

MyConfig::envname('APP_ENV');  # 環境変数 APP_ENV の値に従い設定を切替える
MyConfig::defaultenv('development');  # APP_ENV が未定義の場合は 'development' モード

MyConfig::common( array(  # 環境変数の値に依存しない共通の設定値
    'name' => 'Perl',
) );

# 環境変数 APP_ENV の値に応じた設定を記述
MyConfig::config('development', array(
    'dsn' => 'sqlite:/tmp/development.db',
) );

MyConfig::config('production', array(
    'dsn' => 'sqlite:/tmp/production.db',
) );

利用する側は以下のようにすれば、環境変数 APP_ENV の値に応じた設定値を取得することができます。環境変数は $_SERVER['APP_ENV'] に値を代入しても OK ですし、Apacheホスティングされている Web アプリなら .htaccess に書く、なんて方法もあると思います。

<?php
require_once 'MyConfig.php';

$_SERVER['APP_ENV'] = 'development';
MyConfig::param('dsn'); # => 'sqlite:/tmp/development.db'

$_SERVER['APP_ENV'] = 'production';
MyConfig::param('dsn'); # => 'sqlite:/tmp/production.db'

そのほかにも、設定を一時的に変更するための Config_ENV::local( ) メソッドや、外部設定ファイルを読み込むための Config_ENV::load( ) も実装してあります。
load( ) については、内部的には Closure を使って実装していて、設定値を利用する直前までファイルをロードしないようにしてあります。
また、Perl のように配列を柔軟に扱うことができないため、Config_ENV::merge( ) というメソッドも追加してあります。このメソッドは Closure をよしなに扱って配列のマージを試みるため、Closure の定義を色々工夫すればいろんな使い方ができると思います。

<?php
require_once 'Config/ENV.php';

# 外部設定ファイル読み込み
MyConfig::config('development', MyConfig::load('config/development.php'));

# Closure (MyConfig::load( ) の戻り値) をよしなにマージして設定
MyConfig::config('production', MyConfig::merge( array(
    MyConfig::load('config/development.php'),
    MyConfig::load('config/otherconfig.php'),
    array('cache' => 'redis'),
) );

# 一時的に設定値を変更する
$guard = MyConfig::local('cache', 'memcached');
echo MyConfig::param('cache'), "\n";  # => memcached
$guard = null;  # 一時的な変更を破棄
echo MyConfig::param('cache'), "\n";  # => redis
?>

# in config/development.php
<?php
return array(
    'language' => 'PHP',
);

ニッチなクラスかもしれませんが、しばらくは PHP で何か作る場合には利用してみようかと思います。