symfonyのキャッシュマネージャーが取れないとき

symfonyで、キャッシュが効いているページを強制的にクリアしたいとき、

  $cacheManager = $this->getContext()->getViewCacheManager();
  $cacheManager->remove('quiz/index?id='.$quizIdToRemove);

とかやってたのですが、デバッグ環境でエラーが出てしまいました。

Fatal error: Call to a member function set() on a non-object in ...

実環境でエラーにならないのでうんうん悩んで調べてみたら、デバッグ環境ではcache: off にしてました。getViewCacheManager()はキャッシュ使ってなければnullを返すようです。

# 考えてみたら当たりまえか

問題は、これがfatal errorで止まっていたためにトランザクションが完了していなかったことです。

cacheManagerを取得したときは、必ずnullチェックして、キャッシュが使われてるときだけ呼び出しましょう。 > 自分

SimpleXMLElementをunserializeするとエラーになる

simplexmlで取得したオブジェクトをシリアライズしても、元に戻せない。

$gottenItems = simplexml_load_file($serviceUrl);
$hoge = unserialize(serialize($gottenItems));

エラーはこれ

Warning: unserialize() [function.unserialize]: Node no longer exists in *.php on line *

simplexml_load_stringのマニュアルのコメントでも回避策とか提案されている。

なんでこんなエラーに出会ったかというと、symfonyの関数キャッシュを使おうとしたら、対象の関数の返すのがsimplexml_load_file()の返すオブジェクトそのままだったからで、symfonyの中でエラーになった。

以下のコードは、検索結果をファイルにキャッシュする関数をsymfonyで書いたもの。symfonyのキャッシュフォルダ以下に生成させることで、キャッシュコントロールをsymfony管理下に置いている。

public static function search($words, $offset = 0, $results = 10) {
	$function_cache_dir = sfConfig::get('sf_cache_dir').'/mysearch';
	$fc = new sfFunctionCache($function_cache_dir);
	$results = $fc->call('doSearch', $words, $offset, $results);
	return $results;
}

コメントにあった回避策取るよりは、そもそもシリアライズするポイントが間違ってる、ということかなと。

XMLのままキャッシュに入れるか、SimpleXMLElementから必要なものを取り出してその配列やオブジェクトをserializeするように変更しよう。