Home

日記
Zend_Db_Table::findでの戻り値Edit

primary key検索のfindは、引数にスカラーも配列も受け付けるけど、配列の要素が1つしかないときにRowSetじゃなくRowを返す仕様がとてもうざい。

$keys = somefunction(); // 何らかの条件にマッチするkeyの配列を返す
$rowset = $table->find($keys);
foreach ($rowset as $row) {
// 何らかの処理
}

みたいな書き方をしたときに、somefunctionがたまたま一つしか結果を返さなかったときに、$rowsetがRowになっちゃってちゃんと動かない。

配列の要素数を見て戻り値の型を切り替えるのではなく、引数の型がscalarかarrayかで戻り値の型を決める方が妥当じゃないか。

Published At2006-06-18 00:00Updated At2006-06-18 00:00

日記
Zend Frameworkの記事を書きましたEdit

にZend Frameworkの記事を書きました。サンプルアプリケーションのRSS/Atomフィードリーダーは技評さんのサーバーからダウンロードできますし、うちのサーバーで見ることもできますんで、Zend Frameworkアプリのサンプルを見てみたい方はどうぞ。逐一コメントを入れておいたんで、原稿本文を読むよりもサンプルのソースを読んだ方が話が早いかもしれません。素のサンプルではなくちょっと応用が入っているんで、これでZend Frameworkの基本を学ぼう、という人には向いてないかもしれませんが。

それにしても、もう一ヶ月以上前に書いたんで「本誌発売時点では公開されているであろう0.1.4」としておいたのに、まだ0.1.4が公開されていないとはなー。そういやようやくむかーし報告したログレベルのバグがtrunkで修正されてたよ。あとプロジェクト管理システムをtracからJIRAに変えたみたいね。確かにtracはお手軽なのはいいけど、真面目に管理しようとするといろいろ機能が足りてないからなー。JIRAはそういう意味では使えるけれども、あまりにお手軽さに欠けるのがガンだよなー。俺は前に使ったことがあるから使い方が分かったけど、使ったことがない人にはずいぶん(バグ報告等の)敷居が高くなったんじゃなかろうか。

Published At2006-06-21 00:00Updated At2006-06-21 00:00

日記
RSSからのオートインポート機能Edit

1470.netリニューアル版で、新しくつけるとうれしいんじゃないか機能案。

(blogの)RSS/AtomフィードのURIを登録しておくと、そのエントリー情報に含まれる、MM/Memoで対応可能なアイテム(URL、ASIN、位置情報など)について、自動的にメモを登録する機能があると便利だろうか。

そうすると、あるURLや本に関する情報を、blogに書いてもMM/Memoに登録しても、どちらにしても最終的にはMM/Memo側で統一的に扱う(検索する)ことができるようになる。

いったんURLをメモして、後からblogに書いたりしたときでも、自動的にURLをキーに検索されるようになるし。

Published At2006-06-21 00:00Updated At2006-06-21 00:00

日記
microformats対応Edit

別にmicroformatsでなくてもいいんだけど。

リニューアル版MM/Memoでは、URLやASINをキーにそのメモを取るという仕組みではなく、一つのメモに複数のURLやASINや位置情報や日時情報を添付する、といった形にする予定。

その際に、単にメモとURLやASINをリンクするだけでなく、どういう意味でリンクされているのか、も表現できるとずいぶんデータの表現力が高まるはず。

従来「関連URL」としてオプションでURL情報を追加できたけど、あれを「via」として使う人や、文字通り「related」として使う人など、いろいろいたはず。それを明示的に「via 〜」「related 〜」などとして登録できるようにしよう、という話。

で、その際にはどういうデータ形式および表現形式を使うのが妥当だろうか、と考えたときに思いついたのがmicroformatsなわけだけど、真面目に既存のmicroformats関連情報を調べる暇もなさそうだし、なんちゃってmicroformats(というかユーザーが自由にrel="〜"とかclass="〜"とか相当の情報を登録できるようにするだけで、システム側ではその内容まではサポートしない)で十分かなー。

Published At2006-06-21 00:00Updated At2006-06-21 00:00

日記
タグの自動取り込みEdit

