ArrayObjectで遊んでみる
先週、「ArrayObjectってどうなのかおしえてー」とオフラインメッセージが残っていて、今週そんなのを某氏とメッセで話してたんですが、
<?php class A extends ArrayObject { public function __call($fname, $args) { if (function_exists("array_$fname")) { $arr = call_user_func_array("array_$fname", array((array)$this) + $args); if (is_array($arr)) { return new A($arr); } else { return $arr; } } } public function ksort() { parent::ksort(); return $this; } public function append($val) { parent::append($val); return $this; } } ?>
なんて、クラスをつくって、
<?php // ksort $obj = new A( array('e' => 32, 'a' => 4, 'b' => -3, 's' => 20) ); var_dump($obj->ksort()); // ksortしてキーを取り出す $obj = new A( array('e' => 32, 'a' => 4, 'b' => -3, 's' => 20) ); var_dump($obj->ksort()->keys()); // sortしたキーの末尾をpop $obj = new A( array('e' => 32, 'a' => 4, 'b' => -3, 's' => 20) ); var_dump($obj->ksort()->keys()->pop()); ?>
とかやって、
object(A)#1 (4) { ["a"]=> int(4) ["b"]=> int(-3) ["e"]=> int(32) ["s"]=> int(20) } object(A)#1 (4) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "e" [3]=> string(1) "s" } string(1) "s"
と、結果を得る。$obj->ksort()->keys()->pop()ってつなげて書けると、PHPぽくなくていいねー、と。
きっと、kuせんせいが、これでなんかかっこいいのを書いてくれるはず
メモ
- ksort()などのメソッドがArrayObjectに追加されたのは、PHP5.2くらいから?みたい。5.1では存在していなかった。
- SPLのリファレンスはPHP: Manual Quick Referenceを参照
- ちと気になるのが、ArrayIterator。イテレータのくせにsort系メソッドがあるのか
- ArrayObjectは、メソッドの戻り値を特に返さないので、継承して、ksort()などについて、
return $this
して返す。他にもメソッドがあるが、とりあえずサンプルコードなので割愛。 __call()
マジックメソッドでは、array_keys()
といったarray_
で始まる関数を簡易的に呼んでいます。そして、配列のときはArrayObjectを生成して返却、その他はそのまま値を返却しています。
こまったこと
メモリリークのメッセージでた orz (PHP v.5.2.3 cliのdebug build)
[Wed Jun 6 01:07:19 2007] Script: 'test.php' /tmp/php/php-5.2.3/Zend/zend_execute_API.c(985) : Freeing 0xB790D1D4 (16 bytes), script=test.php Last leak repeated 2 times
変な使い方だからか、と思ったら、
$obj = new ArrayObject( array('e' => 32, 'a' => 4, 'b' => -3, 's' => 20) ); $obj->ksort();
しても出てくるから、まぁ、そういうものなのかもなぁ。