ひとまず使いたい.phpからソースを require_once 'SetConfig.php'; します。で、
SetConfig();
とSetConfig.php内の以下の関数を呼び出してください。
function SetConfig()
{
// 設定ファイルのパス
$dbsettingpath = "../../var/config/DBSetting.ini";
// 読み込み
DbConf::set($dbsettingpath);
}
後述のClassに設定ファイルのパスを渡し、キャッシュの読み込み・作成を行っています。
多数の設定ファイルを使いたい場合はここに追記していきます。
ちなみに設定ファイル(サンプルのDBSetting.ini)はこんな感じ。
[production]
database.type = "PDO_PGSQL"
database.host = "localhost"
database.username = "apache"
database.password = "test"
database.name = "test"
設定ファイルのパスは絶対パスで書くとそれを直さなければならなくなるので、個人的には相対パスをお勧めします。
絶対パスは設定ファイル内にしか書かないように統一すると間違いが少なくなるでしょう。
次。
function makeZendCacheInstance($path)
{
// Zend_Cacheオプション masterFile
$frontendOptions = array(
'lifeTime' => null, 'masterFile' => $path, 'automaticSerialization' => true
);
$backendOptions = array(
'cacheDir' => '../../var/cache/'
);
$frontendName = 'File';
$backendName = 'File';
return Zend_Cache::factory($frontendName, $backendName, $frontendOptions, $backendOptions);
}
Zend_Frameworkのマニュアルほとんどそのままです。
lifeTime は設定しません。キャッシュの再作成を行うトリガーとして masterFile を設定します。
設定ファイルが更新されるとキャッシュを再作成します。
cacheDir はオブジェクトをシリアライズしたデータファイルを格納しておくディレクトリです。権限に注意。
現時点では backendName も File にしているため、シリアライズしたデータをファイルシステムから読み込む負荷がかかります。
Zend_Cache_Backend_Memcached(
memcachedが必要)や
Zend_Cache_Backend_APCの対応が完了すれば、そちらを利用した方が高速になるでしょう。
最後。
class DbConf{
Private static $data;
Private function __construct()
{
}
Public static function get($key, $type = 'database')
{
return self::$data->$type->$key;
}
Public static function set($path)
{
$cache = makeZendCacheInstance($path);
$data = $cache->get('DBSetting_cache');
if(!($data = $cache->get('DBSetting_cache'))){
$data = new Zend_Config_Ini($path,'production');
$cache->save($data, 'DBSetting_cache');
self::$data = $data;
}
else{self::$data = $data;}
}
}
ほとんど
Zend_Configのマニュアルそのまま。クラス名とかはお好みで。
このクラスは中身がほとんどStaticです。(__construct()とかまったく意味がありません)
Staticなメンバであるため、クラスをインスタンス化することなくアクセスが可能です。
これがなぜ必要なのかというと、PHPでは 関数内からGlobalな変数をそのまま呼び出せない(global宣言が必要)であるため。
たとえば以下のようなコードがあるとします。
$instanceA = new ClassA;
$instanceB = new ClassB;
$instanceB->funcB();
class ClassA{
Public Function funcA(){
}
}
class ClassB{
Public Function funcB(){
$instanceA->funcA();
....
}
}
このコードで
$instanceA->funcA();
は効きません(たぶん)。これをやろうとすると、この呼び出しの前に
global $instanceA;
と宣言してやる必要があります(確か)。
各々関数でそれはあまりに面倒であるため、Staticを利用しています。
話を戻して。
if(!($data = $cache->get('DBSetting_cache'))){
この箇所で、まだ有効なキャッシュがある(前回作成したキャッシュより、masterFile の更新日付が新しくなっていない)場合、
$dataに設定ファイルのパース結果が入りますが、ifの中には入らないため、設定ファイルの再パースは行われません。ここ重要。
で、キャッシュがない場合は作成し、
self::$data = $data;
Staticメンバにデータを登録します。
なお、サンプルではINIファイルを利用していますが、Zend_Config_Xmlを利用すればもちろんXMLも利用可能です。
Zend_Config_Xml自体は、シンプルなXMLのパースしかしてくれないので、そっちにXMLの書き方をあわせてやる必要はありますが。
で、値の取得は
Public static function get($key, $type = 'database')
この関数。
Optionalで database と指定しています。設定ファイルで database.*** と記述しているためです。
ここは設定ファイルに応じてわかりやすい感じにしてあげると良いでしょう。
一応、database 以外の記述を混在させてもそれも取得してくれる・・はず。
なのでOptionalを指示してやればなんとかなる・・はず。
呼び出し方。
SetConfig();
echo DbConf::get('type');
SetConfigでStatic変数に一回値を格納したら、あとはDbConf::get('キー名')でアクセスが可能です。
サンプルの設定ファイルで言うと、PDO_PGSQLという文字列が取得できます。
ダブルクォートは入りません。
ルーティングを行うindex.phpで、このクラスが記述されたphpスクリプトのrequire_onceとSetConfig()をしておくと良いでしょう。