PHP 闭包及Closure类

匿名函数

实现一个简单的匿名函数:


$func = function() {

    echo "this is a func\n";

};

上面就是一个简单的匿名函数,定义一个函数体,将函数体赋值给一个变量(php5.3之后支持该写法)。

实现闭包

1、当做参数传递:

2、将匿名函数返回:

捕获外界变量

闭包: 闭包是词法作用于的体现,一个持有外部环境自由变量的函数就是闭包。闭包体现的是在程序运行过程中,由 “不确定”变为“ 确定” 的过程。

捕获外部变量: 在PHP中对捕获这一动作有了更清晰的表现,使用use关键字。如上面例2。

在上面的例2中,匿名函数$func通过use关键字捕获了外部的自由变量$param,在调用时通过传入cFunc()函数的参数123($param此时会变为“确定”状态),进而调用匿名函数时输出“params:456 123”。

use引入的是自由变量的副本。

例如:

golang闭包: 在golang中同样通过匿名函数实现了闭包,和PHP不同的是,golang中的闭包是默认会引入上下文的自由变量,且引入的地址,即在闭包函数内部修改变量会在函数外部生效。

PHP Closure类

用于代表匿名函数类。在PHP中定义一个闭包函数其实就是一个Closure类的实例。

类摘要

Closure {

/* 方法 */

__construct ( void )

public static bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] ) : Closure

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

}
  • Closure::__construct — 用于禁止实例化的构造函数
  • Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。
  • Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。

Closure::bind

复制一个闭包,绑定指定的$this对象和类作用域,返回一个新的匿名函数

参数说明:

  • closure: 需要绑定的匿名函数。
  • newthis: 需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包。(理解:可以选择是否将匿名函数绑定到一个类对象,若绑定到了一个类对象,则可以在匿名函数内使用$this,否则不可使用。
  • newscope: 想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。(理解:如果传入一个类,则可以访问类的static、private、protected属性,否则只能访问public属性。

简单理解:可以简单理解为将该匿名函数绑定到一个类或实例。根据参数的不同,可以访问不同的类的属性。


_dog);

};

$pig = function() {

    var_dump($this->pig);

};

// 传入null,不可使用$this,但传入A类,则可以访问static等

$bindCat = Closure::bind($cat, null, 'A');

echo "bind cat\n";

$bindCat();

// 传入new A()对象,A类,可以使用$this访问私有属性。

$bindDog = Closure::bind($dog, new A(), 'A');

echo "bind dog\n";

$bindDog();

// 为传入类对象,不可使用$this

$bindDog2 = Closure::bind($dog, null, 'A');

echo "bind dog2\n";

$bindDog2();
输出:
bind cat
string(3) "cat"
bind dog
string(3) "dog"
bind dog2
Fatal error: Using $this when not in object context

Closure::bindTo

Closure::bind()的非静态形式。

小结

  • PHP通过匿名函数实现闭包。
  • 可以通过将匿名函数作为参数或返回值实现闭包。
  • 可以通过use关键字引入外部变量,且引入的变量副本。
  • 匿名函数均实现了Closure类,且可以通过Closure::bind()方法将匿名函数绑定到某个类。

你可能感兴趣的:(php,closure)