iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP闭包及Clourse类的作用是什么
  • 954
分享到

PHP闭包及Clourse类的作用是什么

2023-06-29 02:06:54 954人浏览 独家记忆
摘要

今天小编给大家分享一下PHP闭包及Clourse类的作用是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。php Clou

今天小编给大家分享一下PHP闭包及Clourse类的作用是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

php Clourse(闭包类) 浅析

0x00 前言

闭包是指在创建时封装周围状态的函数。即使闭包所在的环境不存在了,闭包中封装的状态依然存在。

在 PHP 里所有的闭包都是 Clourse 类所实例化的一个对象,也就是说闭包与其他 PHP 对象没有什么不同。而一个对象就必然有其方法和属性,这篇文章将总结 PHP 中闭包的基础用法和 Clourse 类方法的作用。

0x01 闭包基本用法

下面看看最基本的闭包使用方法:

<?php$hello = function ($Word) {    return 'hello ' . $word;};echo $hello('world');// 输出 hello world

嘿,这段代码最直观的感受就是将一个函数赋值给了 $hello 变量,然后通过 $hello 直接调用它。但是这个闭包并没有从父作用域中继承变量(就是封装周围状态),我们可以通过 use 关键字从闭包的父作用域继承变量。示例如下:

<?php$name = 'panda';$hello = function () use ($name) {    return 'hello ' . $name;};echo $hello();// 输出 hello panda

PHP 7.1 起,use 不能传入此类变量: superglobals、 $this 或者和参数重名。

此外在使用 use 关键字时,父作用域的变量是通过值传递进闭包的。也就是说一旦闭包创建完成,外部的变量即使修改也不会影响传递进闭包内的值(就是即使闭包所在的环境不存在了,闭包中封装的状态依然存在)。示例如下:

<?php$name = 'panda';$hello = function () use ($name) {    return 'hello ' . $name;};$name = 'cat';echo $hello();// 输出 hello panda

传递变量的引用可以使闭包修改外部变量的值,示例如下:

<?php$name = 'panda';$changeName = function () use (&$name) {    $name = 'cat';};$changeName();echo $name;// 输出 cat

注意:PHP 中传递对象时,默认是以引用传递所以在闭包内操作 use 传递的对象时需要特别注意。示例如下:

<?phpclass Dog {    public $name = 'Wang Cai';}$dog = new Dog();$changeName = function () use ($dog) {    $dog->name = 'Lai Fu';};$changeName();echo $dog->name;// 输出 Lai Fu

0x02 Clourse 类

证明闭包只是 Clourse 类对象

<?php$clourse = function () {    echo 'hello clourse';};if (is_object($clourse)) {    echo get_class($clourse);}// 输出 Closure

上面的代码将输出 Closure 证明了闭包只是一个普通的 Closure 类对象。

Clourse 类摘要

我们可以从 PHP 官方手册 看到闭包类的相关信息,下面是我在 PhpStORM 的本地文档查看到 Clourse 类摘要。

final class Closure {        private function __construct() { }        public function __invoke(...$_) { }        function bindTo($newthis, $newscope = 'static') { }        static function bind(Closure $closure, $newthis, $newscope = 'static') { }        function call ($newThis, ...$parameters) {}            public static function fromCallable (callable $callable) {}}

首先 Clourse 类为 final 类,也就是说它将无法被继承,其次它的构造函数 __construct 被设为 private 即无法通过 new 关键字实例化闭包对象,这两点保证了闭包只能通过 function (...) use(...) {...} 这种语法实例化 。

为什么闭包可以当作函数执行?

从上面的类摘要中我们看出 Clourse 类实现了 __invoke 方法,在 PHP 官方手册中对该方法解释如下:

当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

这就是闭包可以被当作函数执行的原因。

绑定指定的$this对象和类作用域

在允许使用闭包路由的框架中(如:Slim),我们可以看见如下写法:

$app->get('/test', function () {    echo $this->request->getMethod();});

在一个闭包居然能中使用 $this?这个 $this 指向哪个对象?

通过 bindTo 和 bind 方法都能够实现绑定 $this 和类作用域的功能,示例如下:

<?phpclass pandas {    public $num = 1;}$pandas = new Pandas();$add = function () {    echo ++$this->num . PHP_EOL;};$newAdd1 = $add->bindTo($pandas);$newAdd1();// 输出 2$newAdd2 = Closure::bind($add, $pandas);$newAdd2();// 输出 3

上面的这段例子将指定对象绑定为闭包的 $this,但是我们并没有指定类作用域。所以如果将 Pandas 类的 $num 属性改写为 protected 或 private 则会抛出一个致命错误!

Fatal error: Uncaught Error: Cannot access protected property Pandas::$num

在需要访问绑定对象的非公开属性或方法时,我们需要指定类作用域,示例如下:

<?phpclass Pandas {    protected $num = 1;}$pandas = new Pandas();$add = function () {    echo ++$this->num . PHP_EOL;};$newAdd1 = $add->bindTo($pandas, $pandas);$newAdd1();// 输出 2$newAdd2 = Closure::bind($add, $pandas, 'Pandas');$newAdd2();// 输出 3

这里我们看见 bindTo 和 bind 方法都指定了 $newscope 参数,$newscope 参数默认为 static 即不改变类作用域。$newscope 参数接受类名或对象,并将闭包的类作用域改为指定的类作用域,此时 Pandas 类的 $num 属性便能够被闭包访问。

一次性绑定 $this 对象和类作用域并执行(PHP7)

