ConfigReaderInterface とは?

CakePHP の Configure ディレクトリに ConfigReaderInterface っていう interface が定義されているんですね。知らなかった。これは設定ファイルを読み込むために用意されたインターフェイスでコアでは PhpReaderIniReader の二つがそれを実装して組み込まれています。

コアコードでは Acl の設定において実例を確認できますが、 例えば有名どころのプラグイン TwitterBootstrap の BootstrapHtmlHelper のコンストラクタでタグのフォーマットを上書きする際にも用いられていたりします。少し違う使い方として、 Configure クラスのリーダーとしてアタッチして用いることもできます。有名なのかもしれないけど自分は今まで存在を知らなかったんで使ったことがなかった。日本語の記事を見た記憶が無いので探したけどやはり見つからなかったので忘れないようにメモ。

CakePHP は 2系。(ここでは紹介しませんが Configure クラスの一部の機能で 2.2 から追加されたものもあります)

何が出来るのか?

これを使うと、例えば何らかの設定を一つのファイルにまとめて、それを読みに行くことができます。

と言ってしまうと、そんなことわざわざこれを使わなくても出来ると思いがちですが、設定ファイルの設置や記述方法に最低限のルールが適用されるため、ある程度の制限がはたらくことで管理しやすくなることと、設定の読み込みのAPIが統一されるというのは大きなメリットではないでしょうか。読み込みの逆に、設定をファイルに書き込むことも可能です。

(※使い方はここで紹介するのとは別に、 Configure クラスで設定値を読み込むのにも使えます。今回は紹介しませんが興味のある方はこちらをご覧ください → Reading and writing configuration files )

さてとにかく使い方。とても簡単です。

設定ファイルの設置

まず設定ファイルを php ファイルにするか、 ini ファイルにするかを決めます。

ini ファイルは基本的には php.ini と同じ記述方法です。 php の perse_ini_file 関数 を用いています。更に、入れ子にした配列をも扱えるように IniReader クラスで拡張してあります。

ファイルの設置箇所

デフォルトではConfig ディレクトリ以下に設置します。任意の場所にしたい場合はコンストラクタの引数としてパスを渡します。

new IniReader(); // アプリケーション(もしくはプラグイン)の Config ディレクトリ
new IniReader('/path/to/conf/'); // 設定ファイルのディレクトリを指定

ファイル名

拡張子に必ず .php もしくは .ini を付けること。それ以外の制限はありません。

記述できること

php の場合、$config という名前の変数に設定を記述します。そしてその値が設定値として返されます。

ファイルはそのまま通常のphpファイルとしてインクルードされるので、何らかの手続を記述しても問題ありません。ただし、 $config という名前の変数がセットされていないと例外が投げられます。

<?php
/**
 * my_conf.php
 */
$config = array(
    'website' => array(
        'maintainance' => true,
    ),
    'webmaster' => array(
        'name' => 'zuborawka',
        'webmaster-mail' => 'webmaster@example.com',
    ),
);

ini の場合、ini ファイルとしてなんでも記述できます。

# my_conf.ini
[website]
maintainance = 1

[webmaster]
name = zuborawka
mail = webmaster@example.com

ちなみに ini ファイルの書き込みは複数行にまたがるデータは保存できません。

また、キーにドット “.”  を用いることで配列を不完全ではありますがエミュレートできます。(IniReader::_parseNestedValues() が処理)

例: ini ファイルでの記述

[capitals]
asia.japan = tokyo
asia.taiwan = taipei
europe.italy = milano

これを IniReader::read() で解釈すると・・・

array(
    'capitals' => array(
        'asia' => array(
            'japan' => 'tokyo',
            'taiwan' => 'taipei',
        ),
        'europe' => array(
            'italy' => 'milano',
        ),
    ),
);

このようになります

設定の読み込み

まずクラスファイルを指定してオブジェクトを作成。特別な作法はありません。インスタンスは使い捨て。(なお、Configureクラスではメンバー変数(protected)にセットしたものを再利用しています)

class SomethingClass {
    private function loadConfig(){
        $readerClass = 'PhpReader'; // または 'IniReader'
        App::uses($readerClass, 'Configure');
        $reader = new $readerClass();

そして設定ファイル名を指定して読み込みます。

        $file = 'my_conf'; // または 'my_conf.php', 'my_conf.ini'
        $config = $reader->read($file);
        // ........
    }
}

設定の保存

もしも実行時の設定を保存しておきたいなら、ConfigReader::dump() で楽勝です。(Configディレクトリを書き込み可能にしておく)

$config = $this->config;
$config['new-param'] = 'This is a new !';
$reader->dump('new_conf', $config);

以上です。

プラグインの作成だけでなく、アプリケーションの設定ファイルだけを別に管理したいときに使えると思います。何種類かの設定の組み合わせをそれぞれ別のファイルに保存しておけば、読み込み時にファイル名を指定するだけでその設定がロードされるので使い道は結構あるのではないでしょうか。基本設定を読み込ませた後にカスタマイズファイルで上書きなんて言うのもありかも。アプリでの実装なら Configure クラスと組み合わせた使い方のほうが良さそうなのでそちらはマニュアルを参考にしてください。