2010年10月22日金曜日

PHP5.3でJavaScriptのようにメソードを上書きする(ように見せる)方法

JavaScriptをしばらくいじくった後、PHPに戻ると、一旦メソードを上書きでいないのにいらいらします。継承するか、インスタンス化して別クラスに委譲して別メソードをかぶせる、とかぐらいしか出来ません。

で、PHP5.3のクロージャー(無名関数)と__callを使って、
メソードを上書きできる、ように見せることが出来ました。



◆まぁ、こんな感じ。

echo 'test closure' . '
';

class test
{
 var $name;
 // +------------------------------------------+
 function __construct() {
  $self = $this;
  $this->name = 'my test';
  $this->getName = function() use( $self ) {
   echo $self->name . '<br />';
  };
 }
 // +------------------------------------------+
 public function __call( $name, $args ) {
  if( is_callable( $this->$name ) ) {
   call_user_func_array( $this->$name, $args );
  }
 }
 // +------------------------------------------+
}

$t = new test();
$t->getName();   // works.

$t->name = 'new test';
$t->getName();   // works fine.

// kind of overwriting method... 
$t->getName = function() use( $t ) {
 echo 'new: ' . $t->name . '
';
};
$t->getName();   // works great!


自宅のローカルPCでは動いてます。出力は、

test closure
my test
new test
new: new test

となって、ほぼ想定どおりの動きです。
クロージャーを作るときにuseを使って、クラス自身を受け渡すこと、クラス内の変数にクロージャーを渡して、__callでオーバーライドするのがポイント。

$selfとかjavaScriptっぽくて、妙ですね。

実際使うかといわれると・・・
う~ん、

0 件のコメント: