这个类不能实例化,里面主要有两个方法,都用来复制闭包,一个静态一个动态,下面分别详细讲解下这两个很差理解的方法。php
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
属性,
就要设置为对应的类名/类实例,就要像在类里面同样,要访问那个类的保护/私有属性函数。sql
<?php class 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()
,会正常输出每个结果。django
我是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);
上面的程序跟匿名函数同样,啥对象也没有依赖,上面的程序会输出:composer
object(stdClass)#1 (0) { } object(stdClass)#1 (1) { ["name"]=> string(9) "燕睿涛" }
另外还有个特别要说明的例子函数
<?php class 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
的做用域,
也能够影响参数的做用域。学习
bindTo
和bind
功能相似,这里只是另一种形式,都是复制当前闭包对象,绑定指定的$this对象和类做用域。
,参数比bind
少了第一个,
后面两个同样,固然还有一个区别就是bindTo
不是静态方法,是闭包才会存在的一个属性方法。ui
<?php class 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
的相似this
我是T里面的私有函数:show 我是T里面的保护函数:who 我是T里面的公共函数:name
这个函数是在看composer生成的自动加载源码的时候碰到的,在composer中用的比较特别,下面是截取部分composer中的代码spa
// 文件autoload_real.php call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer($loader)); // 文件autoload_static.php public 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); }
好长时间没写blog了,有时候太烦躁,静不下心来,有时又有没有找到想写的东西。仍是得静下心来,好好作好每一件事,遇事情不要烦躁,心放大,心平气和的处理每一件事。
写到最后,突然想起高中的时候,恰好是5.12汶川大地震的时候,咱们在西安,大地震事后还不停的会有余震,稍微一有余震,你们就都慌了,一窝蜂的往下冲,我没记错的话咱们是在5楼,
直到一次咱们物理老师来上课,这个老师年龄偏大,是市里面的特级教师(恩,应该没错),正好碰到余震,你们又疯了似得准备往外跑,这个时候老师说了一句话,让我至今
难忘,命在骨子里,这种余震不必这么慌挤下去,命硬的怎么都没事
,确实,这种小余震挤下去可能更容易发生事故,虽然这句话带了少量的消极,但里面更多的是心态的平静、
心比较大、冷静果断的体现,这是我要学习的。
该出现的总会出现,不应出现的永远不会出现,一味的好高骛远,追求太远的目标容易致使焦虑,固然要不要妄自菲薄,总之一句话:心平气和、心放大、切勿患得患失、踏踏实实的作好每一件事,越努力、越幸运,越幸运、越努力。