そういやmicroformats関連ってことで、URLが指定されたときに、そのURLで示されるコンテンツが何らかのタグ情報を含んでいた場合、自動的にそのタグ情報を取り込む機能とかあると便利かなー、などと思い、でもいろんなサービスにアドホックに対応するのはいやだから、もしかしていまどきのその手のサービスは、みんなタグ情報へのリンクにはrel="tag"とか持たせていたりして、汎用的にタグ情報を抽出できたりするんじゃね、などとちょっと期待しつついくつか見てみたけど、んなとこまだ全然ねーのね。microformatsって言葉が出てきてからずいぶん経つ気がするけど、まだ全然(実装レベルでは)流行ってない? それともすでにobsolete気味?(実は「やっぱりRDFだよ」方面に向かってたりして)

Published At2006-06-21 00:00Updated At2006-06-21 00:00

日記
Amazon WebサービスにHTTP/1.1でアクセスするとゴミが出るEdit

Zend_Http_Clientをincubatorバージョンに変えてテストしていたら、Zend_Service_Amazonの動作がおかしい*1。なんでかなーと原因をたどっていったら、Amazon WebサービスへのリクエストがHTTP/1.0からHTTP/1.1に変わったことが原因だった。

以下再現コード。HTTP/1.1でのリクエスト。

$socket = fsockopen('webservices.amazon.co.jp', 80);
fwrite($socket, "GET /onca/xml?ResponseGroup=Request&SubscriptionId=[Subscription ID]&Service=AWSECommerceService&Operation=ItemLookup&ItemId=4774128104 HTTP/1.1\r\n");
fwrite($socket, "Host: webservices.amazon.co.jp\r\n");
fwrite($socket, "Connection: close\r\n");
fwrite($socket, "\r\n");
while (!feof($socket)) {
echo fread($socket, 8192);
}
fclose($socket);

結果。

HTTP/1.1 200 OK
Date: Thu, 22 Jun 2006 04:39:16 GMT
Server: Server
x-amz-id-1: 0TR0TFSQ68NG6TEF33NC
x-amz-id-2: Qc8vxAunuvNVpdAORHM5YVP2pvxgSkOv
Connection: close
Transfer-Encoding: chunked
Content-Type: text/xml; charset=UTF-8
36f
<?xml version="1.0" encoding="UTF-8"?><ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2005-10-05"><OperationRequest><HTTPHeaders><Header Name="UserAgent"></Header></HTTPHeaders><RequestId>0TR0TFSQ68NG6TEF33NC</RequestId><Arguments><Argument Name="SubscriptionId" Value="[Subscription ID]"></Argument><Argument Name="ResponseGroup" Value="Request"></Argument><ArgumentName="Operation" Value="ItemLookup"></Argument><Argument Name="Service" Value="AWSECommerceService"></Argument><Argument Name="ItemId" Value="4774128104"></Argument></Arguments><RequestProcessingTime>0.0139038562774658</RequestProcessingTime></OperationRequest><Items><Request><IsValid>True</IsValid><ItemLookupRequest><ItemId>4774128104</ItemId><ResponseGroup>Request</ResponseGroup></ItemLookupRequest></Request><Item><ASIN>4774128104</ASIN></Item></Items></ItemLookupResponse>
0

「36f」「0」などのゴミが混ざっている。上記を見るとボディ部の前後にゴミが混ざるように見えるけれども、もっと長い結果を返すリクエストの場合は、定期的に類似したゴミが混ざる。バッファ(最大0x2000バイト)から出力した文字数を16進数で出力しているっぽい。

続いてHTTP/1.0に変える。

$socket = fsockopen('webservices.amazon.co.jp', 80);
fwrite($socket, "GET /onca/xml?ResponseGroup=Request&SubscriptionId=[Subscription ID]&Service=AWSECommerceService&Operation=ItemLookup&ItemId=4774128104 HTTP/1.0\r\n");
fwrite($socket, "Host: webservices.amazon.co.jp\r\n");
fwrite($socket, "Connection: close\r\n");
fwrite($socket, "\r\n");
while (!feof($socket)) {
echo fread($socket, 8192);
}
fclose($socket);

以下、結果。

HTTP/1.1 200 OK
Date: Thu, 22 Jun 2006 04:39:16 GMT
Server: Server
x-amz-id-1: 0TXZ0YSV0W5WA2TQGFCD
x-amz-id-2: oew++LbGRDya+Ju9I49Vx7bXa6CAsn4V
Connection: close
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?><ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2005-10-05"><OperationRequest><HTTPHeaders><Header Name="UserAgent"></Header></HTTPHeaders><RequestId>0TXZ0YSV0W5WA2TQGFCD</RequestId><Arguments><Argument Name="SubscriptionId" Value="[Subscription ID]"></Argument><Argument Name="ResponseGroup" Value="Request"></Argument><ArgumentName="Operation" Value="ItemLookup"></Argument><Argument Name="Service" Value="AWSECommerceService"></Argument><Argument Name="ItemId" Value="4774128104"></Argument></Arguments><RequestProcessingTime>0.00991702079772949</RequestProcessingTime></OperationRequest><Items><Request><IsValid>True</IsValid><ItemLookupRequest><ItemId>4774128104</ItemId><ResponseGroup>Request</ResponseGroup></ItemLookupRequest></Request><Item><ASIN>4774128104</ASIN></Item></Items></ItemLookupResponse>

