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){//注意:没用形参$namereturn 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里面用魔术方法和匿名函数闭包函数动态的给类里面添加方法相关推荐

  1. Java/java程序设计多态参数:练手小题:父类员工类含有普通员工和经理两个子类,普通员工有work方法,经理有特有属性年终奖,和manage方法现要求在主文件中设计能调用所有类的年薪方法和工作方法

    多态参数:练手小题 1. 前言: 2. 分析需求: 2.1 主类Employee分析 2.1.1 主类Employee代码片段 2.2 子类work普通员工分析 2.2.1 子类work普通员工代码片 ...

  2. Java运行时动态加载类之ClassLoader方法带参数

    和该文环境一样http://blog.csdn.net/fjssharpsword/article/details/64922083 不同的是,在load出的class调用具体方法时传递参数. 1.U ...

  3. php的匿名函数和闭包函数

    php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因 ...

  4. 好好学python·函数进阶(递归函数,回调函数,闭包函数,匿名函数,迭代器)

    函数进阶 递归函数 回调函数 闭包函数 特点 匿名函数 lambda 表达式 迭代器 iter() next() 迭代器的取值方案 迭代器取值特点,取一个少一个,直到都取完,最后再获取就会报错 检测迭 ...

  5. py函数式编程(高阶函数map/reduce/filter/sorted、闭包函数/返回函数、匿名函数lamber、@装饰器decorator、偏函数functool.partial())

    #py函数式编程.py #高阶函数map/reduce/filter/sorted.闭包函数/返回函数.匿名函数lamber.@装饰器decorator.偏函数functool.partial()# ...

  6. js中的匿名函数和匿名自执行函数

    1.匿名函数的常见场景 js中的匿名函数是一种很常见的函数类型,比较常见的场景: <input type="button" value="点击" id=& ...

  7. 【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 使用 MetaClass 进行方法拦截 | 对象上拦截方法 | 类上拦截方法 )

    文章目录 一.使用 MetaClass 进行方法拦截 1.使用 MetaClass 在单个对象上进行方法拦截 2.使用 MetaClass 在类上进行方法拦截 二.完整代码示例 1.对象方法拦截 2. ...

  8. 向现有对象实例添加方法

    我读过,可以在Python中向现有对象(即不在类定义中)添加方法. 我了解这样做并不总是一件好事. 但是怎么可能呢? #1楼 至少有两种方法可以将方法附加到没有types.MethodType的实例上 ...

  9. python高阶函数闭包装饰器_Python自学从入门到就业之高阶函数、嵌套函数、闭包、装饰器...

    高阶函数 在Python中,函数其实也是一种数据类型. def test(): return 'hello world' print(type(test)) # 函数对应的数据类型是 function ...

最新文章

  1. 线段树 ---- 2021牛客多校第一场 J Journey among Railway Stations [线段树维护区间可行性判断]
  2. jquery.cookie.js 使用方法
  3. 思科模拟器叫什么_扫盲!通过型号快速识别思科路由器,交换机,服务器等设备...
  4. 面试题 10.01. 合并排序的数组
  5. html5系列:notification api升级——从webkitNotifications到Notification
  6. Bootstrap响应式布局之 col-xs col-sm col-md
  7. H5网页去除苹果手机底部白边
  8. [乡土民间故事_徐苟三传奇]第廿三回_吃蒸肉财主受捉弄
  9. 名片管理系统python详解_取名字大全_免费男孩女孩起名字
  10. 二次元壁纸 | 心情烦躁?换上喜欢的手机壁纸
  11. Vue 运行提示“没有注册类”的解决办法
  12. 使用html 语言建立一个简单的网页,如何用记事本建立简单的网页(1).doc
  13. 有一个棋盘,有64个方格,在第一个方格里面放1粒芝麻重量为0.00001,第二个里面放2粒,第三个里面放4,第四个8 ,以此类推,棋盘上放的所有芝麻的重量?
  14. 邮电通信业宣传片制作技巧
  15. 忆阻器交叉开关阵列中的长短期记忆(LSTM)神经网络
  16. 5 种全局 ID 生成方式、优缺点及改进方案
  17. 扫雷游戏软件测试,软件测试-扫雷游戏
  18. python 效率 算法_python – 算法(prob solve)实现最快的运行时间
  19. 前端大事记之几件大事
  20. 聚类分析matlab

热门文章

  1. 了解一下Bootstrap
  2. python代码怎么运行_使用Joblib并行运行Python代码
  3. 2018麦考林杂志计算机科学,最新出炉|2018年麦考林杂志加拿大大学排名!
  4. mysql 递归_mysql5.7递归使用
  5. 【第1篇】Python爬虫实战-王者荣耀高清壁纸下载
  6. java switch中标签重复_java程序 怎样把id相同的记录挑出来,分别存到不同的文件中,除了switch case,数据量很大,id种类很多。...
  7. T-SQL(SQL Sever) 简单语句实例
  8. html演示 用鼠标画记号,html怎么用鼠标画出一条直线,鼠标移动时候要能看到线条...
  9. java的数据连接_java中连接各种数据的方法
  10. android自定义键盘遮挡,Android软键盘遮挡的四种完美解决方案