NoteDeep
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数参数的值。当然,也有其它应用的情况。
匿名函数目前是通过 Closure 类来实现的。

php的闭包不会像js那样自动封装应用的状态,而是需要手动bindTo() 或者 use,把你需要的变量或值存到闭包里面。

例:把匿名函数放到变量里,然后调用。
<?php $greet = function($name) { printf("Hello %s\r\n", $name); };
$greet('World'); ?>

例:把匿名函数放到数组里,随机调用
// Store 3 anonymous functions in an array
$luckyDip = array(
function() {
echo "You got a bag of toffees!";
},
function() {
echo "You got a toy car!";
},
function() {
echo "You got some balloons!";
}
);
// Call a random function
$choice = rand( 0, 2 );
$luckyDip[$choice]();

使用匿名函数作为回调

许多内置的PHP函数接受回调。

比如,在工作中经常有一个场景:改变数组中每一个元素的内容,这时可以用array_map + 匿名函数的方式解决。
$names = array( "fred", "mary", "sally" );
// Map an anonymous callback function to elements in an array.
print_r ( array_map( function( $name ) {
return "Hello " . ucfirst( $name ) . "!";
}, $names ) );

// Array ( [0] => Hello Fred! [1] => Hello Mary! [2] => Hello Sally! )


通过usort + 匿名函数,对二维数组排序
usort: 匿名函数返回-1表示,把b往后拿。返回1表示,把b往前拿。
$people = array(
array( "name" => "Fred", "age" => 39 ),
array( "name" => "Sally", "age" => 23 ),
array( "name" => "Mary", "age" => 46 )
);
usort( $people, function( $personA, $personB ) {
return ( $personA["age"] < $personB["age"] ) ? -1 : 1;
} );
print_r( $people );

//Array (
// [0] => Array ( [name] => Sally [age] => 23 )
// [1] => Array ( [name] => Fred [age] => 39 )
// [2] => Array ( [name] => Mary [age] => 46 )
//)


用匿名函数创建闭包

匿名函数的另一个常见用途是创建闭包。闭包是一个函数,它保留对其封闭范围内变量的访问权限。
function getGreetingFunction() {
$timeOfDay = "morning";
return ( function( $name ) use ( &$timeOfDay ) {
$timeOfDay = ucfirst( $timeOfDay );
return ( "Good $timeOfDay, $name!" );
} );
};
$greetingFunction = getGreetingFunction();
echo $greetingFunction( "Fred" ); // Displays "Good Morning, Fred!"


另一个例子
$people = array(
array( "name" => "Fred", "age" => 39 ),
array( "name" => "Sally", "age" => 23 ),
array( "name" => "Mary", "age" => 46 )
);
function getSortFunction( $sortKey ) {
return function( $personA, $personB ) use ( $sortKey ) {
return ( $personA[$sortKey] < $personB[$sortKey] ) ? -1 : 1;
};
}
echo "Sorted by name:<br><br>";
usort( $people, getSortFunction( "name" ) );
print_r( $people );
echo "<br>";
echo "Sorted by age:<br><br>";
usort( $people, getSortFunction( "age" ) );
print_r( $people );
echo "<br>";




通过闭包的bindTo方法,可以把对象内部的$this绑定到其他对象上(App对象),第二个参数也很重要,指定了绑定闭包的那个对象所属的类,因此闭包可以访问到 APP对象的私有属性
<?php class App { private $name; protected $routes; public function addRoute($path, $callback) { $this->routes[$path] = $callback->bindTo($this, __CLASS__); } public function dispatch($path) { if (isset($this->routes[$path])) { $callback = $this->routes[$path]; $callback(); } } public function getName() { return $this->name; } } $app = new App(); $app->addRoute('index', function (){ $this->name = 'index'; }); $app->dispatch('index'); echo $app->getName();


评论列表

    使用匿名函数作为回调
    用匿名函数创建闭包