PHPでURIを扱うものをつくろうの会

こんばんは!こっちでは最近寒かったり暑かったりしますが風邪など引いてないですか?最近本屋でどうぶつしょうぎを見つけて衝動買いしてしまったんですが、考えたらやってくれる相手が近くにいなくて悲しい思いをしています…。子供さんがいたら買ってあげるといいかもしれません。

あと最近PHPをやることになっているので、NetBeans 6.8 beta + PHPUnit 3.4.2の試用とPHPURIの勉強をかねてPHPURIを扱うものをテスト実装しようとしています…というのが今回のお話です。PHPの関数名がフリーダムでやりきれない思いになったりarrayとかempty()とかの挙動に引っかかったりしながらこんな感じのことを考えてつくっています。

  • RFC 3986ベースでできるだけRFCに沿って実装する
    • 相対参照(relative reference)はURIとして表現しないとか (RFC 3986 section 1.2.3)
    • mailto:addr1%2C%20addr2 と mailto:?to=addr1%2C%20addr2 と mailto:addr1?to=addr2 を比較して等しくなるようにするとか (RFC 2368 section 2)
    • RFC 3986 + scheme固有でできるだけちゃんと正規化するとか (比較に必要なので)
  • 一般的構文, http:, https:, ftp:, file:, mailto:, data: あたりに対応したい
  • RubyURIの生成手順*1は良いと思うので生成手順とクラスの構成はRubyURIに近い形にする
  • URI生成時にデフォルトでURIを正規化すると非正規形のURIが表現できないのでデフォルトで正規化しない (.NET FrameworkのSystem.Uriはデフォルトで正規化するみたいです)

今のところhost(IP-literalとIPv4address)以外の解析とチェック、一般的構文の正規化(ポートの正規化とかドットセグメントの削除とか)ができるようになっているところです。RFC 3986は親切なことに実装例が書いてあるのでありがたいです。

IRIをどうするかはまだ決まっていません。mailto:の正規化はできないかもしれません(そもそも正規形が何かについて書いていなさそうなのと、mailbox内のdomainの小文字化が出来そうかわからないので…)。

mailto:とdata:の謎のurlcとかurlcharとかは今のところ無視してRFC 3986の一般的構文として解析してからscheme固有の制限のチェックなどをすることにしています。ただurlcとかurlcharがRFC 2396のuricなら、queryの区切り子("?")がuricに含まれていること、RFC 2396のopaque_partの部分がRFC 3986だとpath-rootlessとqueryに収束する(と思う)関係で、例えばdata:text/plain,foo?barを解析するとpathが"text/plain,foo"でqueryが"bar"みたいに分かれてしまうのが何だか面白くないです…。

あとPHPのどのバージョンに合わせるかなんですが、遅延静的束縛を使わないといけない形になっているので今は5.3以上になってしまっています。割り切って完全に5.3以上にするならcreate_function()は面倒なので無名関数を使ったりしたいです。

ちょっと文章の整理ができていないですがもう夜遅くなってきたのでこのお話の続きは今度にして寝ます。ではー。

*1:Kernel#URI()とかURI.parse()からschemeを見てURI::GenericかURIモジュールの@@schemesに登録されたURI::Genericのサブクラスのインスタンスを生成する形