匿名函数
匿名函数,也叫闭包函数,允许临时创建一个没有指定名称的函数。最经常用作回调函数参数的值。当然,也有其它应用的情况。匿名函数目前是通过 Closure
类来实现的。
<?php
$foo = preg_replace_callback(
'/^([a-z]*)$/',
function (array $matches): string {
return strtoupper($matches[1]);
},
'foo'
);
var_dump($foo); // string(3) "FOO"
闭包函数也可以作为变量的值来使用。 PHP 会自动把此种表达式转换成内置类 Closure
的对象实例。把一个 Closure
对象赋值给一个变量的方式与普通变量赋值的语法是一样的。
<?php
/**
* Return a string.
*
* @param string $string
* @return string
*/
$foo = function (string $string): string {
return strtoupper($string);
};
var_dump($foo('foo')); // string(3) "FOO"
闭包函数可以从父作用域中继承变量, 任何此类变量都应该用 use
语言结构传递进去。
<?php
$string = 'foo';
/**
* Inherit variables from the parent scope.
*
* @param void
* @return string
*/
$foo = function () use ($string): string {
return $string;
};
var_dump($foo()); // string(3) "foo"
从父作用域中继承的变量的值取决于闭包函数被定义的时候,而不是被调用的时候。
<?php
$string = 'foo';
/**
* Inherit variables from the parent scope.
*
* @param void
* @return string
*/
$foo = function () use ($string): string {
return $string;
};
$string = 'bar';
var_dump($foo()); // string(3) "foo"
闭包函数也可以从父作用域中继承变量的引用。
<?php
$string = 'foo';
/**
* Inherit references from the parent scope.
*
* @param void
* @return string
*/
$foo = function () use (&$string): string {
return $string;
};
$string = 'bar';
var_dump($foo($string)); // string(3) "bar"
在类的上下文中声明时,当前类自动绑定到它,使得在函数范围内可以使用 $this
。
<?php
class Foo
{
/**
* Return an anonymous function.
*
* @param void
* @return Closure
*/
public function method(): Closure
{
/**
* Automatic binding of $this.
*
* @param void
* @return Foo
*/
return function (): Foo {
return $this;
};
}
}
$foo = new Foo();
$method = $foo->method();
var_dump($method()); // object(Foo)#1 (0) { }
如果不需要当前类的自动绑定,则可以使用静态匿名函数。
<?php
class Foo
{
/**
* Return an anonymous function.
*
* @param void
* @return Closure
*/
public function method(): Closure
{
/**
* Try to automatic binding of $this.
*
* @param void
* @return Foo
*/
return static function (): Foo {
return $this;
};
}
}
$foo = new Foo();
$method = $foo->method();
var_dump($method()); // PHP Fatal error: Uncaught Error: Using $this when not in object context.
PHP 还支持短闭包来实现更简洁的单行书写。
<?php
$foo = preg_replace_callback(
'/^([a-z]*)$/',
fn(array $matches): string => strtoupper($matches[1]),
'foo'
);
var_dump($foo); // string(3) "FOO"
短闭包可以直接访问闭包函数外部的变量,所以不需要再使用 use
关键词。
<?php
$string = 'foo';
/**
* Return a string.
*
* @param void
* @return string
*/
$foo = fn(): string => strtoupper($string);
var_dump($foo()); // string(3) "FOO"