PHP基于Closure类创建匿名函数的方法详解

前端之家收集整理的这篇文章主要介绍了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' ] )

参数说明:

函数。

函数的对象,或者 NULL 创建未绑定的闭包。

方法 的可见性。

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

例子

PHP;"> 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(),会正常输出每一个结果。

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

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

name = "燕睿涛"; },null); $func($test); var_dump($test);

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

string(9) "燕睿涛" }

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

PHP;"> show(); },null); $test = new T(); $func($test);

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

Closure::bindTo

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

例子

PHP;"> show(); $this->who(); $this->name(); }; $funcNew = $func->bindTo(new T(),T::class); $funcNew();

上面函数输出和bind的类似

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

一个trick

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

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里面,对象形参和实参数指向相同的对象,函数里面对对象的修改会反映到对象外面。

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

prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4; $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0; $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap; },ClassLoader::class); }

更多关于PHP相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》及《PHP程序设计算法总结》

希望本文所述对大家PHP程序设计有所帮助。

猜你在找的PHP相关文章