# 匿名函数

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

```php
<?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
<?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
<?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
<?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
<?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
<?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
<?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
<?php

$foo = preg_replace_callback(
    '/^([a-z]*)$/',
    fn(array $matches): string => strtoupper($matches[1]),
    'foo'
);
var_dump($foo); // string(3) "FOO"

```

短闭包可以直接访问闭包函数外部的变量，所以不需要再使用 `use` 关键词。

```php
<?php

$string = 'foo';

/**
 * Return a string.
 *
 * @param  void
 * @return string
 */
$foo = fn(): string => strtoupper($string);
var_dump($foo()); // string(3) "FOO"

```