こっちは正常な結果が返ってくる。

Amazon WebサービスへのリクエストはHTTP/1.0で行わなければならない、とか決まっていたんだっけ? どこに報告するべき問題なのかいまいちよくわからない。ひとまずZend_Http_Clientのincubator版はHTTP/1.1がデフォルトになっちゃってるから、このままだと正式版に格上げされたときにトラブりそうだな。

ああ

Transfer-Encoding: chunkedだからか! これで正常なのね。っつーか、HTTP/1.1で送るならば受信側がちゃんと対応しないといけないのね。HTTP/1.1のRFCちゃんと読んでおこう。

一応資料

ハイパーテキスト転送プロトコル -- HTTP/1.1 3.6.1 チャンク形式転送エンコーディング

すべての HTTP/1.1 アプリケーションは、"chunked" 転送コーディングを受信しデコードできなければならないし、理解できない転送コーディング拡張は無視しなければならない。

※参照するRFCを2068から2616に変更しました。

*1 コンストラクタのインターフェースが変わっていたのは修正した

Published At2006-06-22 00:00Updated At2006-06-22 00:00

日記
1470.netリニューアル開発テストバージョンEdit

まだプロトタイピングの段階なんで、ベータとか以前のバージョンだけど、だいぶまとまってきたんで、いったん晒してみる。まだ実用レベルではないし、データも保全しない可能性が高い(DB設計からやり直す可能性がある)のでそのつもりでどうぞ。

Zend Frameworkとの格闘も落ち着いてきて、前向きな作業の割合が増えてきたけど、そうなると何となく後回しにしてきたUI周りの設計を本格的にやらなきゃいけなくなって、懸案事項が盛りだくさんだ。

あと、JavaScriptの基礎知識が不足しているのに、Google Maps+Yahoo UI Library+prototype.jsとかを無理矢理使っているんで、ひとまず動くように書いたきちゃないコードを、いまどきのコーディングスタイルに直す必要があるだろうなー。

あと、今回はものすごく富豪的な作り方をしているんで、それでどのくらい負荷的に耐えられるのかも検証する必要がある。DB設計的には、従来バージョンよりもずいぶんましにはなっているんだけど、データ取得系はたいていデータオブジェクトのプロパティに見せかけつつ、裏でがんがんクエリーを投げる仕組みにしちゃってるからなー。

修正

  • コメントと評価の処理がおかしかった(保存および編集時の復元処理にバグがあった)のを修正

Published At2006-06-23 00:00Updated At2006-06-23 00:00

日記
「グループ」機能の導入Edit

1470.netリニューアル開発テスト版に「グループ」機能を追加した。「グループ」はタグとまったく同じ機能を持ち、技術的には単に一つのメモに「タグ」と「グループ」という二つのタグ機能がついただけのものだが、いろいろと応用範囲が広いんじゃないかと思っている。

まず、従来MM/Memoで「メモ種別」として用意していた機能の代替として使える。この機能を使っている人はあまり多くなかったけれども、これはタグよりもキーワードの揺らぎを少なくすることによって、確実にメモをグルーピングするために用意した機能だ。

MM/Memoの「メモ種別」では文字数として2バイトしか使えないので、自由度がない代わりに、簡単なルールを決めたらほぼ確実にそのルール内でメモを分別できるようになる。また、その命名規則はタグの名前空間を汚さない。

たとえば、「ToDo」というタグを付けた場合、それが自分にとっての「ToDo項目」という意味なのか、それとも一般的な「ToDo」に関連する情報であることを意味しているのかが、タグだけでは区別できない。そこで、前者の「自分にとってのToDo項目である」という意味を表すタグを「グループ」に逃がすことによって、同じ「ToDo」というタグを使い分けることができるようになる。

また、ある本について購入前は「購入予定」グループに、購入後は「購入記録」グループに、読み終わった後は評価付きで「読了記録」グループに変更することによって、状態管理をグループを使って表現することも可能だろう。「後で読む」などもどちらかというとタグよりはグループに入れた方が管理しやすいように思う。

