前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP 闭包及Closure类

PHP 闭包及Closure类

作者头像
猿哥
发布2019-11-27 16:33:07
7890
发布2019-11-27 16:33:07
举报
文章被收录于专栏:Web技术布道师Web技术布道师

匿名函数

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

代码语言:javascript
复制
$func = function() {

    echo "this is a func\n";

};

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

实现闭包

1、当做参数传递:

代码语言:javascript
复制
<?php

// 定义一个匿名函数,赋值给$func

$func = function($param) {

    var_dump($param);

};

// 将匿名函数作为参数传入,并调用该参数

function dFunc($func, $param) {

    $func($param);

}

dFunc($func, '123'); // 输出:string(3) "123"

2、将匿名函数返回:

代码语言:javascript
复制
<?php

// 定义一个函数,在该函数中将内部的匿名函数返回

function cFunc($param) {

    $func = function($param1) use ($param) {

    echo "params:".$param1." ".$param;

};

return $func;

}

// 获取并调用匿名函数

$rCFunc = cFunc("123");

$rCFunc("456"); // params:456 123

捕获外界变量

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

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

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

use引入的是自由变量的副本。
代码语言:javascript
复制
例如:

<?php

/*

输出结果:

匿名函数执行前:p1:p1

匿名函数内修改后:p1:p2

匿名函数执行完:p1:p1

*/

function f1() {

    $p1 = "p1";

    echo "匿名函数执行前:p1:$p1\n";

    $func = function() use ($p1) {

        $p1 = "p2";

        echo "匿名函数内修改后:p1:$p1\n";

    };

$func();

echo "匿名函数执行完:p1:$p1\n";

}

f1();

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

PHP Closure类

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

代码语言:javascript
复制
<?php

/*

输出:

object(Closure)#1 (0) {

}

*/

$func = function() {};

    var_dump($func);

类摘要

代码语言:javascript
复制
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属性。 )

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

代码语言:javascript
复制
<?php

class A{

    private static $_cat = 'cat';

    private $_dog = 'dog';

    public $pig = 'pig';

}

$cat = static function() {

    var_dump(A::$_cat);

};

$dog = function() {

    var_dump($this->_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()方法将匿名函数绑定到某个类。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP技术大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 匿名函数
  • 实现闭包
  • 捕获外界变量
    • use引入的是自由变量的副本。
    • PHP Closure类
      • Closure::bind
        • 参数说明:
          • Closure::bindTo
          • 小结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档