php动态地将方法附加到类

时间:2016-08-22 09:14:21

标签: php

需要动态地将方法附加到类。

我的代码:

func imageViewTapped(recognizer:UITapGestureRecognizer) {

    guard let imageView = recognizer.view as? UIImageView
      else { return }
    imageView.tintColor = UIColor.orangeColor()

}

问题:为什么<?php class stdClass1 { public function __call($method, $arguments) { return call_user_func_array(Closure::bind($this->$method, $this, get_called_class()), $arguments); } } class stdClass2 { function stdRunMethod() { $obj = new stdClass1(); $obj->test = function() { echo 'a simple function'; }; $obj->test(); $obj2 = new stdClass1(); $obj2->test(); } } $obj = new stdClass2(); $obj->stdRunMethod(); 方法仅针对test类的第一个实例运行?如何为所有新实例附加此方法?

2 个答案:

答案 0 :(得分:2)

改为尝试(demo):

   <?php 

    class stdClass1 extends \stdClass
    {
        private static $addedClosures = array();

        public function __set($name, $value)
        {
            if ($value instanceof \Closure) {
                self::$addedClosures[$name] = $value;
            }
            else {
                parent::__set($name, $value);
            }
        }

        public function __call($method, $arguments)
        {
            if (isset(self::$addedClosures[$method]))
                return call_user_func_array(self::$addedClosures[$method], $arguments);
            return call_user_func_array($method, $arguments);
        }
    }

    class stdClass2 extends \stdClass
    {

        function stdRunMethod()
        {
            $obj = new stdClass1();
            $obj->test = function () {
                print_r('a simple function');
            };
            $obj->test();

            $obj2 = new stdClass1();
            $obj2->test();
        }

    }

答案 1 :(得分:1)

它只运行一次的原因是stdClass1的每个副本都维护着自己的一组变量。在下面的

$obj1 = new stdClass1();
$obj1->a = '1';

$obj2 = new stdClass1();
$obj2->a = '2';

echo $obj1->a;

您将获得值1作为输出。因为在大多数情况下他们保持不同的参考除非您使用static关键字。静态属性在类的所有实例之间共享,应该谨慎使用,但这是您正在考虑的内容。您正在考虑的事情可以像这样做

<?php

class stdClass1 {
    private static $methods = [];

    public function __call($method, $arguments) {
        return call_user_func_array(Closure::bind($this->methods[$method], $this, get_called_class()), $arguments);
    }

    public function __set($name, $value) {
        if (is_callable($value)) {
            $this->methods[$name] = $value;
        } else {
            parent::__set($name, $value);
        }
    }
}

我们在这里使用静态的已定义属性来保存所有动态方法,并且我们正在使用魔术__set属性将方法设置为数组。

话虽如此,动态地将方法加载到对象中是不好的。不要这样做