The function of the anonymous function is to enlarge the function, and before PHP 5.3, we have only two choices to pass the callback way:
The function name of the string
Using Create_function's return
After PHP5.3, we have one more choice, namely closure.
$func = function () {...};
- Array_walk ($arr, $func);
The first way to implement this is to pass the function name string as the simplest. And the second way create_function, in fact, and the first way essentially the same, Create_function returns the function name of a string, which is the format of the function name:
"\000_lambda_". Count (anonymous_functions) + +
Let's look at the create_function implementation steps:
1. Get the parameter, function body;
2. Piecing together a "function __lambda_func (parameter) {functional body;} "The string;
3. Eval;
4. Through __lambda_func in the function table to find the function of the eval, can not find the error;
5. Define a function name: "\000_lambda_". Count (anonymous_functions) + +;
6. Replace the __lambda_func with the new function name;
7. Returns the new function.
Let's verify the following:
<?php
- Create_function ("", ' echo __function__; ');
- Call_user_func ("\000lambda_1", 1);
- ?>
- Output
- __lambda_fun
Because the function name is "__lambda_func" at Eval, the __lambda_func is output within the anonymous function, and because the last "\000_lambda_". Count (anonymous_functions) + + Renamed the "__lambda_func" function in the function table, so you can pass "\000_lambda_". Count (anonymous_functions) + + calls this anonymous function. To confirm this, you can dump the return value of create_function to view it.
When PHP 5.3 was released, one of the new feature was to support the closure/lambda Function, and my first reaction was to assume that Zval added a is_function, but it actually constructed a closure "class" introduced by PHP 5.3. instance, the constructor for the closure class is private, so it cannot be instantiated directly, and the closure class is the final class, so it cannot be derived as a base class.
php-5.3.0
- $class = new Reflectionclass ("Closure");
- Var_dump ($class->isinternal ());
- Var_dump ($class->isabstract ());
- Var_dump ($class->isfinal ());
- Var_dump ($class->isinterface ());
- Output:
- BOOL (TRUE)
- BOOL (FALSE)
- BOOL (TRUE)
- BOOL (FALSE)
- ?>
In PHP 5.3, the support for closures is simply to keep the external variables as "static attributes" of the closure object (not a normal traversal/access attribute).
php-5.3.0
- $b = "Laruence";
- $func = function ($a) use ($b) {};
- Var_dump ($func);
- /* Output:
- Object (Closure) #1 (2) {
- ["Static"]=>
- Array (1) {
- ["B"]=>
- String (8) "Laruence"
- }
- ["Parameter"]=>
- Array (1) {
- ["$a"]=>
- String (a) "<required>"
- }
- }
- */
This implementation, personally think and JS to the closure of the package, or a bit too shabby.