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好了吧…

时间: 2024-10-07 04:18:48

php中怎么理解Closure的bind和bindTo的相关文章

PHP Closure类Bind与BindTo方法

Closure类为闭包类,PHP中闭包都是Closure的实例: 1 $func = function(){}; 2 var_dump($func instanceof Closure); 输出 bool(true) Closure有两个函数将闭包函数绑定到对象上去, 静态方法Bind public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )

javascript中apply、call和bind的区别,容量理解,值得转!

a)  javascript中apply.call和bind的区别:http://www.cnblogs.com/cosiray/p/4512969.html b)  深入浅出 妙用Javascript中apply.call.bind   http://www.admin10000.com/document/6711.html ====================================================== 在JS中,这三者都是用来改变函数的this对象的指向的,他们

js中call、apply、bind的用法

今天看博客时,看到了这样的一段js代码: var bind = Function.prototype.call.bind(Function.prototype.bind); 我想突然看到这样的一段代码,即使js能力再强的人,可能也需要花点时间去理解.像我这样的菜鸟就更不用说了.其实,原文已经对这端代码做出了解释,但我还是想用我的想法去解释这段代码. 上面那段代码涉及到了call.bind,所以我想先区别一下call.apply.bind的用法.这三个方法的用法非常相似,将函数绑定到上下文中,即用

在实践中深入理解VMware虚拟机的上网模式:NAT模式

0.说明 本篇博文为<在实践中深入理解VMware虚拟机的上网模式>系列的其中一篇:NAT模式. VMware虚拟机在我们学习过程中必不可少,不管是安装Linux操作系统来进行学习.搭建各种网络服务,拟或者是用来做集群测试.云计算平台OpenStack等的搭建,可以说,VMware虚拟机为我们带来了极大的便利,最直观的好处就是,我们可以节省很多用来购买各种设备的资金,同时也可以达到了学习各种技术的目的. 然而只要涉及到通过宿主机与VMware虚拟机中的操作系统进行通信,或者是VMware虚拟机

ibatis 开发中的经验 (一)ibatis 和hibernate 在开发中的理解

这个项目的底层是用ibatis框架完毕,这几天也是都在用这个框架写代码,也有了一些简单的理解,把项目拿过来后基本的配置都已经配置好了,比方一些事务.日志控制等,在开发中主要用到的是写SQL语句以及熟悉ibatis xml文件都提供的一些标签,这些标签大部分是用来处理推断.逻辑,使得sql能够动态组装变的更灵活. 在写代码的工作量上ibatis要比hibernate高一些,在你写了服务层后还须要些dao层,dao层实现,然后这些在hibernate中不须要自己写,仅仅写到服务层就能够调用hiber

博客专题计划:《在实践中深入理解常见网络协议》

距离学习CCIE的课程已经有近一年的时间,虽然这一年来已经丢下了挺多关于路由交换技术的知识,不过随着这一年时间以来通过对Linux和Python的学习研究和学校相关课程的学习,对于TCP/IP的理解是越来越清晰,至少可以慢慢形成自己的想法,于是想借此机会,整理一下过去的思绪,撰写<在实践中深入理解常见网络协议>的博客专题. 写博客已有近一年的时间,慢慢地也形成了自己写博文的一种风格,有一大部分也获得了许多网友的肯定,包括51cto网友,或者通过其它方式浏览我写博文的其它门户网站的网友,在此表示

ibatis 和hibernate 在开发中的理解

这个项目的底层是用ibatis框架完成,这几天也是都在用这个框架写代码,也有了一些简单的理解,把项目拿过来后主要的配置都已经配置好了,比如一些事务.日志控制等,在开发中主要用到的是写SQL语句以及熟悉ibatis xml文件都提供的一些标签,这些标签大部分是用来处理判断.逻辑,使得sql可以动态组装变的更灵活. 在写代码的工作量上ibatis要比hibernate高一些,在你写了服务层后还需要些dao层,dao层实现,然后这些在hibernate中不需要自己写,只写到服务层就可以调用hibern

深入浅出妙用 Javascript 中 apply、call、bind

原文地址:深入浅出妙用 Javascript 中 apply.call.bind apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念. 先来一个栗子:eg1: function fruits() {} fruits.prototype = {

解析JavaScript中apply和call以及bind

函数调用方法 在谈论JavaScript中apply.call和bind这三兄弟之前,我想先说下,函数的调用方式有哪些: 作为函数 作为方法 作为构造函数 通过它们的call()和apply()方法间接调用 前面的三种调用方法,我们都知道且不在这篇文章的讨论范围内,就不说了. 下面我们来说说这第四种调用方法 通过call()和apply()间接调用 其实,我们可以将这两个函数看做是某个对象的方法,通过调用方法的方式来间接调用函数: function f(){} f.call(o); f.appl