Zend_Deteにゃやられた2007年10月13日 23時39分13秒

ごめん、ZF入門、また遅れてます。その代わりってわけじゃないけど、Zend_Dateネタを2つほど。

Zend_Date::addYear()にゃやられた

DBで「現在日から1年以内」を検索するって、まぁありがちなパターンを処理する必要があるので、日付周りでラクしようと思ってあんまりつかってなかったZend_Dateを使ってみることにした。メソッド調べたらおあつらえ向きに「addYear」だの「addDay」だのがあるので、

$date1 = new Zend_Date();
$date2 = $date->addYear(-1)->addDay(1);
なんて具合にして、「BETWEEN $date2 AND $date1」ってクエリ組み立ててみたんだけど全然データが引っかかんない。なんで?

仕方ないので組み立てたクエリ確認したら、$date1と$date2に同じデータが入ってるじゃん

感覚的に、日付型は値型のように思っていて、addYear()すると演算結果が反映されたクローンが返ってくるように思ってたんだけど、破壊的なメソッドだったのね。むぅ。

仕方ないのでクローンを作成したかったんだけどクローンメソッドもないみたいなので、

$date1 = new Zend_Date();
$date2 = new Zend_Date( $date1 );
$date2->addYear(-1)->addDay(1);
ってな感じに落ち着いたんだけど。

しかし、PHPってなんでnewしたオブジェクトをそのまま使えないんかな。

$date2 = new Zend_Date($date1)->addYear(-1)->addDay(1);
とかって記述できりゃいいのに。じゃなければ、
Zend_Date::create( $date1 );
なんてファクトリがあればそのままメソッドチェーンできるのに。

Zend_Date::isDate()にゃやられた

DBからデータ取得してページにレンダリングするって用途はよく話で、数値や日付をレンダリング時にフォーマットしたいってのもよくある話。なので、値とデータ型とフォーマット指定を渡してついでにエスケープ(つか、htmlspecialchars())も通すビューヘルパーを作ってみたのだが、これ使うとやけにサーバからのレスポンスが遅い。

最初は発行しているSQLに問題あるのかなと思ったけどそちらはあまり問題がないので、フォーマット処理そのものに問題があるのかと思ってさらに調べてみたら、以外なものがボトルネックになっていた。

日付型としてフォーマット指示を出した際に、値が日付型にできるかをチェックするため「Zend_Date::isDate()」でチェックしていたのだが、これのコストがかなり高くついていたのだ。

流し込むデータの出所はDBからfetchしたデータに限られるので割り切って単純な正規表現でのチェックに切り替えたとたん、嘘のようにレスポンスがよくなってびっくり。

まぁ文字列の解析処理になるだろうから、そう軽い処理じゃないのはわからんこともないけど、ここまでコスト高いと、むりやり「new Zend_Date()」して例外補足したほうがいいんじゃねーの?って思う。

ループ処理中にこれ持ち込むと、想像以上に足を引っ張られるのでご注意を。