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‘ ] )

动态方法BindTo

public Closure Closure::bindTo ( object $newthis [, mixed $newscope = ‘static‘ ] )

静态闭包不能有绑定的对象($newthis 参数的值应该设为 NULL )

此时Closure不可以使用$this。

 1     class Father
 2     {
 3         public $pu = "public variable";
 4
 5         public static $spu = ‘public static‘;
 6     }
 7
 8     class Son extends Father
 9     {
10
11     }
12
13     class Other
14     {
15
16     }
17
18     $son = new Son();
19     $func = function(){
20         echo self::$spu;
21     };
22
23     ($func -> bindTo(null, ‘Son‘))();

静态闭包中不可以调用$this,否则会保持。就像类的静态方法不可以调用$this一样

1     $son = new Son();
2     $func = function(){
3         echo $this -> $pu;
4     };
5
6     ($func -> bindTo(null, ‘Son‘))();
7 报错:
8 Fatal error: Uncaught Error: Using $this when not in object context in D:\laravel\test.php:21
9 Stack trace:

类作用域:

当闭包绑定到对象上时,或者绑定到null成为静态对象,可以通过返回的闭包对象来调用对象的方法,同时可以设定第三个参数$newscope来设定对象中

属性或方法对于闭包的访问可见性。闭包的访问可见性和$newscope类的成员函数是相同的。

 1     class Father
 2     {
 3         protected $pu = "public variable";
 4
 5         protected static $spu = ‘public static‘;
 6     }
 7
 8     class Son extends Father
 9     {
10
11     }
12         //Son中的方法可以正常访问Father类中的protected属性
13
14     class Other
15     {
16
17     }
18         //Other中的方法无法访问Father类中的protected属性

测试:

 1     $son = new Son();
 2
 3     $func = function(){
 4         echo $this -> pu;
 5     };
 6
 7     (Closure::bind($func, $son, ‘Son‘))();
 8     输出 public variable
 9     (Closure::bind($func, $son, ‘Other‘))();
10     报错 Fatal error: Uncaught Error: Cannot access protected property Son::$pu
匿名函数都是Closure的实例所以可以调用 bindTo 方法。1     bindTo方法
2         ($func -> bindTo($son, ‘Son‘))();
3     ($func -> bindTo($son, ‘Other‘))();    

$newscope默认为‘Static‘表示不改变,还是之前的作用域。

    class Grand
    {
        protected $Grandvar = ‘this is grand‘;
    }

    class Father extends Grand
    {
        protected $Fathervar = "this is  Father";
    }

    class Mother extends Grand
    {
        protected $Mothervar = ‘this is Mother‘;
    }

    class Son extends Father
    {
        protected $Sonvar = ‘this is son‘;
    }

    $son = new Son();
    $mon = new Mother();

    $func = function(){
        echo $this -> Grandvar;
    };

        绑定访问作用域为‘Son‘的作用域,之后使用之前的默认作用域,
        所以可以访问Grandvar
    $newFunc = Closure::bind($func, $son, ‘Son‘);
    $newFunc = Closure::bind($newFunc, $mon);
    $newFunc();

        未绑定访问作用域,默认没有权限
    $newFunc = Closure::bind($func, $mon);
    $newFunc();

http://php.net/manual/zh/class.closure.php

时间: 2024-07-29 06:57:12

PHP Closure类Bind与BindTo方法的相关文章

php中怎么理解Closure的bind和bindTo

bind是bindTo的静态版本,因此只说bind吧.(还不是太了解为什么要弄出两个版本) 官方文档: 复制一个闭包,绑定指定的$this对象和类作用域. 其实后半句表述很不清楚. 我的理解: 把一个闭包转换为某个类的方法(只是这个方法不需要通过对象调用), 这样闭包中的$this.static.self就转换成了对应的对象或类. 因为有几种情况: 1.只绑定$this对象.2.只绑定类作用域.3.同时绑定$this对象和类作用域.(文档的说法)4.都不绑定.(这样一来只是纯粹的复制, 文档说法

PHP闭包之bind和bindTo

PHP闭包之bind和bindTo Closure类摘要如下: Closure { __construct ( void ) public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static'] public Closure bindTo (object $newthis [, mixed $newscope = 'static' ]) } 方法说明: Closure::__co

Java面试08|Java重要的类和相关的方法

1.深入理解Class类及其中的方法 获取Class类的方法: 1.调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法.2.使用Class类的中静态forName()方法获得与字符串对应的Class对象.例如: Class c2=Class.forName("MyObject") // MyObject必须是接口或者类的名字 3.获取Class类型对象的第三个方法非常简单.如果T是一个Java类型,那么T.class就代表了匹配的类

黑马程序员---Objective-C基础学习---类、对象、方法相关知识笔记

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 类.对象.方法相关知识笔记 Objective-C相对于C语言有了面向对象的特性,但是ObjC又没有其他面向对象语言那么多语法特性,ObjC本身对面向对象进行了精简.下面是一些相关知识笔记. 类定义 成员变量 方法和属性 self关键字 类定义 在C#.Java等其他高级语言中定义一个类是相当简单点的,直接一个关键字class加一对大括号基本就完成了,但是在ObjC中类的定义相对变化比较大.现

命名技巧(包。类。字段。方法)

根据很多人习惯和一些约定俗成,在编程的时候设包名讲究一定的技巧,这样既方便自己记忆,又方便别人将包中的类分类观看: 1.跟用户相接触的包名示例:com.project_name.ui 2.跟数据库相关的包名示例:com.project_name.dao(date access object) 3.java封装类包包名示例:com.project_name.domain com.project_name.bean com.project_name.entity(里面装的是javabean封装类)

利用反射机制,获取类的字段、方法、并实现简单调用

这篇文章是为之后要介绍Android的ICO框架做预备的,所以,如果想最近学习Android的ICO框架的同学,可以稍微看一下. 首先,简单介绍一下Java里面的反射. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 不知道这样的一段解释,你能否看懂.如果更简单的说,反射就是能够根据你给出类名实例化出一个实实在在的对象.所以,对象的实例

Java线程状态及Thread类中的主要方法

要想实现多线程,就必须在主线程中创建新的线程对象. 任何线程一般具有5种状态,即创建,就绪,运行,阻塞,终止. 创建状态: 在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此时,他已经有了相应的内存空间和其他资源,但还处于不可运行状态. 就绪状态: 新建线程对象后,调用该线程的start()方法可以启动线程.当线程启动时,线程进入就绪状态.此时,线程将进入线程队列排队,等待CPU服务,这表明它已经具备了运行条件.-------(运行start()方法只是进入就绪状态,并没有开

java类,对象,方法

1,类和对象   在面向对象的概念当中,类(class)是既包括数据又包括作用于数据的一组操作的封装体.类的数据称为成员变量,类对数据的操作称为成员方法.成员变量反映类的状态和特征,成员方法反映类的行为和能力.类的成员变量和方法统称为类的成员.   对象(Object)是类的实例(instance).对象是动态的,拥有生命周期,都会经历一个从创建.运行到消亡的过程.对象与类的关系就像变量与数据类型一样.   类声明 { 修饰符 } class <Classname> { extends <

java-第十三章-类的无参方法(一)-查找客户姓名

package 上机练习; public class A02class { String names[] = new String[30]; public void showA(String name) { for (int i = 0; i < names.length; i++) { if (names[i] == null) { names[i] = name; break; } } } public void showB() { System.out.println("\t客户列表