php中怎么理解Closure的bind和bindTo
bind是bindTo的静态版本,因此只说bind吧。(还不是太了解为什么要弄出两个版本)
官方文档: 复制一个闭包,绑定指定的$this对象和类作用域。
其实后半句表述很不清楚。 我的理解: 把一个闭包转换为某个类的方法(只是这个方法不需要通过对象调用), 这样闭包中的$this、static、self就转换成了对应的对象或类。
因为有几种情况:
1、只绑定$this对象.
2、只绑定类作用域.
3、同时绑定$this对象和类作用域.(文档的说法)
4、都不绑定.(这样一来只是纯粹的复制, 文档说法是使用cloning代替bind或bindTo)
下面详细讲解这几种情况:
1、只绑定$this对象
$closure = function ($name, $age) {
$this->name = $name;
$this->age = $age;
};
class Person {
public $name;
public $age;
public function say() {
echo "My name is {$this->name}, I'm {$this->age} years old.\n";
}
}
$person = new Person();
//把$closure中的$this绑定为$person
//这样在$bound_closure中设置name和age的时候实际上是设置$person的name和age
//也就是绑定了指定的$this对象($person)
$bound_closure = Closure::bind($closure, $person);
$bound_closure('php', 100);
$person->say();
My name is php, I’m 100 years old.
注意: 在上面的这个例子中,是不可以在$closure中使用static的,如果需要使用static,通过第三个参数传入带命名空间的类名。
2、只绑定类作用域.
$closure = function ($name, $age) {
static::$name = $name;
static::$age = $age;
};
class Person {
static $name;
static $age;
public static function say()
{
echo "My name is " . static::$name . ", I'm " . static::$age. " years old.\n";
}
}
//把$closure中的static绑定为Person类
//这样在$bound_closure中设置name和age的时候实际上是设置Person的name和age
//也就是绑定了指定的static(Person)
$bound_closure = Closure::bind($closure, null, Person::class);
$bound_closure('php', 100);
Person::say();
My name is php, I’m 100 years old.
注意: 在上面的例子中,是不可以在$closure中使用$this的,因为我们的bind只绑定了类名,也就是static,如果需要使用$this,新建一个对象作为bind的第二个参数传入。
3、同时绑定$this对象和类作用域.(文档的说法)
$closure = function ($name, $age, $sex) {
$this->name = $name;
$this->age = $age;
static::$sex = $sex;
};
class Person {
public $name;
public $age;
static $sex;
public function say()
{
echo "My name is {$this->name}, I'm {$this->age} years old.\n";
echo "Sex: " . static::$sex . ".\n";
}
}
$person = new Person();
//把$closure中的static绑定为Person类, $this绑定为$person对象
$bound_closure = Closure::bind($closure, $person, Person::class);
$bound_closure('php', 100, 'female');
$person->say();
My name is php, I’m 100 years old. Sex: female.
在这个例子中可以在$closure中同时使用$this和static
4、都不绑定.(这样一来只是纯粹的复制, 文档说法是使用cloning代替bind或bindTo)
$closure = function () {
echo "bind nothing.\n";
};
//与$bound_closure = clone $closure;的效果一样
$bound_closure = Closure::bind($closure, null);
$bound_closure();
bind nothing.
这个就用clone好了吧…
php中怎么理解Closure的bind和bindTo的更多相关文章
- PHP Closure类Bind与BindTo方法
Closure类为闭包类,PHP中闭包都是Closure的实例: 1 $func = function(){}; 2 var_dump($func instanceof Closure); 输出 bo ...
- javascript中apply、call和bind的区别,容量理解,值得转!
a) javascript中apply.call和bind的区别:http://www.cnblogs.com/cosiray/p/4512969.html b) 深入浅出 妙用Javascrip ...
- (转)深入浅出 妙用Javascript中apply、call、bind
原文连接 深入浅出 妙用Javascript中apply.call.bind 网上文章虽多,大多复制粘贴,且晦涩难懂,我希望能够通过这篇文章,能够清晰的提升对apply.call.bind的认识,并且 ...
- 在Javascript中闭包(Closure)
在Javascript中闭包(Closure) 什么是闭包 “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. ...
- js中call、apply、bind的用法
原文链接:http://www.cnblogs.com/xljzlw/p/3775162.html var zlw = { name: "zlw", sayHello: funct ...
- 解析JavaScript中apply和call以及bind
函数调用方法 在谈论JavaScript中apply.call和bind这三兄弟之前,我想先说下,函数的调用方式有哪些: 作为函数 作为方法 作为构造函数 通过它们的call()和apply()方法间 ...
- session与cookie的区别以及HTML5中WebStorage理解
一.session与cookie的区别 二.HTML5中WebStorage理解 WebStorage的目的是克服由cookie所带来的一些限制,当数据需要被严格控制在客户端时,不需要持续的将数据发回 ...
- 关于java中Stream理解
关于java中Stream理解 Stream是什么 Stream:Java 8新增的接口,Stream可以认为是一个高级版本的Iterator.它代表着数据流,流中的数据元素的数量可以是有限的, 也可 ...
- js中call、apply和bind的区别
在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢.在说区别之前还是先总结一下三者的相似之处:1.都是用来改变函数的this对象的指向的.2.第一个参数都是this要指向的对 ...
随机推荐
- php prepare
详见 https://stackoverflow.com/questions/134099/are-pdo-prepared-statements-sufficient-to-prevent-sql- ...
- java学习笔记_接口
接口:interface(关键字) public interface USB {} 1. 接口中都是抽象方法,方法前面的可见度(public.private)和抽象关键字(abstract)可以不写. ...
- win10 安装 mysql 5.7
win10 安装 mysql 5.7 1.在mysql 官网下载mysql 5.7 的手动安装包 mysql--winx64.zip 2. 解压到mysql 目录的文件夹下面 D:\moudle\my ...
- Oracle数据库学习(四):学习中的遇到的问题
一.xhost图形化界面安装问题 问题1:运行xhost +命令,出现命令没有找到错误 原因:Linux系统没有安装xhost图形化包. 解决办法:安装xhost图形化包,命令如下: yum what ...
- 对 ArrayList 进行分页.
/** * 测试分页 */ @Test public void testPage() { int bulkSize = 2; List<Integer> dataList = new Ar ...
- 基于Anaconda 安装 geatpy 和 tensorflow
装了好久的第三方包终于成功了,暴风哭泣!!!总结一下 分两部分说: 一. 首先是在本地电脑windows系统下装: 首先安利一下这个包括各种 Genetic and Evolutionary Algo ...
- 思科网络设备配置AAA认证
思科网络设备配置AAA认证登陆,登陆认证后直接进入#特权模式,下面以Cisco 3750G-24TS-S为例,其他设备配置完全是一样的,进入config terminal后命令如下: 前面是加2个不同 ...
- SpringMVC初写(五)拦截器
在系统开发过程中,拦截器的使用可以使我们实现一些需求.如:登录认证,权限管理等,拦截器的工作核心就是将一些工作流程进行统一处理 拦截器和过滤器的区别: 过滤器过滤的是请求路径,拦截器拦截的各层方法的映 ...
- suse-Linux下安装Oracle11g服务器
系统要求 Linux安装Oracle系统要求 系统要求 说明 内存 必须高于1G的物理内存 交换空间 一般为内存的2倍,例如:1G的内存可以设置swap 分区为3G大小 硬盘 5G以上 2.修改操作系 ...
- linux安装使用xdebug
我还是来给大家一个正确的配方,每个人的php版本不一样 所以下载的xdebug应该是不一样的 1,https://xdebug.org/wizard.php 进入这个网页 把自己phpinfo的信 ...