php闭包函数-【现代PHP】第二章新特性五个闭包

2023-08-29 0 6,017 百度已收录

关闭

从 PHP 5.3.0 开始就出现了闭包匿名函数,这是我最喜欢也是最常用的 PHP 功能。 当我听到这个名字的时候我很困惑(至少我第一次看到它的时候是这么觉得),但其实它真的很容易理解。 它们是每个 PHP 开发人员工具箱中必备的最有用的工具。

闭包是一个在创建时封装外部状态的函数。 即使最初创建闭包的环境不再存在,封装的状态仍然会保留在闭包中。 这是一个很难理解的概念,一旦你弄清楚了,感觉就像人生的新篇章开始了。

匿名函数实际上是没有名称的函数。 匿名函数可以参数化为变量,像所有其他 PHP 对象一样在代码中传递。 但它仍然是一个函数,因此您可以调用它并传递参数。 匿名函数最大的好处是作为函数或方法的反弹。

闭包和匿名函数在理论上是不同的概念。 然而,PHP 认为它们是同一件事。 因此php闭包函数,当我说闭包时,我也可能指的是匿名函数,反之亦然。

PHP 的闭包和匿名函数在语法上与函数相同,但不要被它们所迷惑。 它们实际上是伪装成函数的对象。 如果你检查 PHP 闭包或匿名函数的类型,你会发现它们都是 Closure 类的实例。 闭包可以看作是和字符串、整数一样重要的数据类型。

创造

我们都知道 PHP 闭包和函数看起来很相似。 当您创建像示例 2-19 这样的 PHP 闭包时,您不会感到如此震惊。

例2-19 简单闭包

 "Hello Josh"

登录复制

就是这么简单。 示例 2-19 创建一个 Closure 对象并将其分配给变量 $closure。 它看起来像一个标准的 PHP 函数:它使用相同的语法、接受参数并返回一个值。 但它没有名字。

我们可以调用 $closure 变量,因为 $closure 是一个闭包,而 Closure 闭包对象实现了 _invoke() 魔术。 当变量名后面有一对 () 符号时,PHP 将手动查找并调用 __invoke() 方法。

我通常使用 PHP 的闭包对象作为函数和技巧的反弹。 许多 PHP 函数都使用回调函数php闭包函数,例如 array_map() 和 preg_replace_callback()。 这就像为PHP匿名函数量身定做的函数! 请记住,与任何其他值一样,闭包可以作为参数传递给其他 PHP 函数。 在示例 2-10 中,我使用 Closure 对象作为 array_map() 函数的反弹参数。

示例 2-20 array_map 闭包

 [2,3,4]

登录复制

看起来没有那么令人印象深刻吧? 但请记住,在闭包函数出现之前,PHP 开发人员没有任何好的选择来实现这样的函数。 他们只能创建一个命名函数并将函数名称作为参数传递。 这执行起来有点慢,最重要的是它将反弹的实现和使用分开。 老派 PHP 开发人员使用以下代码:

<?php// 具名回调的实现function incrementNumber ($number) {    return $number + 1;}// 具名回调的使用$numberPlusOne = array_map('incrementNumber', [1,2,3]);print_r($numberPlusOne);

登录复制

上面的代码仍然可以正常执行,但是没有例2-20那样简单。 我们不需要一个名为incrementNumber() 的单独的一次性函数作为反弹。 使用闭包作为反弹可以创建更清晰、更易读的代码。

附件状态

到目前为止,我们已经演示了如何使用未命名(又称匿名)函数作为反弹。 让我们研究一下如何使用 PHP 闭包附加和封装状态。 JavaScript 开发人员可能会对 PHP 的闭包感到困扰,因为 PHP 的闭包不会像 JavaScript 那样手动将应用程序的状态封装到闭包中。 相反,您必须通过调用闭包对象的 bintTo() 方法或 use 关键字来自动将状态附加到 PHP 闭包。

通常我们使用 use 关键字来附加闭包状态,所以让我们以此为例(示例 2-21)。 当使用 use 关键字将变量附加到闭包时,附加变量的值将保持该变量附加到闭包时的值。

示例 2-21 使用 use 关键字附加闭包状态

 "Clay, get me sweet tea!"

登录复制

在情况 2-21 中,命名函数 enclosePerson() 函数接收 $name 参数并返回封装 $name 参数的闭包对象。 即使闭包最终离开 enclosePerson() 函数的范围,返回的闭包对象 $clay 仍将保留附加到闭包时 $name 参数的值。 换句话说,$name变量总是存在于闭包中!

您可以使用 use 关键字将多个参数传递给闭包。 参数之间用冒号分隔,就像我们通常在PHP中使用的函数或方法的参数一样。

不要忘记 PHP 闭包是对象。 每个 Closure 实例都有其内部状态,我们可以像任何其他 PHP 对象一样使用 $this 关键字访问它。 Closure 对象的默认状态相当无聊,它包含一个魔术 __invoke() 和一个 bindTo() 方法,仅此而已。

然而,bindTo() 方法可以引导我们挖掘出一些有趣的实现。 这种方法允许我们将 Closure 对象的内部状态绑定到另一个对象。 bindTo()方法的第二个参数相当关键,它可以指定闭包需要绑定的对象的类。 这样我们就可以获取闭包中绑定对象的protected和private成员变量了。

你会发现一些PHP框架经常使用bindTo()方法来将路由地址映射到匿名反弹函数。 这些框架将匿名函数绑定到应用程序对象。您可以在匿名函数中使用 $this 关键字来引用应用程序对象,如示例 2-22 所示

示例2-22 使用bindTo附加闭包状态

routes[$routePath] = $routeCallback->bindTo($this, __CLASS__);    }    public function dispatch($currentPath)    {        foreach ($this->routes as $routePath => $callback) {            if ($routePath === $currentPath) {                $callback();            }        }        header('HTTP/1.1 ' . $this->responseStatus);        header('Content-type: ' . $this->responseContentType);        header('Content-length: ' . mb_strlen($this->responseBody));        echo $this->responseBody;    }}

登录复制

注意 addRoute 技巧。 它需要一个路由地址(例如/users/josh)和一个路由反弹。 dispatch()方法接收当前HTTP请求地址并调用相应的路由反弹。 神奇之处在于第11行,我们将路由的反弹绑定到当前App类的实例上。 这样,我们就可以创建一个可以操作App实例状态的bounce函数:

addRoute('/users/josh', function () {    $this->responseContentType = 'application/json;charset=utf8';    $this->responseBody = '{"name": "Josh"}';});$app->dispatch('/users/josh');

登录复制

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 php php闭包函数-【现代PHP】第二章新特性五个闭包 https://www.wkzy.net/game/171113.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务