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()」して例外補足したほうがいいんじゃねーの?って思う。

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

WSHでMSHTML.HTMLDocumentを扱えた2007年10月14日 05時41分08秒

久々のWSHネタ

via: Windows Script Programming: コマンドラインでHTMLファイルをテキストファイルにする。

うは、こりゃすごい。昔2chのWSHスレで「InternetExplorer.ApplicationをcreateしなくてもMSHTML扱える」っていうようなレスを見たことあったんだけど、具体的にどうやるのか知らなかったが、リンク先の記事にばっちり書いてあった。

こんな方法で取得できるとは...

この記事では、

var htmlfile = new ActiveXObject("htmlfile");
ってな方法でオブジェクトを作成していて、これでMSHTMLのHTMLDocument(=documentオブジェクト)が取得できる。

んで、これのparentWindowを参照するとHTMLWindow2(=windowオブジェクト)があっさり取得できる(ちなみにこのwindowのlocation.hrefはabout:blankだった)。

ちなみにこの操作を行ってもIEのプロセスは起動していなかった。インプロセスでIE相当のオブジェクトを取得できたわけだ。

クリップボード使い放題

WSHでクリップボードを扱う場合はIE経由が定番だったのだが、IEはアウトプロセスサーバのため、インスタンスの生成コストがべらぼーに高く、あんまり手軽に扱えなかった。

が、今回の方法は前述のとおりインプロセス動作のようなので、さくっとwindowオブジェクトにアクセスでき(IE経由の場合と違い、わざわざabout:blankにnavigateしなくてもいいし)、

var ClipUtil = {
	get : function() {
		return new ActiveXObject("htmlfile").parentWindow
			.clipboardData.getData("text");
	},
	set : function(text) {
		new ActiveXObject("htmlfile").parentWindow
			.clipboardData.setData("text", text);
	}
};
なんてユーティリティ作って、さくさくとクリップボードデータが操作できたりする。また、インプロセスだから終わった後にプロセス落とさなくてもいいってのもうれしい。

tumblrのpostからlinkのみ抽出した簡易ブックマーク2007年10月15日 04時09分01秒

なんとなく作ってみた

Tumblr APIアサブロランキング取得で利用させてもらった「Webページ取得JSONP」を組み合わせて、自分のtumblrにlinkでpostしたやつだけ抽出する簡易ブックマークページを作ってみた。なんとなく。

現物はこちら

DOMParserって知らんかったわ

Webページ取得JSONP」のおかげでソースを取得するのはまったく苦労がないんだけど、クロスブラウザでのXMLってほとんどやったことがなかったので、ソース文字列として取得したXMLからどうやってDOMツリーを構築するのかわからなかったんだけど、いろいろ調べたらこんなとこが見つかった。

試してみたら、Firefox2/Opera9/Safari3で動いた。なるほど、IE以外のモダンブラウザは「DOMParser」クラスを実装していると。IE以外。

ま た I E か

なんちゃってラッパーを作る

ブラウザ判別してもいいんだけど、IEとそれ以外って仕切りになるなら、IE向けにラッパーをでっち上げればいいやと思って、

if( typeof( window.DOMParser ) == "undefined" && window.ActiveXObject ) {
  window.DOMParser = Class.create();
  window.DOMParser.prototype = {
    initialize : function() {},
    parseFromString : function(src, type) {
      var result = new ActiveXObject("MSXML.DOMDocument");
      result.loadXML(src);
      return result;
    }
  };
}
なんて具合にでっち上げてみた。といってもparseFromStringメソッドのみの実装だけど。わりとうまくいった。

その他もろもろ

このほか、指定ノードのテキストを取得するのに、またもIEのみ仲間はずれというか明後日の方向だったので、これはノード渡してテキスト返す関数でごまかして、あとキャッシュ対策でTumblr API叩くときにnew Date().valueOf()でてきとーにオレオレパラメータを追加してみた。

あとは現物のソースを参考にしてください。たいしたことしてないけど。format.js使ったりしてるけど、URLの組み立てと日付フォーマットくらいにしか使ってない(し、ソースそのものも小さい)ので、まあ適当に工夫すれば同じようなことできると思います。

蛇足

あとで気が付いたが、「XML を JSON に変換するサービス - ベータ版を公開 :: Drk7jp」使えばもっとラクにできた予感が...orz

ClipUtil、ダメじゃん2007年10月16日 02時14分09秒

がーん、書き換わらん!

こちらの記事で、IEではなくMSHTMLから取得したwindowを利用したクリップボードユーティリティクラスを掲載したのだが、落とし穴が。

クリップボードからテキストを取得するのは問題ないのだが、テキストを設定してもクリップボードの内容が書き換わらないのだ。

いやー、未検証なコードを載せてしまいました。申し訳ない。ClipUtil.get()はちゃんと動きます。

失敗してるのか?

で、clipboardData.setData()を実行結果を確認すると、こちらのリファレンスにあるとおりtrueが返ってきているので、見かけ上はうまくいっているようなのだが、実際は更新されない。むぐぐ。

やっぱIE経由しかないのか?

こちらの掲示板(の「 2004年 04月 02日 18時 55分 39秒」の投稿)によれば

一方、SetDataはWScript/CScriptが死にます。
であるとか。試したところ死にはしなかったけど、状況は変わらず。

はっきりしたところはわからんけど、セキュリティ周りの話かも知らんし、おとなしくIE使うしかないのかな。ちぇ。

ふご?ページランクがついてる2007年10月28日 04時06分55秒

このページについてさんでこのブログの情報をちょくちょく確認しているのだが、「Google PageRank」はこれまでずーーっと「0」だったのに、今日はなぜか「3」になっている。

まあ、ページランクがどの程度重要なものかもよくわからんし、10段階の3程度なので別にたいした話じゃないんだが、なかったものに点数がつくのってうれしいやね。

なんて、約2週間ぶりの記事なのにたいそうな駄文でお茶を濁してみたり。来週いっぱいはまだ余裕がなさそうだが、そろそろZF入門再開せにゃ。