さらに、この「グループ」を活用して、いわゆるまとめサイトや人力検索系サイト的なものも表現できるのではないかと考えている。

たとえば「PHPのフレームワークに関する情報サイトを教えてください」というグループを作り、興味を持った人がそのグループに関連サイトをブックマークしていく。するとそのグループの新着情報や人気(登録数が多いURI)情報が、いわゆるまとめサイト的な情報となっていく。

もちろん同様のことはタグを使っても可能だが、タグの名前空間をそういう用途で汚してしまうのは、ユーザーにとってはあまりうれしくないだろう。タグの名前空間自体は通常の使い方で利用しつつ、そういう特殊な用途には同じ機能を持つ別の検索軸である「グループ」を使うことにより、タグの可能性が広がるのではないだろうか。

まあそういう使い方がうまく回るようにするためには、ユーザーインターフェースあるいはサイトナビゲーション的な工夫が必要になるだろうが、一応そういうことを考えて「グループ」という軸を導入してみたわけだ。

Published At2006-06-26 00:00Updated At2006-06-26 00:00

日記
これからのフィードはどの形式を採用するべきかEdit

1470.netリニューアル開発テスト版にはまだRSS出力機能は一つもつけていない。

というのは、新バージョンではURI以外の情報もいろいろ含んでおり、また一つのメモに複数のURIが所属することもできるため、単純なURI=1アイテム型のRSSで置き換えることができないから、ってことが表面上の大きな理由ではあるんだけど、それ以前の問題として、今から新しく作るアプリケーションではどの形式のフィードを採用するのがいいんだろう、という根本的なところでの疑問もあったりする。

昔はいろいろ考えるのが面倒だし、日本での採用事例も多い(=提供するフィードを利用するアプリケーション側で扱いやすい)しってんで、基本的にRSS 1.0を使ってきたんだけど、最近ではフィードをハンドリングするライブラリも充実してきたし、後者の理由はもはや大きな理由にはならないだろう。で、前者の理由に関しても、今回はどうせ位置情報とか日時情報とかの扱いが絡むんで、いろいろ調べたり考えたりしなければならないことが多いから、ついでにちゃんと考えてもいいんじゃないかと思ったりしている。

ポイントとしては、URL、位置情報、日時情報あたりをうまくまとめて扱いやすく、将来的な活用可能性が高く(フィードとしてだけでなく、フィード内に含まれる各データ自体もそれなりに再利用性を持つ)、さらに現時点でもそれなりに利用できる(現行のフィードリーダー等でちゃんと扱うことができる)ようにするには、どういうフィードデータを吐けばいいのか、というところ。これもそれPla(ggerで後付けで加工すれば何とでもなるじゃん)禁止。

自分でもぼちぼち調べていきますが、よさげな情報をお持ちの方、ご教示ください。

1470.netリニューアル開発テスト版のアカウントをお持ちの方は

関連しそうな情報を「これからのフィードはどの形式を採用するべきか」グループでメモしておいてもらえるとありがたいです。

Published At2006-06-27 00:00Updated At2006-06-27 00:00

日記
MM/MemoからのインポートEdit

MM/Memoからのデータインポートスクリプトを作って、試しに自分のメモをインポートしてみた。MM/Memoではできなかった*1解析とか検索とかがまっとうに動くので結構楽しい。

MM/Memoユーザーの方で、自分のデータもリニューアル開発テスト版の方にインポートして欲しい方は、リニューアル開発テスト版の方にアカウントを登録した上で、MM/MemoのユーザーID(数値)とリニューアル開発テスト版のアカウント名(英数字)を教えてください(ここのコメントにお願いします)。

ちなみに対応するのはURLとASINに関するメモのみで、位置情報(互換性がなくなった)やテレビ番組情報(リニューアル版では取り扱っていない)はインポートできません。あと、URLに関しては古いデータだとすでに情報が取れないURLも結構たくさんあるみたいです。

データがある程度そろった状態じゃないと分からないこともいろいろあるので、ご協力お願いします。

ちなみに

今回のはあくまでも主にテスト目的のインポートであって、正式移行時のインポートの機会はまた別に用意しますよ。

特に問題がなければ、今回移行したデータはそのまま正式稼働時にも残すつもりではいますが、大規模な仕様変更(特にデータ構造的に)があった場合は、データをリセットする可能性もありますので。

*1 SPAMまみれで巨大化したblogmapデータベースと一体化していて重いクエリーが流せなかった

Published At2006-06-28 00:00Updated At2006-06-28 00:00