YAMLを読み込む / キャッシュする
前回(たくさんのパラメータを効率よく管理する)で触れたYAMLハンドラ。SyckよりはLibYAMLのほうがよさそうだな…とも思ったのだが、Windowsローカルに開発環境を作るのが非常に大変なので、相変わらずSpycを使うことにした。キャッシュはPEAR::Cache_Liteに変更して、読み込みだけキャッシングするラッパを実装してみた。
【KwappaYamlReader.php】
<?php /** * YAMLリーダ with Cache_Lite * * YAMLの読み込みとキャッシングを行う。 */ //============================================================================== // constants //============================================================================== define("KWAPPA_YAML_CACHE_DIR", "/path/to/cache_dir/") ; define("KWAPPA_YAML_CACHE_ID_PREFIX", "KWAPPA_YAML_CACHE") ; //============================================================================== // includes //============================================================================== require_once "Cache/Lite.php" ; //============================================================================== // class //============================================================================== /** * YAMLリーダ with Cache_Lite */ class KwappaYamlReader { // Cache_Lite object private $cache ; // Cache_Lite用YAML向けパラメータ private static $CACHE_OPTIONS = array( 'cacheDir' => KWAPPA_YAML_CACHE_DIR, 'lifeTime' => null ) ; /** * コンストラクタ */ public function __construct() { $this->cache = new Cache_Lite(self::$CACHE_OPTIONS) ; } /** * YAML読み込み * @param string $fileName YAMLファイル(フルパス) * @returns array パース済み配列 * @throws RuntimeException 何らかのエラー */ public function readYaml($fileName) { // キャッシュIDを生成する $cache_id = KWAPPA_YAML_CACHE_ID_PREFIX . "_" . md5($fileName) ; // キャッシュを取得 $cached_yaml = $this->cache->get($cache_id) ; // 読み込もうとするファイルが存在しない if (!file_exists($fileName)) { // ファイルが存在しないのにキャッシュが残ってるとイヤなので消去 if ($cached_yaml) { $this->cache->remove($cache_id) ; } $this->raiseError("YAML [{$fileName}] is not found.") ; } // キャッシュヒット if ($cached_yaml) { // 更新されていればクリアして再キャッシュ if (filemtime($fileName) > $this->cache->lastModified()) { $this->cache->remove($cache_id) ; $cached_yaml = null ; } // 更新されてなければこのデータを返す else { $cached_yaml = unserialize($cached_yaml) ; } } // キャッシュヒットしない : YAMLを読み込んでparse if (!$cached_yaml) { // YAMLを読み込んでパース require_once "lib/Spyc.php5" ; if (!$cached_yaml = Spyc::YAMLLoad($fileName)) { $this->raiseError("Spyc::YAMLLoad failed.[{$fileName}]") ; } // キャッシング if (!$this->cache->save(serialize($cached_yaml), $cache_id)) { $this->raiseError("failed to cache YAML [{$fileName}].") ; } } return $cached_yaml ; } /** * 何らかの不具合があったら例外を投げる * @param string $msg message */ private function raiseError($msg) { throw new RuntimeException($msg) ; } } ?>
Cache_Lite#setToDebugをコールすると、Cache_Lite内でエラーが発生した場合即死するようになる。実装初期のデバッグにはいいが、ある程度他に組み込みが進むと逆に不便そうなので、何か異常事態が発生したらRuntimeExceptionをthrowするようにしてある。
現在Cache_Liteのパッケージページを見に行くと大きく「このパッケージはメンテナンスされてないよー」と書いてある。一瞬ものすごく憂鬱な気分になるが、つい先月にStableリリースがあったばかり。どういうことなんだろう?とTrackbacksをたどってみたら、新任のメンテナが「ぼくの最初のリリースなの」とエントリしていたので一安心。ページのメンテナンスが追いついてないだけのようだ。
See also:
・たくさんのパラメータを効率よく管理する