view.ymlのdefault/metas/titleでサイトワイドのタイトルを定義しているのに、layout.phpや_header.phpでタイトルを手打ちするのは嫌だなあ、ということで、どこから辿ってview.ymlのデータが取れるのかを探しました。
layout.php等で、
sfContext::getInstance()->getResponse()->getTitle()
を呼ぶと、view.ymlの中のタイトルが取れます。これを<h1>とかに放り込めばOK。
view.ymlのdefault/metas/titleでサイトワイドのタイトルを定義しているのに、layout.phpや_header.phpでタイトルを手打ちするのは嫌だなあ、ということで、どこから辿ってview.ymlのデータが取れるのかを探しました。
layout.php等で、
sfContext::getInstance()->getResponse()->getTitle()
を呼ぶと、view.ymlの中のタイトルが取れます。これを<h1>とかに放り込めばOK。
いつも関数名が思い出せなくなるけど、どうやって検索したら見つかるかも毎回悩んでしまうので、自分用にメモ。get_object_varsですね。
# 「オブジェクトを配列にする」, “Object2Array”
昨日の、SimpleXMLElementをserializeしてもunserializeで元に戻せない件で、キャッシュでどうしてもserializeを使いたいことから、SimpleXMLElementの中のデータを配列に変換してしまうという方針にしました。
一つずつ取ってきて配列を再構築してもいいんですが、この手の処理はget_object_vars関数を使えばやってくれるので、その方が間違いが少ないと思います。
ただ、get_object_varsは再帰的に配列にしてくれるわけではありません。、SimpleXMLElementの要素の中にまた、SimpleXMLElementがあれば、それはそのまま残ってしまうため、今回の「serializeさせる」という目的ではこれだけでは不十分です。
PHPマニュアルのコメントにも、どうやってrecursiveに変換するか、というコード例がいろいろ出てきています。
今回は、SimpleXMLElementとget_object_varsで調べて出てきたIBM developerworks のPHP で XML をJSON に変換するを参考に、defineをconstに直すなど調整をしたものを使うことにしました。再帰の深さを制限できるようになってます。
PHP Hacksの目次を見ると53. 任意のオブジェクトを配列に変換する、とあるので、これ持ってる人はたぶんここに似たような話が載ってるんじゃないかな、とも思いました。
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するように変更しよう。