LoginSignup
25
25

More than 5 years have passed since last update.

PHPで動的にメソッドを追加する方法

Last updated at Posted at 2014-05-17

プラグイン機構を実装したいことがあって調べた。

基本的なやりかたとしては、

  • 「メソッド名」と「コールバック」をひもづける配列を用意しておく
  • __call()の中で、call_user_func_array()で追加したメソッドを実行する
  • Closure::bindTo()で$thisをバインドする(コールバックから他のメソッドを呼び出すため)

という感じ。

以下のようになる。

test1.php
class Object
{
    static private $_methods = array();

    static public function addMethod($name, Closure $cb)
    {
        self::$_methods[$name] = $cb;
    }

    public function __call($name, array $args)
    {
        $func = self::$_methods[$name];
        return call_user_func_array($func->bindTo($this, get_class($this)), $args);
    }

    public function add($a, $b)
    {
        return $a + $b;
    }
}

foreach (array(10,100,1000) as $base) {
    Object::addMethod('add'.$base, function($number) use ($base) {
        return $this->add($number, $base);
    });
}

$object = new Object();

echo $object->add10(1)."\n";
echo $object->add100(1)."\n";
echo $object->add1000(1)."\n";

Closure::bindTo()は、5.4からの機能なので、
もし5.3で同じように行うためには、
コールバックの引数の最初に$thisを追加するように対応する。

test2.php
<?php

class Object
{
    static private $_methods = array();

    static public function addMethod($name, Closure $cb)
    {
        self::$_methods[$name] = $cb;
    }

    public function __call($name, array $args)
    {
        array_unshift($args, $this);
        return call_user_func_array(self::$_methods[$name], $args);
    }

    public function add($a, $b)
    {
        return $a + $b;
    }
}

foreach (array(10,100,1000) as $base) {
    Object::addMethod('add'.$base, function($self, $number) use ($base) {
        return $self->add($number, $base);
    });
}

$object = new Object();

echo $object->add10(1)."\n";
echo $object->add100(1)."\n";
echo $object->add1000(1)."\n";

Closure::bindTo()と違うのは、
privateのメソッドが呼び出せないところ。

参考

PHP 5.3でクラスにメソッドを動的に追加する
http://lab.tricorn.co.jp/toda/4082

PHPでメソッドを動的に追加する方法
http://qiita.com/suin/items/99c95c6b2182b54d9405

25
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
25