我的编程空间,编程开发者的网络收藏夹
学习永远不晚

PHP中怎么使用Closure类

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

PHP中怎么使用Closure类

小编给大家分享一下PHP中怎么使用Closure类,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

Closure 类

用于代表匿名函数的类。

匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象。在过去,这个类被认为是一个实现细节,但现在可以依赖它做一些事情。自 PHP 5.4 起,
这个类带有一些方法,允许在匿名函数创建后对其进行更多的控制。

这个类不能实例化,里面主要有两个方法,都用来复制闭包,一个静态一个动态,下面分别详细讲解下这两个不好理解的方法。

Closure::bind

public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )参数说明:closure需要绑定的匿名函数。newthis需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包。newscope想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。 The class scope to which associate the closure is to be associated, or 'static' to keep the current one. If an object is given, the type of the object will be used instead. This determines the visibility of protected and private methods of the bound object.

上面是该方法的定义,第一个参数很好理解,就是一个闭包函数;第二个参数就不太好理解,如果要复制的闭包中包含$this,这个对象就表示这个
$this,闭包函数里面对这个对象的修改在调用结束之后也会保持一致,比如修改了一个属性;第三个参数就不太好理解了,看官方的说明也是云里雾里的,
默认参数情况下,调用$this->访问object $newthis中的属性函数的时候,会有限制,只能访问public属性的函数,如果想访问protected/private属性,
就要设置为对应的类名/类实例,就要像在类里面一样,要访问那个类的保护/私有属性函数。

例子
<?phpclass T {    private function show()    {        echo "我是T里面的私有函数:show\n";    }    protected  function who()    {        echo "我是T里面的保护函数:who\n";    }    public function name()    {        echo "我是T里面的公共函数:name\n";    }}$test = new T();$func = Closure::bind(function(){    $this->who();    $this->name();    $this->show();}, $test);$func();

上面的代码会报错Fatal error: Uncaught Error: Call to protected method T::who() from  context 'Closure'。 加上bind第三个参数为t::class或者new T(),会正常输出每一个结果。

我是T里面的保护函数:who我是T里面的公共函数:name我是T里面的私有函数:show

当然了,闭包也可以传递参数

$test = new StdClass();var_dump($test);$func = Closure::bind(function($obj){    $obj->name = "燕睿涛";}, null);$func($test);var_dump($test);

上面的程序跟匿名函数一样,啥对象也没有依赖,上面的程序会输出:

object(stdClass)#1 (0) {}object(stdClass)#1 (1) {  ["name"]=>  string(9) "燕睿涛"}

另外还有个特别要说明的例子

<?phpclass T {    private function show()    {        echo "我是T里面的私有函数:show\n";    }    protected  function who()    {        echo "我是T里面的保护函数:who\n";    }    public function name()    {        echo "我是T里面的公共函数:name\n";    }}$func = Closure::bind(function ($obj) {    $obj->show();}, null);$test = new T();$func($test);

上面的情况会输出什么呢,没错,会报错,提示访问不了私有属性show,这个时候,加上第三个参数就可以了,看了第三个参数不光影响$this的作用域,
也可以影响参数的作用域。

Closure::bindTo

bindTobind功能类似,这里只是另外一种形式,都是复制当前闭包对象,绑定指定的$this对象和类作用域。,参数比bind少了第一个,
后面两个一样,当然还有一个区别就是bindTo不是静态方法,是闭包才会存在的一个属性方法。

例子
<?phpclass T {    private function show()    {        echo "我是T里面的私有函数:show\n";    }    protected  function who()    {        echo "我是T里面的保护函数:who\n";    }    public function name()    {        echo "我是T里面的公共函数:name\n";    }}$func = function () {    $this->show();    $this->who();    $this->name();};$funcNew = $func->bindTo(new T(), T::class);$funcNew();

上面函数的输出和bind的类似

我是T里面的私有函数:show我是T里面的保护函数:who我是T里面的公共函数:name

一个trick

这个函数是在看composer生成的自动加载源码的时候碰到的,在composer中用的比较特别,下面是截取部分composer中的代码

// 文件autoload_real.phpcall_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer($loader));// 文件autoload_static.phppublic static function getInitializer(ClassLoader $loader){    return \Closure::bind(function () use ($loader) {        $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;        $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;        $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;        $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;    }, null, ClassLoader::class);}

上面的代码比较奇特,在call_user_func中,第一感觉是传错参数了,其实不然,这里调用了一个函数,这个函数会返回一个Closure对象,
也就是一个匿名函数,最终传入的参数还是一个callable类型。再看看这个返回的闭包,里面使用了use,这是连接闭包和外部变量的桥梁。
至于这里为什么普通传参数就可以,是因为php5里面,对象形参和实参数指向相同的对象,函数里面对对象的修改会反映到对象外面。

所以,上面这么做是没问题的,还有另外一种形式也可以

call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer(), $loader);public static function getInitializer(){    return \Closure::bind(function ($loader) {        $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;        $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;        $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;        $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;    }, null, ClassLoader::class);}

以上是“PHP中怎么使用Closure类”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

PHP中怎么使用Closure类

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

下载Word文档

