Entrevistador: ¿Conoce la característica principal de las funciones anónimas de PHP? Di algo

presentar

Antes de que aparecieran las funciones anónimas, era necesario nombrar todas las funciones antes de que pudieran usarse

function increment($value)
{
    
    
    return $value + 1;
}

array_map('increment', [1, 2, 3]);

A veces, es posible que la función solo deba usarse una vez. En este momento, el uso de funciones anónimas hará que el código sea más conciso e intuitivo y, al mismo tiempo, evitará que la función se use en otros lugares.

array_map(function($value){
    
    
    return $value + 1;
}, [1, 2, 3]);

Definición y uso

PHP trata los cierres y las funciones anónimas como conceptos equivalentes (denominados colectivamente funciones anónimas en este artículo), que son esencialmente objetos disfrazados de funciones.

La esencia de una función anónima es un objeto, así que al igual que un objeto, una función anónima se puede asignar a una variable

$greet = function(string $name){
    
    
    echo "hello {
      
      $name}";
}

$greet("jack") // hello jack

Todas las funciones anónimas son instancias de objetos de cierre.

$greet instanceof Closure // true

Los objetos no tienen alcance principal, por lo que debe usar use para declarar manualmente las variables utilizadas.

$num = 1;
$func = function() use($num){
    
    
    $num = $num + 1;
    echo $num;
}
$func();  // 2
echo $num;  // 还是 1

Si desea que las variables de la función anónima surtan efecto, debe pasar por valor por referencia

$num = 1;
$func = function() use(&$num){
    
    
    $num = $num + 1;
    echo $num;
}
$func();  // 2
echo $num;  // 2

A partir de PHP 5.4, cuando se usa una función anónima en una clase, el $ this de la función anónima se vinculará automáticamente a la clase actual

class Foo {
    
    
    public function bar()
    {
    
       
        return function() {
    
    
            return $this;
        };
    }
}

$foo = new Foo();
$obj = $foo->bar(); // Closure()
$obj();   // Foo

Si no desea que el enlace automático surta efecto, puede usar funciones anónimas estáticas

class Foo {
    
    
    public function bar()
    {
    
       
        return static function() {
    
    
            return $this;
        };
    }
}
$foo = new Foo();
$obj = $foo->bar(); // Closure()
$obj();   // Using $this when not in object context

La esencia de las funciones anónimas

La esencia de las funciones anónimas es el objeto Closure, incluidos los siguientes cinco métodos

Closure {
    
    
    private __construct ( void )
    public static bind ( Closure $closure , object $newthis [, mixed $newscope = "static" ] ) : Closure
    public bindTo ( object $newthis [, mixed $newscope = "static" ] ) : Closure
    public call ( object $newthis [, mixed $... ] ) : mixed
    public static fromCallable ( callable $callable ) : Closure
}

__construct -Evitar que se creen instancias de funciones anónimas

$closure = new \Closure();
// PHP Error:  Instantiation of 'Closure' is not allowed

Closure::bindTo-Copie el objeto de función anónimo actual, vincule el $ this objeto y el alcance de la clase especificados. En términos sencillos, se trata de vincular manualmente la función anónima al objeto especificado, con lo que se puede ampliar la función del objeto.

// 定义商品类
class Good {
    
    
    private $price;

    public function __construct(float $price)
    {
    
    
        $this->price = $price;
    }
}

// 定义一个匿名函数,计算商品的促销价
$addDiscount = function(float $discount = 0.8){
    
    
    return $this->price * $discount;
}

$good = new Good(100);

// 将匿名函数绑定到 $good 实例,同时指定作用域为 Good
$count = $addDiscount->bindTo($good, Good::class); 
$count(); // 80

// 将匿名函数绑定到 $good 实例,但是不指定作用域,将无法访问 $good 的私有属性
$count = $addDiscount->bindTo($good); 
$count(); // 报错

Closure::bind - bindTo La versión estática del método se puede utilizar de dos formas:

Uso 1: lograr el mismo efecto que el método bindTo

$count = \Closure::bind($addDiscount, $good, Good::class); 

Uso 2: vincule la función anónima a la clase (no al objeto), recuerde establecer el segundo parámetro en nulo

// 商品库存为 10
class Good {
    
    
    static $num = 10;
}

// 每次销售后返回当前库存
$sell = static function() {
    
    
    return"当前库存为". --static::$num ;
};

// 将静态匿名函数绑定到 Good 类中
$sold = \Closure::bind($sell, null, Good::class);

$sold(); // 当前库存为 9
$sold(); // 当前库存为 8

call- PHP 7 nuevas callformas de lograr la vinculación y llamar a la función anónima, además de una sintaxis más concisa, pero también un mayor rendimiento

// call 版本
$addDiscount->call($good, 0.5);  // 绑定并传入参数 0.5,结果为 50

// bindTo 版本
$count = $addDiscount->bindTo($good, Good::class); 
$count(0.5); // 50

fromCallable- callablefunción dada que se transforma en función anónima

class Good {
    
    
    private $price;

    public function __construct(float $price)
    {
    
    
        $this->price = $price;
    }
}

function addDiscount(float $discount = 0.8){
    
    
    return $this->price * $discount;
}

$closure = \Closure::fromCallable('addDiscount');
$good = new Good(100);
$count = $closure->bindTo($good);  
$count = $closure->bindTo($good, Good::class);   // 报错,不能重复绑定作用域
$count(); // 报错,无法访问私有属性

fromCallable Equivalente a

$reflexion = new ReflectionFunction('addDiscount');
$closure = $reflexion->getClosure();

Una cosa a la que se debe prestar especial atención aquí es que si se trata de un cierre convertido de fromCallable o un cierre obtenido mediante reflexión, cuando se usa bindTo, si el segundo parámetro especifica la clase de enlace, se informará un error

Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()

Presta atención, no te pierdas

Muy bien, todos, lo anterior es todo el contenido de este artículo. Las personas que pueden ver aquí son todos talentos . Como dije antes, hay muchos puntos técnicos en PHP, porque hay demasiados, es realmente imposible de escribir, y no leerás demasiado después de escribirlo, así que lo organizaré en PDF y documentos aquí, si es necesario. lata

Haga clic para ingresar el código secreto: PHP + 「Plataforma」

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí


Para obtener más contenido de aprendizaje, visite el excelente catálogo de tutoriales de arquitecto PHP de [Comparative Standard Factory], siempre que pueda leerlo para asegurarse de que el salario aumentará un paso (actualización continua)

El contenido anterior espera poder ayudarte . Muchos PHPers siempre encuentran algunos problemas y cuellos de botella cuando están avanzados. No hay sentido de dirección cuando escriben demasiado código comercial. No sé por dónde empezar a mejorar. He compilado información sobre esto, incluyendo Pero no se limita a: arquitectura distribuida, alta escalabilidad, alto rendimiento, alta concurrencia, ajuste del rendimiento del servidor, TP6, laravel, YII2, Redis, Swoole, Swoft, Kafka, optimización de Mysql, scripts de shell, Docker, microservicios, Nginx, etc. Muchos puntos de conocimiento, productos secos avanzados avanzados, se pueden compartir con todos de forma gratuita, y aquellos que lo necesiten pueden unirse a mi grupo de intercambio de tecnología PHP

Supongo que te gusta

Origin blog.csdn.net/weixin_49163826/article/details/109170089
Recomendado
Clasificación