Class Closure
Classes used to represent anonymous functions.
Anonymous functions (introduced in PHP 5.3) produce objects of this type. In the past, this class was considered an implementation detail, but now it can be relied on to do something. Since PHP 5.4,
This class has methods that allow more control over anonymous functions after they are created.
This class can not be instantiated, there are two main methods, both used to copy closures, a static and a dynamic, the following two methods are explained in detail.
Closure::bind
public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] ) Description of parameters: closure Anonymous functions that need to be bound. newthis Objects that need to be bound to anonymous functions, or NULL creates unbound closures. newscope Class scopes that you want to bind to closures, or'static'means unchanged. If an object is passed in, the type name of the object is used. The class scope is used to determine the $this object in the closure The visibility of private and protective methods. The class scope to which association the closure is to be associated, or'static'to keep the closure 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.
The definition of this method is given above. The first parameter is a closure function, which is well understood. The second parameter is not so well understood. If the closure to be copied contains $this, the object represents this.
The modifications to this object in the closure function will also be consistent after the call ends, such as modifying an attribute; the third parameter is not very easy to understand, and the official instructions are cloudy.
By default, when calling $this - > to access the attribute function in object $newthis, there is a restriction on accessing only the function of the public attribute, if you want to access the protected/private attribute.
To set it to the corresponding class name / class instance, you need to access the protection / private property function of that class as in the class.
Example
<?php class T { private function show() { echo "I am T Private functions inside: show\n"; } protected function who() { echo "I am T The protection function inside: who\n"; } public function name() { echo "I am T Common functions inside: name\n"; } } $test = new T(); $func = Closure::bind(function(){ $this->who(); $this->name(); $this->show(); }, $test); $func();
The above code will report Fatal error: Uncaught Error: Call to protected method T:: who () from context'Closure'. With the third parameter of bind, t::class or new T(), every result will be output normally.
I am the protection function in T: I'm the common function in T: name. I am the private function in T:show.
Of course, closures can also pass parameters
$test = new StdClass(); var_dump($test); $func = Closure::bind(function($obj){ $obj->name = "Yan Lei Tao"; }, null); $func($test); var_dump($test);
The above program, like anonymous functions, does not depend on any object. The above program will output:
object(stdClass)#1 (0) { } object(stdClass)#1 (1) { ["name"]=> string(9) "Yan Lei Tao" }
There is another special example to illustrate.
<?php class T { private function show() { echo "I am T Private functions inside: show\n"; } protected function who() { echo "I am T The protection function inside: who\n"; } public function name() { echo "I am T Common functions inside: name\n"; } } $func = Closure::bind(function ($obj) { $obj->show(); }, null); $test = new T(); $func($test);
What will be output from the above situation? Yes, there will be an error, indicating that private property show can not be accessed. At this time, add a third parameter, and see that the third parameter not only affects the scope of $this.
It can also affect the scope of parameters.
Closure::bindTo
The bindTo and bind functions are similar, but here's just another form, which copies the current closure object and binds the specified $this object and class scope. The first parameter is less than bind.
The latter two are the same, but the difference is that bindTo is not a static method, but an attribute method only exists in closures.
Example
<?php class T { private function show() { echo "I am T Private functions inside: show\n"; } protected function who() { echo "I am T The protection function inside: who\n"; } public function name() { echo "I am T Common functions inside: name\n"; } } $func = function () { $this->show(); $this->who(); $this->name(); }; $funcNew = $func->bindTo(new T(), T::class); $funcNew();
The output of the above function is similar to that of bind
I am the private function in T:show. I am the protection function in T: I'm the common function in T: name.
A trick
This function is encountered when looking at the composer generated auto-loading source code, which is more special in composer. Below is the interception of part of the composer code.
// File autoload_real.php call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer($loader)); // File 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); }
The above code is rather strange. In call_user_func, the first feeling is that the fault parameter is wrong. Otherwise, a function is called here, which returns a Closure object.
It's an anonymous function, and the final parameter passed in is a callable type. Look at the return closure, which uses use as a bridge between closures and external variables.
As for why common parameters can be passed here, because in php5, the object parameters and real parameters point to the same object, and the modification of the object in the function will be reflected outside the object.
So, it's okay to do this above. There's another way to do it.
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); }
summary
I haven't blog ged for a long time. Sometimes I'm too upset to calm down. Sometimes I haven't found anything I want to write. Still have to calm down, do everything well, don't get upset when things happen, enlarge your heart, handle everything calmly.
In the end, I suddenly remembered that when I was in high school, it was just 5.12 Wenchuan Earthquake. We were in Xi'an. After the big earthquake, there would be aftershocks all the time. Once there were aftershocks, everyone panicked. A swarm of people rushed downward. I remember correctly that we were on the 5th floor.
Until one time our physics teacher came to class, the older teacher was a super teacher in the city (well, it should be right), just in time to encounter aftershocks, we were crazy and ready to run outside, at this time, the teacher said a word, let me now.
Unforgettable, life is in the bone, this kind of aftershock need not be squeezed down in such a panic, life is hard how nothing happens, indeed, this kind of small aftershock squeezed down may be more prone to accidents, although this sentence brings a little negative, but there is more peace of mind inside.
This is what I want to learn.
There will always be appearances, and there will never be ones that should not be appearing. It's easy to get anxious when pursuing too far-reaching goals. Of course, don't underestimate yourself. In a word, be calm, magnify your heart, and never suffer from gains and losses.
Do everything steadfastly, the harder, the luckier, the luckier, the harder.