猜你喜欢

PHP中怎么使用Closure类

小编给大家分享一下PHP中怎么使用Closure类,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Closure 类用于代表匿名函数的类。匿名函数(在 PHP 5.
2023-06-07

JavaScript中的闭包closure怎么使用

这篇文章主要介绍“JavaScript中的闭包closure怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript中的闭包closure怎么使用”文章能帮助大家解决问题。闭包简述
2023-07-02

PHP7中如何使用Closure :: call

这篇“PHP7中如何使用Closure :: call”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“PHP7中如何使用Closure :: call”,小编整理了以下知识点,请大家跟着小编的步
2023-06-14

php中Snoopy类怎么使用

在PHP中,您可以使用Snoopy类来进行网络请求。以下是使用Snoopy类的一些基本示例:1. 包含Snoopy类的文件:```phprequire_once('Snoopy.class.php');```2. 创建Snoopy对象:``
2023-08-17

PHP怎么使用Callback/Callable类型

这篇文章主要介绍PHP怎么使用Callback/Callable类型,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!PHP Callback/Callable 类型使用测试代码
2023-06-15

使用php怎么往lavarel框架中添加类

使用php怎么往lavarel框架中添加类?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。php有什么用php是一个嵌套的缩写名称,是英文超级文本预处理语言,它的
2023-06-14

怎么在php中使用foreach遍历类对象

怎么在php中使用foreach遍历类对象?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。php有什么特点1、执行速度快。2、具有很好的开放性和可扩展性。3、PHP支持多种主
2023-06-14

PHP中的抽象类和接口怎么使用

这篇文章主要介绍“PHP中的抽象类和接口怎么使用”,在日常操作中,相信很多人在PHP中的抽象类和接口怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PHP中的抽象类和接口怎么使用”的疑惑有所帮助!接下来
2023-06-30

C#中类怎么使用

这篇文章主要介绍了C#中类怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#中类怎么使用文章都会有所收获,下面我们一起来看看吧。实例化在对类进行访问时,需要将类进行实例化。并产生一个对象。可以使用关键字
2023-07-02

MFC中COleDateTime类怎么使用

COleDateTime类是MFC中用于表示日期和时间的类。它提供了许多方法和操作符用于获取、设置和比较日期和时间。下面是一些COleDateTime类的常用方法和操作符的使用示例:1. 获取当前日期和时间:```cppCOleDateTi
2023-09-14

java中ToStringBuilder类怎么使用

ToStringBuilder类是apache.commons.lang包中的一个工具类,用于生成Java对象的toString()方法。使用ToStringBuilder类可以方便地生成对象的字符串表示。下面是ToStringBuilde
2023-09-26

java中boolean类怎么使用

Boolean类是Java中的一个包装类,用于封装基本数据类型boolean的值。Boolean类提供了一些方法和常量来操作和表示boolean类型的值。1. 声明和初始化Boolean对象:```Boolean b1 = new Bool
2023-09-29

java中peekgraphic类怎么使用

在Java中,没有名为`PeekGraphic`的标准类。我怀疑您可能指的是`java.awt.image.BufferedImage`类,它用于处理图像数据。`BufferedImage`类提供了一系列方法来创建、操作和处理图像。以下是一
2023-08-24

Java中NumberFormat类怎么使用

Java中的NumberFormat类用于格式化数字,可以将数字格式化为特定的模式,例如货币、百分比和科学计数法等。下面是使用NumberFormat类的基本步骤:1. 导入NumberFormat类:```javaimport java.
2023-09-29

C#中XmlDocument类怎么使用

XmlDocument类是 C# 中用于操作 XML 文档的类,它提供了一系列方法和属性来创建、读取、修改和保存 XML 文档。下面是一个简单的示例,展示了如何使用 XmlDocument 类:1. 创建一个新的 XmlDocument 对
2023-09-15

java中arrays类怎么使用

在Java中,Arrays类是一个工具类,提供了一些常用的操作数组的方法。可以通过静态方法调用这些方法。以下是一些Arrays类常用的方法及使用示例:1. toString方法:将数组转换为字符串输出。```javaint[] array
2023-08-30

java中logger类怎么使用

java中的Logger类是java.util.logging包提供的一个日志记录工具。使用Logger类可以在程序中方便地打印日志信息,用于调试和问题排查。以下是Logger类的使用步骤:1. 导入Logger类:```javaimpor
2023-09-22

Spring中ClassPathXmlApplicationContext类怎么使用

今天小编给大家分享一下Spring中ClassPathXmlApplicationContext类怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获
2023-06-26

C++中iostringstream类怎么使用

`ostringstream` 是C++中的一个类,它继承自 `ostream` 类,用于将数据格式化为字符串。可以通过 `ostringstream` 类来进行字符串的输入和输出操作。以下是一些 `ostringstream` 类的常见用
2023-08-25

C#中pingreply类怎么使用

在C#中,PingReply类主要用于接收Ping操作的结果。可以通过以下步骤来使用PingReply类:首先,创建一个Ping对象:using System.Net.NetworkInformation;Ping ping = new
C#中pingreply类怎么使用
2023-10-28

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录