用于代表匿名函数的类。
这个类不能实例化,里面主要有两个方法,都用来复制闭包,一个静态一个动态,下面分别详细讲解下这两个不好理解的方法。
- 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
- <?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();
上面的代码会报错
。 加上 bind 第三个参数为
- Fatal error: Uncaught Error: Call to protected method T::who() from context 'Closure'
或者
- 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) "燕睿涛"
- }
另外还有个特别要说明的例子
- <?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
- <?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
- 我是T里面的私有函数:show
- 我是T里面的保护函数:who
- 我是T里面的公共函数:name
这个函数是在看 composer 生成的自动加载源码的时候碰到的,在 composer 中用的比较特别,下面是截取部分 composer 中的代码
- // 文件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
所以,上面这么做是没问题的,还有另外一种形式也可以
- 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 楼,
直到一次我们物理老师来上课,这个老师年龄偏大,是市里面的特级教师(恩,应该没错),正好碰到余震,大家又疯了似得准备往外跑,这个时候老师说了一句话,让我至今
难忘,
,确实,这种小余震挤下去可能更容易发生事故,虽然这句话带了少许的消极,但里面更多的是心态的平静、 心比较大、冷静果断的体现,这是我要学习的。
- 命在骨子里,这种余震没必要这么慌挤下去,命硬的怎么都没事
该出现的总会出现,不该出现的永远不会出现,一味的好高骛远,追求太远的目标容易导致焦虑,当然要不要妄自菲薄,总之一句话:心平气和、心放大、切勿患得患失、
踏踏实实的做好每一件事,越努力、越幸运,越幸运、越努力。
来源: http://www.cnblogs.com/iforever/p/6439852.html