匿名函数

匿名函数,也叫闭包函数,允许临时创建一个没有指定名称的函数。最经常用作回调函数参数的值。当然,也有其它应用的情况。匿名函数目前是通过 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"

results matching ""

    No results matching ""