官方文档:Closure 类

原文:php中怎么理解Closure的bind和bindTo

bind是bindTo的静态版本,因此只说bind吧。(还不是太了解为什么要弄出两个版本)

官方文档: 复制一个闭包,绑定指定的$this对象和类作用域。

其实后半句表述很不清楚。 我的理解: 把一个闭包转换为某个类的方法(只是这个方法不需要通过对象调用), 这样闭包中的$this、static、self就转换成了对应的对象或类。

因为有几种情况:

1、只绑定$this对象.
2、只绑定类作用域.
3、同时绑定$this对象和类作用域.(文档的说法)
4、都不绑定.(这样一来只是纯粹的复制, 文档说法是使用cloning代替bind或bindTo)

下面详细讲解这几种情况:

1、只绑定$this对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$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();

  

1
My name is php, I’m 100 years old.

注意: 在上面的这个例子中,是不可以在$closure中使用static的,如果需要使用static,通过第三个参数传入带命名空间的类名。

2、只绑定类作用域.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$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();

  

1
My name is php, I’m 100 years old.

注意: 在上面的例子中,是不可以在$closure中使用$this的,因为我们的bind只绑定了类名,也就是static,如果需要使用$this,新建一个对象作为bind的第二个参数传入。

3、同时绑定$this对象和类作用域.(文档的说法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$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();

  

1
My name is php, I’m 100 years old. Sex: female.

在这个例子中可以在$closure中同时使用$this和static

4、都不绑定.(这样一来只是纯粹的复制, 文档说法是使用cloning代替bind或bindTo)

1
2
3
4
5
6
7
8
$closure function () {
    echo "bind nothing.\n";
};
 
//与$bound_closure = clone $closure;的效果一样
$bound_closure = Closure::bind($closure, null);
 
$bound_closure();

  

1
bind nothing.

这个就用clone好了吧…

php Closure::bind的用法(转)的更多相关文章

  1. php中Closure::bind用法(手册记录)

    手册中 Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域. 具体参数可以看手册,这里记录下这个方法的实际用处. <?php trait MetaTrait { p ...

  2. php Closure::bind的参数说明

    publicstatic Closure Closure::bind ( Closure $closure , object$newthis [, mixed$newscope = 'static' ...

  3. js中call、apply、bind的用法

    原文链接:http://www.cnblogs.com/xljzlw/p/3775162.html var zlw = { name: "zlw", sayHello: funct ...

  4. js中bind的用法,及与call和apply的区别

    call和apply的使用和区别不再做阐述,可以参考我的另一篇随笔<JavaScript中call和apply方法的使用>(https://www.cnblogs.com/lcr-smg/ ...

  5. call、apply、bind的用法

    数组追加 //用apply拼接 var arr1=[12,'name:foo',2048]; var arr2=['Joe','Hello']; Array.prototype.push.apply( ...

  6. C++标准 bind函数用法与C#简单实现

    在看C++标准程序库书中,看到bind1st,bind2nd及bind的用法,当时就有一种熟悉感,仔细想了下,是F#里提到的柯里化.下面是维基百科的解释:在计算机科学中,柯里化(英语:Currying ...

  7. JavaScript学习(2)call&apply&bind&eval用法

    javascript学习(2)call&apply&bind&eval用法 在javascript中存在这样几种特别有用的函数,能方便我们实现各种奇技淫巧.其中,call.bi ...

  8. javascript中call()、apply()、bind()的用法理解

    一.bind的用法 第一个:obj.showInfo('arg','arg_18');中传的2个参数通过showInfo方法改变的是obj下中的name和age 第二个:obj.showInfo.bi ...

  9. call,apply,bind的用法

    关于call,apply,bind这三个函数的用法,是学习javascript这门语言无法越过的知识点.下边我就来好好总结一下它们三者各自的用法,及常见的应用场景. 首先看call这个函数,可以理解成 ...

随机推荐

  1. 00-python概述。

    人生苦短,我用Python. -发展历史: - 1989年,由Guido van Rossum开始开发, - 1991年,发布第一个公开发行版,第一个Python编译器(同时也是解释器)诞生. - 2 ...

  2. day 52 Django 的中间件加载顺序

    前情提要: django的中间键的作用是进行加载 可以通过中间键进行辅助操作 1.中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局 ...

  3. 【NOIP2013】 火柴排队 贪心+splay

    这题为啥我写得这么复杂. 首先我们不难发现,我们将序列$a$和序列$b$排序,考虑两序列内无相同元素,那么最小值显然为$\sum_{i=1}^{n} (a_i-b_i)^2$. 下面考虑做法 首先,我 ...

  4. DIV+CSS 按比例等分

    div { display: inline-block; /* 如需支持IE8以下版本,用浮动来做 */ width: calc(100% / 3.09); /* 此处运用了一个css3的表达式,将d ...

  5. Hive Cli相关操作

    landen@Master:~/UntarFile/hive-0.10.0$ bin/hive --database 'stuchoosecourse' -e 'select * from hidde ...

  6. Windows10下简单搭建zookeeper

    转载请注明源出处:http://www.cnblogs.com/lighten/p/6798669.html 1 简介 zookeeper是Apache的一个开源项目,致力于开发和维护一个开源的服务器 ...

  7. slq 修改表结构

    1.增加列: alter table tableName add columnName varchar(30) 2.修改列类型: alter table tableName alter column  ...

  8. SearchView去掉下划线

    SearchView calSearchView = (SearchView) findViewById(R.id.sv_search_text); if (calSearchView != null ...

  9. java学习-MD5消息摘要算法

    md5 属于hash算法一类,是不可逆的消息摘要算法.与对称加密和非对称加密算法不一样,不需要加密密钥. 注意: md5不是加密算法,只是将数据进行散列计算后生成一个唯一值的算法,没有加密密钥也没有解 ...

  10. python:rs, ws, es = select.select(inputs, [], []) --报错error 10022

    昨晚折腾的1个多钟,直到3点多才睡,感觉自己也是热爱代码了,敲3个多钟一点也不累(其实是为了凌晨6点起来抢票回家了^_^) 练习python中select进行异步通信-防止socket.recv方法阻 ...