php里面用魔术方法和匿名函数闭包函数动态的给类里面添加方法

Posted 与f

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php里面用魔术方法和匿名函数闭包函数动态的给类里面添加方法相关的知识,希望对你有一定的参考价值。

1.认识  __set  (在给不可访问属性赋值时,__set() 会被调用)

也就是说你再访问一个类里面没有的属性,会出发这个方法

class A{
    private  $aa = \'11\';
    public function __set($name, $value)
    {
        $this->$name = $value;
    }
}
$a = new A();
$a->name = \'name\';
echo $a->name;

2.认识 __set  (在对象中调用一个不可访问方法时,__call() 会被调用。)

class B{
    private $bb = \'22\';
  public function __call($name, $arguments) { echo $name; var_dump($arguments); } } $b = new B(); $b->names();

 

3.动态添加方法

class B{
    private $bb = \'22\';
    public function __set($name, $value)
    {
        $this->$name = $value;
    }
    public function __call($name, $arguments)
    {//注意:没用形参$name
        return call_user_func($this->$name,$arguments);//通过这个把属性的匿名方法加进来 注意:$arguments 是一个数组
    }
}
$b = new B();
$b->names = function(){echo \'this is a fun \';};
$b->names();

//这时候B类里面已经有一个 属性name 指向一个匿名方法
//怎么运行呢? $b->name() 错误因为类里面没有这个方法 ---这个错误可以触发__call()魔术方法
//这时候还不能在 匿名函数 中用B类里面的 属性

4.动态加方法之,让闭包函数也能操作类里面的属性 参考(http://php.net/manual/zh/closure.bindto.php)

class C{
    private $cc = \'33\';
    public function __set($name, $value)
    {
        //$this->$name = $value; //(和上面例子比较  就改动了这个)
        $this->$name = $value->bindTo($this,$this);//复制当前闭包函数,绑定指定的$this作用域对象,这样匿名函数就可以访问类的属性值了
    }
    public function __call($name, $arguments)
    {
        return call_user_func($this->$name,$arguments);
    }
}
$c = new C();
$c->username = function ($strs){
    var_dump($strs);//这里其实是 call_user_func的$arguments传过来的是数组
    $this->cc=4;//可以操作作用于的属性值
    return \'111\';
};
echo $c->username(\'字符串\');

 

一个完整的例子:

/**
 * 给类动态添加新方法
 *
 * @author fantasy
 */
trait DynamicTrait {
    /**
     * 自动调用类中存在的方法
     */
    public function __call($name, $args) {
        if(is_callable($this->$name)){
            return call_user_func($this->$name, $args);
        }else{
            throw new \\RuntimeException("Method {$name} does not exist");
        }
    }
    /**
     * 添加方法
     */
    public function __set($name, $value) {
        $this->$name = is_callable($value)?
            $value->bindTo($this, $this):
            $value;
    }
}
/**
 * 只带属性不带方法动物类
 *
 * @author fantasy
 */
class Animal {
    use DynamicTrait;
    private $dog = \'汪汪队\';
}
$animal = new Animal;
// 往动物类实例中添加一个方法获取实例的私有属性$dog
$animal->getdog = function() {
    return $this->dog;
};
echo $animal->getdog();//输出 汪汪队

 

 

动态给类里面加方法,就是把一个闭包函数通过__set和__call结合call_user_func()等方法,加入进去,

为了让匿名函数或闭包函数可以访问类的属性值,需要结合Closure类的Closure::bindTo (复制当前包对象,绑定到指定this作用域)

 

参考:http://www.cnblogs.com/fps2tao/p/8727248.html

 

以上是关于php里面用魔术方法和匿名函数闭包函数动态的给类里面添加方法的主要内容,如果未能解决你的问题,请参考以下文章

PHP匿名函数和闭包

PHP中的闭包和匿名函数

php的闭包

php匿名函数和闭包函数及use关键字传参及Closure匿名函数类

php值callback类型和匿名函数(闭包)

浅析PHP中的闭包和匿名函数