SYSTEM238 / NOTES1 / Zend Framework1 / ZF1で設定ファイルを使用する。

NOTES1 PROG1
ZF1で設定ファイルを使用する。
Zend Framework1(ZF1)でINI形式の設定ファイルを使用する手順のノート

ZF1の設定ファイルを扱うクラスZend_Config_Iniは結構便利です。複数設定ファイルを扱ったり、本番環境と開発環境を切り替えたり、値の読込だけでなく書込みもできたりします。

Zend_Config_Iniは、INI形式のファイルに保存された設定データをオブジェクトのプロパティとして扱えるようにします。

INI形式ファイルの作成例

Zend_Config_Iniでは階層化された設定データを扱うことと、セクション間の継承関係を扱うことができます。

設定データの階層構造は、キーの名前をドット(.)で区切ることによって表現します。

セクションの継承関係は、セクション名を[子セクション名:親セクション名]と指定することで表現します。

[application.ini]

; --
; 本番環境用の設定をセクション[production]で記述
; --
[production]
phpSettings.display_startup_errors = 0  ; phpSettings.~でPHPの環境設定ができる
phpSettings.display_errors         = 0
phpSettings.default_charset        = UTF-8
resources.frontController.params.displayExceptions  = 0
bootstrap.path   = APP_PATH "/Bootstrap.php"  ; PHPの定数も使用可能
bootstrap.class  = "Bootstrap"
appnamespace     = "Application"

app.debugMode  = 0
app.title      = '◯◯◯システム'

; -- db設定
db.adapter  = "Pdo_Pgsql"
db.host     = "localhost"
db.dbname   = "postgres"
db.username = "dbuser"
db.password = "dbpassword"

; $INI->arrayEx->toArray()で配列として取得できる
arrayEx.1   = "赤"
arrayEx.2   = "白"
arrayEx.3   = "青"

; --
; 開発環境用の設定をセクション[development : production]で記述
; productionを継承してdevelopmentで差分を上書き〜追加することができる。
; 開発環境はエラー出力したり、DBの接続先を変更したりする設定を記述できるので便利。
; --
[development : production]
phpSettings.display_startup_errors  = 1
phpSettings.display_errors          = 1
phpSettings.error_reporting         = E_ALL
resources.frontController.params.displayExceptions = 1

app.debugMode  = 1
app.title      = '<font color="#ff0000">【開発環境】</font>◯◯◯システム'

db.username = 'dbuser_dev'
db.password = "dbpassword_dev"

フロントコントローラ実行時に設定を読み込む

フォロントコントローラ実行時の設定ファイルの使用方法です。phpの設定などはこのタイミングでしか有効になりません。

INIファイルは先の説明で使った「application.ini」を使ってます。

[index.php]

require 'Zend/Application.php';

//開発 or 本番 ... 開発と本番で定数の値を変更する
define('APPLICATION_ENV',   'development'); //開発
//define('APPLICATION_ENV', 'production');  //本番

//INI内でも参照している定数
define('APP_PATH',  '/[省略]/application');

//iniフィル
define('APP_INI',   '/[省略]/application.ini');

//'production'を継承した'development'の値が使用される
$application = new Zend_Application(APPLICATION_ENV, APP_INI);
$application->bootstrap()->run();

設定を読み込む

Zend_Config_Ini使用方法を説明します。

INIファイルは先の説明で使った「application.ini」を使ってます。定数は「index.php」が定義されているものとします。

application.iniを開発環境で取得

$this->INI  = new Zend_Config_Ini(APP_INI, APPLICATION_ENV);

$this->INI->app->title;         //<font color="#ff0000">【開発環境】</font>◯◯◯システム
$this->INI->arrayEx->toArray()  //array('1'=>'赤', '2'=>...)

複数のINIファイルをマージする

//allowModificationをtrueで変更可能になる。(省略時は変更不可)
$this->INI  = new Zend_Config_Ini(APP_INI, APPLICATION_ENV, array("allowModifications"=>true));
//マージ
$this->INI->merge(new Zend_Config_Ini(USER_INI, APPLICATION_ENV));
//変更不可にする
$this->INI->setReadOnly();

複数のINIファイルを利用することで、一画面中の表示件数など「運用開始後に変更したい設定」とDB接続値など「変更したくない、ユーザに触ってほしくない設定」を別ファイルに分けることができます。

複数のINIファイルを別々オブジェクトとして扱ってもいいんですが、一つにまとめた方がスマートだと思う場合は上記手順で一つにまとめられます。

それから、同じ設定が複数INIファイルにあった場合は、後から読み込んだ方が有効になります。

設定を書き出す

Zend_Config_Ini使用方法を説明します。

INIファイルは先の説明で使った「application.ini」を使ってます。定数は「index.php」が定義されているものとします。

//すべてのセクションを設定ファイルから読み込みますが継承は読み飛ばします
$userIni = new Zend_Config_Ini(USER_INI, null, array('skipExtends'=>true, 'allowModifications'=>true));

//値を変更します
$userIni->maxLine = 200;

//設定ファイルを書き出します
$writer = new Zend_Config_Writer_Ini(array('config'=>$userIni, 'filename'=>USER_INI));
$writer->write();    

//変更不可にする
$this->INI->setReadOnly();

変な値が設定されるとプログラムが実行できなくなる場合があります。そうなると、エディタで直接INIファイルを修正するしかなくなります。設定値のチェックは厳密に!!

それから、継承された値の書き換えはできないようです。ZF1のマニュアルに下記の記述があります。プログラムから書き換えるINIファイルは個別に用意してください。

既存の設定ファイルを読み込んで変更をする場合は、 すべてのセクションを読み込んで継承を読み飛ばすことが大切です。そうすることで、値がマージされてしまうことがなくなります。そのために、コンストラクタでskipExtendsオプションを指定します。
Zend_Config_Writer - Zend_Config_Writer - Zend Framework

その他

キー名の区切りについて

INI形式ファイルの作成例で述べたようにキー名はドット(.)で区切ることができますが、あまり細かい単位で区切らない方がいいです。

区切りのドット(.)はソース中ではオブジェクトの区切り(->)になります。細かく区切りすぎるとキー名を検索するときなどにドット(.)からオブジェクト区切り(->)に変更するのが面倒くさくなります。

$app.user.name.kana  → $ini->app->user->name->kana
$app.userNameKana    → $ini->app->userNameKana

その環境変数、本当にINIファイルにする必要があるの?

Zend_Config_IniによるINIファイルの読み込みは結構重い処理です。中間コードキャッシュができる環境ならハードコーディングした方がパフォーマンスがいいです。

ほとんど(多分、すべて)のIDEではINIのキーはコード補完が効きません。定数やクラスのスタティック変数・クラス定数にすればコード補完が効くのでプログラミングが楽になります。

PHPなんかのスクリプト言語はコンパイルの必要がないので、運用環境でもソース中の環境変数を書き換えることは簡単です。INIファイルを編集するのと手間は大して違いません。

定数や環境設定用のクラスを別ファイルに切り出す方が楽チンかもしれませんよ。