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里面用魔术方法和匿名函数闭包函数动态的给类里面添加方法的更多相关文章

  1. 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数

    [源码下载] 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数 作者:webabcd 介绍速战速决 之 PHP 函数基础 函数参数 函 ...

  2. python 函数--闭包函数

    一.闭包函数: 在一个外函数中定义一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用. 二.实例: def outer(a): #外函数 b = 10 #临时变量 def i ...

  3. PHP函数(六)-匿名函数(闭包函数)

    匿名函数能够临时创建一个没有名称的函数,常用作回调函数参数的值 <?php $test = function($a){ echo "Hello,".$a; }; $test( ...

  4. python 内嵌函数, 闭包, 函数装饰器

    一.  函数内嵌 闭包 在python中,函数可以作为返回值, 可以给变量赋值. 在python中, 内置函数必须被显示的调用, 否则不会执行. #!/usr/bin/env python #-*- ...

  5. ios开发runtime学习三:动态添加方法(实际应用少,面试)

    #import "ViewController.h" #import "Person.h" /* 1: Runtime(动态添加方法):OC都是懒加载机制,只要 ...

  6. 如何为jquery添加方法

    以下内容引自一位网友的帖子: jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery ...

  7. 快速上手Runtime(四)之动态添加方法

    如果一个类方法非常多,加载类到内存的时候也比较耗费资源,可以使用动态给某个类,添加方法解决.做到优化内存,节省资源的效果. // // Person.m // ResolveInstanceMetho ...

  8. JavaScript匿名自执行函数~function(){}

    原博客:https://blog.csdn.net/yaojxing/article/details/72784774 1.匿名函数的常见场景 js中的匿名函数是一种很常见的函数类型,比较常见的场景: ...

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

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

随机推荐

  1. Unity防破解 —— 加密Dll与Key保护

        在阅读这篇文章之前,我在处理mono加密问题时,也是参考了雨凇的文章,所以建议先看一下雨凇写的关于加密Dll的文章: 1.Unity3D研究院之Android加密DLL与破解DLL .SO 2 ...

  2. springMVC笔记:jsp页面获取后台数据记录列表

    1.读取数据库中的记录List<HashMap<String,String>> attributes; 2.Controller构造Model如下: @RequestMappi ...

  3. 【NOI2016】优秀的拆分

    题目描述 如果一个字符串可以被拆分为 $AABB$ 的形式,其中 $A$ 和 $B$ 是任意非空字符串,则我们称该字符串的这种拆分是优秀的. 例如,对于字符串 aabaabaa,如果令 $A = \m ...

  4. POJ 3368 Frequent values(线段树区间合并)

    [题目链接] http://poj.org/problem?id=3368 [题目大意] 有一个有序序列,要求区间查询出现次数最多的数 [题解] 维护每个区间左端点和右端点,以及左右的长度,还有区间的 ...

  5. Linux Whois命令安装与使用

    大家都知道查看域名的详细信息,都是跑去whois服务器去查询,如 http://whois.chinaz.com 其实在Linux下直接有一个whois的命令,不过需要安装jwhois才可以,以Cen ...

  6. iOS UI、Xcode、调试、代码等常见问题总汇(持续更新中)

    以前比较懒,遇到问题解决了就完事了,有些问题再次遇到时忘记了当初是怎么解决的,又要查各种资料来解决.好记忆不如烂笔头,不管简单还是复杂都记一下吧,所以决定写一篇常见问题总结,方便以后查阅.现在有点忙, ...

  7. 手把手教你使用FineUI+动软代码生成器开发一个b/s结构的取送货管理信息系统(附源码)之开篇

    一 本系列随笔概览及产生的背景 近阶段接到一些b/s类型的软件项目,但是团队成员之前大部分没有这方面的开发经验,于是自己选择了一套目前网上比较容易上手的开发框架(FineUI),计划录制一套视频讲座, ...

  8. ios 字体类型设置 倾斜加粗等

    后面加-Bold就是加粗 加-Oblique就是倾斜等 还有不懂请看http://iosfonts.com/ iPhone 5.0 iPad 5.0 Font Families: 58 Font Fa ...

  9. 控制面板里找不到“应用程序server”这个项目,Windows XP中金蝶安装时无“应用程序server”的解决的方法

    要注意先安装IIS,再安装VS2008. 我们会常常在控制面板里找不到"应用程序server"这个项目.我们须要依照以下的步骤来操作就会Ok. 1.下载IIS6,放置到D盘根文件夹 ...

  10. boost/config.hpp文件详解

    简要概述 今天突发奇想想看一下boost/config.hpp的内部实现,以及他有哪些功能. 这个头文件都有一个类似的结构,先包含一个头文件,假设为头文件1,然后包含这个头文 件中定义的宏.对于头文件 ...