おぎろぐはてブロ

なんだかんだエンジニアになって10年以上

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では存在していなかった。
  • 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();

しても出てくるから、まぁ、そういうものなのかもなぁ。