イッソノ〜そろそろPHPでの最強CouchDBライブラリ決めようぜ (第1回)
ナカシマ「イソノ〜。今日もテンプレートエンジン界のオーバーテクノロジーで遊ぼうぜ〜」
イソノ「そうだな〜。今日はスクレイピングした結果をさくっと保存したいな〜。*1」
ナカシマ「それならやっぱりCouchDBがナウいよ。」
イソノ「NoSQLって言うんだっけ?」
ナカシマ「CouchDBはドキュメント指向DBって括りに入るね。」
イソノ「最近だと、MongoDBのほうがPHP界隈(日本の)だと注目浴びてるんじゃないか?」
ナカシマ「それを言いだすと、この記事がなんの意味もないじゃないか。。。」
ナカシマ「Futonというアドミン画面があるからvar_dump好きにはオススメだよ」
イソノ「で、PHPでCouchDBを扱うにはどうしたらいいんだい?」
イソノ「CouchDBの導入記事にはcurlが載ってるからexec("curl"..なのかな?」
ナカシマ「お前はSnoopyか!お前はSnoopy.class.phpか!」
ナカシマ「CouchDBのAPIはHTTPだから、httpリクエスト送れば良いってことになるけど、
CouchDB用のライブラリはいくつかあるんだ。」
イソノ「あ、CouchDBのwikiを見ると4つばかりライブラリが載ってるからそれの中から選ぶんだね」
ナカシマ「バカを言うなよ。CouchDBを扱うPHPライブラリは10は越えるよ。」
イソノ「まるでフレームワークの状況じゃないか。。」
ナカシマ「以下にリストとして載っけてみたよ」
http://wiki.github.com/sasezaki/diggin/php-couchdb-clients
ナカシマ「フレームワーク同様、各ライブラリは特徴があるし、選定条件も状況によってまちまちになると思うんだ」
イソノ「最強のを選ぶんじゃなかったのかい?」
ナカシマ「え?」
イソノ「え?」
ナカシマ「対応するPHPのバージョンってのがあるけど、CouchDB用の選定基準になるのはいくつかあるよ。」
イソノ「どういうことが挙げられる?」
ナカシマ「並べてみようか」
- PHPのバージョン - 対応するCouchDBのバージョン - ライブラリが対称とする範囲("モデル"に特化している場合がある) - View対応 - AttachMent対応 - ViewServer利用 - リクエスト送信方法(fget,stream,curl,pecl_http) - JSONエンコード/デコード方法 - 他のフレームワーク・ライブラリとの連携・依存性
ナカシマ「CouchDB自体がまだ開発途上だから対応するCouchDBのバージョンってのも重要だね」
ナカシマ「だから必然的にメンテされてるかってのも重要だと思うんだ」
----- Object_Freezer
イソノ「条件にはライセンスとかテストコード入ってるかとかは入らないのかい。」
ナカシマ「もちろんそうだね。」
イソノ「じゃあテストPHPUnit作者のObject_Freezerってのを……」
ナカシマ「ちょっとまった。ライブラリ名確認したかい?」
イソノ「オブジェクトをふりーずするんだろ?」
ナカシマ「これはPHPオブジェクトのストアリングの一つにCouchDBがあるってだけなんだ。」
レスポンスステータスコードをチェックしてるのか謎なところもあるんでCouchDBクライアントとしては全然おすすめできないね。」
----- PHP-on-CouchとPHPillow
イソノ「じゃあ有力なクライアントって何?」
ナカシマ「今のところ知名度も考慮すると、PHP-on-CouchとPHPillowだろうね」
イソノ「PHP-on-Couchってこの前IBMの記事に載ってた?*2」
ナカシマ「そう。更新が活発でCouchDB0.9からでの特殊リクエストメソッド"COPY"も意識されてるようだしね。枯れてないとも言えるけど」
イソノ「やたらあるprint_rのコメントアウトが気になるんだけど。。」
ナカシマ「PHPillowはezのコミッターでもある人が作者なんだ。」
イソノ「ezって最近Apache Incubatorにプロポーザル出したあのez?」
ナカシマ「そう。PHPコミッター(というか毎コミ記事・後藤さんネタ元)であるJohannes Schlüter
も紹介してるしね。*3」
イソノ「CouchDB自体もApacheプロジェクトだし、相性抜群って訳だ。」
ナカシマ「PHPillow自体がezコンポーネントって訳じゃないらしいけどね。」
----- Phly_CouchとSopha
ナカシマ「次に紹介したいのは、ZFのコミッターでもあるShahar EvronのSophaだ。」
ナカシマ「shevronはZend PHP
カンファレンス2009で”Introduction CouchDB with PHP"っていう講演をしてるよ」
イソノ「あれ、ZFのコミッターが作ったものってリードのマシューが作ったPhly_Couchがあるよね。」
ナカシマ「たしかに、Phly_CouchはZFのプロポーザルにあがったりしてるけど、Attachmentに対応してる節はないししばらくメンテされてないみたいなんだ」
イソノ「あれ、このSophaって中身見るとZFそのものを使ってないの?」
ナカシマ「そう、1.8ぐらいの頃のZFから一部コンポーネントをポートしてあるよ。」
イソノ「なんでそんなことを。。」
ナカシマ「オトナ ノ ジジョウ ワカリマセン」
……第2回につづく(?)
PHP 5.3ではXpathを拡張できる
タイトルでは誇張して煽ってみてますが、PHP5.3より前ではXSLTProcessorでしかついてなくて正直へえ(´・∀・`)だった感じのregisterPhpFunctions()がDOMXPathについたことによって超すごいことになってたんですよ奥さん!(私は今頃しった)
Premature Optimization > XPath regular expression matching in PHP 5.3
PHP: DOMXPath::registerPhpFunctions - Manual
詳細は上記リンク先とマニュアル見てもらえば良いんですが、
$domPath->query("//html:a[php:functionString('preg_match', '$regex', @href)> 0]")
て感じで正規表現にマッチするもの取得とか、ユーザー定義関数もレジストできるので複雑なこともできますね!
たしかperlのxpathのモジュールでも正規表現が使えるとか見たような気がするんですけど、これでウラヤマシイーとか思うこともなくなりましたー(かな?)
PHPでYouTube動画をダウンロードするWozozo_WWW_YouTubeをリリース。
インストール
sudo pear install openpear/Wozozo_WWW_YouTube
使い方
<?php require_once 'Wozozo/WWW/YouTube.php'; Wozozo_WWW_YouTube::download('gQf_QTsvXCU'); //YouTubeのvideoID Wozozo_WWW_YouTube::download('http://www.youtube.com/watch?v=gQf_QTsvXCU'); //URL指定でもOK //直にダウンロードせず、ダウンロードURL取得 $youtube = new Wozozo_WWW_YouTube; echo $youtube->getVideoInfo('gQf_QTsvXCU')->makeDownloadUrl();
Zend Frameworkコマンドようプロパイダーはもちろんつけてますので、
zf enable config.provider Wozozo_WWW_YouTube_Tool_YoutubeProvider
て、感じで実行できます。
保存先はデフォルトでは$_SERVER['PWD']ですが、
configの'save'にファイルパスを指定、もしくはコールバック関数を渡して保存方法を変更できます。
詳しくは今のところソース見てください。
http://openpear.org/repository/Wozozo_WWW_YouTube/trunk/src/Wozozo/WWW/YouTube.php
え?僕はyourfilehost用のZFコマンドが欲しいって?
すでにありますよ。
http://openpear.org/package/Wozozo_Libido_Tool_Provider_YourfilehostProvider
RecursiveIteratorIteratorIteratorIterator
(※画像はI love unicodeの人のスライドの「Code, Ideas, People」からの借用です。)
さて本題の再帰処理です。RubyのArray#flattenと同じようなものを実装してみます。Array#flattenはネストした配列を1次元の配列に平滑化するメソッドです。無名関数にする必要はないですが、再帰のサンプルと言うことで...
$flatten = function($array) use(&$flatten) { $result = array(); foreach ($array as $value) { if (is_array($value)) { // 配列ならこの無名関数を再度呼び出す $result = array_merge($result, $flatten($value)); } else { $result[] = $value; } } return $result; };
こっちのほうが短いっすよ!
$flatten = function (array $a) { $results = array(); array_walk_recursive($a, function ($v, $k) use (&$results) { //$results = array_merge($results, array($k => $v)); だとキーがあって重複したときにダメ $results = array_merge($results, (array)$v); }); return $results; }; $array = array('a' => 1, 5, array(3, array(22, 5, array(9, 500))), 12); echo join (', ', $flatten($array)); //1, 5, 3, 22, 5, 9, 500, 12
PHP5.3で無名関数が搭載されたので、コールバックを使う頻度はあがると思います。(実際にlithiumには無名関数とarray_map、array_walkの組み合わせがいくつかあるし、ZFリードによるミニマルAOPのPhly_PubSubだってコールバックありきだし、またBlankaでも!)
しかしながらブログ記事用のサンプルに突っ込むのは野暮ですけれども、無名関数をそのまま再起するのはモダンじゃない感じがします。ファイル読み込みや、多次元配列内のオブジェクトのメソッドを呼ぶ場合など、遅延評価なことを行うことも考えられます。再帰的に処理するわけなので、みんな大好きSPL系のRecursive群の出番ですね。
$array = new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::LEAVES_ONLY);
ちなみに、↑これをiterator_to_arrayするさいは各個別のarrayのキーはかぶってるので第2引数falseを加えないとだめです。
echo join(', ', iterator_to_array($array, false)); // 1, 5, 3, 22, 5, 9, 500, 12
文字列結合演算子
echo は , か . かって話
http://d.hatena.ne.jp/sotarok/20100321/1269200776
を受けての話ですが、"."こと文字列結合演算子は思い込みでリテラル以外はちょっと微妙になるとおもってました。
<?php class ToString { private $value; public function __construct($value) { $this->value = $value; } public function __toString() { return (string) $this->value; } } echo "a".new ToString('b')."c"; //abc
...実行できるんだ。。
個人的にはvar_dumpっぽい感じだから変数が個別に評価されてく感じですっきりするので","多用してますが。
パフォーマンス的な話は、ユーザーノートにも記載がありますね。
http://php.net/manual/ja/language.operators.string.php
今の pear list -a
PHP5.3使ってます!キリッ!とかのたまってる割にはメインのpearはphp5.2の
(というかubuntuの\phpなので)だったりするので、pearも5.3のbinにしとこうということで、各パッケージ入れ直したりする前よう昔こんなの入れてたのねー的なメモ。
INSTALLED PACKAGES, CHANNEL __URI: ================================== PACKAGE VERSION STATE PEAR_PackageProjector 0.1.3 beta Pit 1.0.0 stable Services_Photozou 1.2.0 stable phpman 0.1.3 beta INSTALLED PACKAGES, CHANNEL DOC.PHP.NET: ======================================== (no packages installed) INSTALLED PACKAGES, CHANNEL OPENPEAR.ORG: ========================================= PACKAGE VERSION STATE HTML_CSS_Selector2XPath 0.1.0 beta IgnoreExceptionIterator 0.1.3 stable Maple4_DocTest 0.2.2 alpha Net_Q4M 0.1.0 beta INSTALLED PACKAGES, CHANNEL PEAR.HATOTECH.ORG: ============================================== PACKAGE VERSION STATE IO_OutputBuffering 0.1 beta INSTALLED PACKAGES, CHANNEL PEAR.HORDE.ORG: =========================================== PACKAGE VERSION STATE Yaml 1.0.1 stable INSTALLED PACKAGES, CHANNEL PEAR.MICHELF.COM: ============================================= (no packages installed) INSTALLED PACKAGES, CHANNEL PEAR.PHING.INFO: ============================================ PACKAGE VERSION STATE phing 2.3.3 stable INSTALLED PACKAGES, CHANNEL PEAR.PHP.NET: ========================================= PACKAGE VERSION STATE Archive_Tar 1.3.3 stable Benchmark 1.2.7 stable CodeGen 1.0.6 stable CodeGen_PECL 1.1.2 stable Config 1.10.11 stable Console_Color 1.0.2 stable Console_Getargs 1.3.4 stable Console_Getopt 1.2.3 stable Console_Table 1.1.3 stable Event_Dispatcher 1.1.0 stable File_Find 1.3.0 stable HTML_CSS 1.5.4 stable HTML_Common 1.2.5 stable HTTP_Client 1.2.1 stable HTTP_Request 1.4.4 stable HTTP_Request2 0.3.0 alpha Image_GraphViz 1.2.1 stable MDB2 2.4.1 stable Net_CDDB 0.3.0 alpha Net_Socket 1.0.9 stable Net_URL 1.0.15 stable Net_URL2 0.3.1 beta Net_UserAgent_Mobile 1.0.0RC3 beta PEAR 1.9.0 stable PEAR_PackageFileManager 1.6.3 stable PHP_CodeSniffer 1.2.0 stable PHP_CompatInfo 1.9.0 stable Structures_Graph 1.0.2 stable Text_Figlet 1.0.1 stable VersionControl_SVN 0.3.1 alpha XML_Parser 1.3.2 stable XML_Util 1.2.1 stable INSTALLED PACKAGES, CHANNEL PEAR.PHPUNIT.DE: ============================================ PACKAGE VERSION STATE File_Iterator 1.2.0 stable PHPUnit 3.4.11 stable phploc 1.0.0 stable INSTALLED PACKAGES, CHANNEL PEAR.PROJECT-P.JP: ============================================== (no packages installed) INSTALLED PACKAGES, CHANNEL PEAR.SYMFONY-PROJECT.COM: ===================================================== (no packages installed) INSTALLED PACKAGES, CHANNEL PEAR.ZFCAMPUS.ORG: ============================================== PACKAGE VERSION STATE ZF 1.10.2 stable INSTALLED PACKAGES, CHANNEL PECL.PHP.NET: ========================================= PACKAGE VERSION STATE PDO 1.0.3 stable PDO_SQLITE 1.0.1 stable inclued 0.1.0 alpha pecl_http 1.6.5 stable sqlite3 0.6 alpha xdebug 2.0.5 stable INSTALLED PACKAGES, CHANNEL PHPCOMMONS.SOURCEFORGE.JP/PEAR: =========================================================== PACKAGE VERSION STATE Commons 1.0.3 stable
@see おまえ達がインストールしているPEAR パッケージはなんなんだぜ?
http://project-p.jp/halt/anubis/blog_show/662
ZendFramework 勉強会 #2
行ってまいりました。
http://events.php.gr.jp/events/show/91
株式会社paperboy&co.様会場&懇親会費提供ありがとうございます!
で発表中、咳ゴホンゴホンしまくっててマジすいません!!!(;´Д`)
私の発表のスライドは以下。