bindTo 和 bind 方法每次指定新的对象和类作用域时都要将原闭包进行复制然后返回新的闭包,在需要多次修改绑定对象的情景下便显得繁琐,所以 PHP7 提供了一个新的方法 call 它能将闭包临时的绑定到一个对象中(类作用域同时被修改为该对象所属的类)并执行。示例如下:

<?phpclass Pandas {    protected $num = 1;}$pandas = new Pandas();$add = function ($num) {    $this->num += $num;    echo $this->num . PHP_EOL;};$add->call($pandas, 5);// 输出 6

Callable 转为闭包(PHP7.1)

在 PHP7.1 中 Closure 类存在 fromCallable 方法能够将 callable 类型的值转为闭包,示例如下:

<?phpclass Foo{    protected $num = 1;    public static function hello(string $bar)    {        echo 'hello ' . $bar;    }}$hello = Closure::fromCallable(['Foo', 'hello']);$hello('world');

这种写法还是挺爽的毕竟通过闭包调用总比用 call_user_func 函数调用爽的多^_^。

以上就是“PHP闭包及Clourse类的作用是什么”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网PHP编程频道。

--结束END--

本文标题: PHP闭包及Clourse类的作用是什么

本文链接: https://www.lsjlt.com/news/321913.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PHP闭包及Clourse类的作用是什么
    今天小编给大家分享一下PHP闭包及Clourse类的作用是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。PHP Clou...
    99+
    2023-06-29
  • php中闭包函数的作用是什么
    这篇文章给大家分享的是有关php中闭包函数的作用是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是闭包函数:在子函数内部使用通过use关键字使用父函数的变量,这种方式就是闭包函数格式:function&n...
    99+
    2023-06-15
  • python闭包的作用是什么
    Python闭包的作用是将函数和其相关的引用变量封装在一个包裹(closure)中,以便在函数外部访问这些变量。具体而言,闭包允许函...
    99+
    2023-10-11
    python
  • Javascript闭包的作用是什么
    本篇内容主要讲解“Javascript闭包的作用是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Javascript闭包的作用是什么”吧!对于初学者来说,理...
    99+
    2022-10-19
  • JavaScript中闭包的概念、原理及作用是什么
    本篇内容主要讲解“JavaScript中闭包的概念、原理及作用是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript中闭包的概念、原理及作用是...
    99+
    2022-10-19
  • JavaScript闭包是什么及怎么用
    这篇“JavaScript闭包是什么及怎么用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaScript闭包是什么及怎...
    99+
    2023-07-04
  • python函数及闭包是什么及怎么用
    本篇内容主要讲解“python函数及闭包是什么及怎么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python函数及闭包是什么及怎么用”吧!函数对象函数对象指...
    99+
    2022-10-19
  • JavaScript 函数闭包的含义和作用是什么
    这篇文章主要讲解了“JavaScript 函数闭包的含义和作用是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript 函数闭包的含义和作用...
    99+
    2022-10-19
  • php闭包官方写法的好处是什么
    本篇内容介绍了“php闭包官方写法的好处是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php闭包官方写法有什么好处 ?具体问题描述:&...
    99+
    2023-06-22
  • php接口类的实际作用是什么
    PHP接口类的主要作用是定义一组方法的规范,以便其他类可以实现这些方法并提供自己的实现逻辑。接口类可以看作是一种契约,规定了其他类必...
    99+
    2023-10-18
    php
  • PHP中heredoc的概念及作用是什么
    这篇文章主要讲解了“PHP中heredoc的概念及作用是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PHP中heredoc的概念及作用是什么”吧!在php中,存在一种定义字符串的方法,...
    99+
    2023-06-20
  • Java包的作用是什么
    这篇文章主要介绍了Java包的作用是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java包的作用是什么文章都会有所收获,下面我们一起来看看吧。为了更好地组织类,Java提供了包机制,用于区别类名的命名空间...
    99+
    2023-06-02
  • PHP中数据类型的分类及其应用场景是什么?
    PHP是一种广泛使用的服务器端编程语言。在PHP中,数据类型是程序员必须了解的一个重要概念。在本文中,我们将讨论PHP中的数据类型及其应用场景。 PHP中的数据类型可以分为以下几类: 整数类型(Integer) 浮点数类型(Float) ...
    99+
    2023-11-08
    日志 数据类型 apache
  • C语言类型转换的作用是什么及怎么使用
    这篇“C语言类型转换的作用是什么及怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言类型转换的作用是什么及怎么使用...
    99+
    2023-06-30
  • c++中类的作用是什么
    在 C++ 中,类是一种用户自定义的数据类型,用于封装数据和方法以实现特定的功能。类的作用在于: 封装数据:类可以将相关的数据和...
    99+
    2023-10-24
    c++
  • java string类的作用是什么
    Java的String类是用于处理字符串的类。它提供了多种方法来操作和处理字符串,包括字符串的连接、截取、替换、比较、搜索等操作。S...
    99+
    2023-09-23
    java
  • Java Parser类的作用是什么
    Java Parser类的作用是将源代码转换为抽象语法树(AST),从而可以对源代码进行分析和处理。它可以解析Java源文件,并将其...
    99+
    2023-10-23
    Java
  • C# CultureInfo类的作用是什么
    C# CultureInfo类是用于管理特定区域性的类。它提供了访问和操作与特定区域性相关的信息的方法和属性。具体而言,Cultur...
    99+
    2023-08-09
    C#
  • python中time包的作用是什么
    这期内容当中小编将会给大家带来有关python中time包的作用是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。python的数据类型有哪些python的数据类型:1. 数字类型,包括int(整型)、...
    99+
    2023-06-14
  • vue的el是什么及有什么作用
    本篇内容介绍了“vue的el是什么及有什么作用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在vue中,el是element的缩写,可称之为...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作