PHP Fermeture et lunette de fermeture


Exemple

Considérons cet exemple:

<?php

$myClosure = function() {
    echo $this->property;
};

class MyClass
{
    public $property;

    public function __construct($propertyValue)
    {
        $this->property = $propertyValue;
    }
}

$myInstance = new MyClass('Hello world!');
$myBoundClosure = $myClosure->bindTo($myInstance);

$myBoundClosure(); // Shows "Hello world!"

Essayez de modifier la visibilité de la property pour qu'elle soit protected ou private . Vous obtenez une erreur fatale indiquant que vous n'avez pas accès à cette propriété. En effet, même si la fermeture a été liée à l'objet, la portée dans laquelle la fermeture est appelée n'est pas celle nécessaire pour avoir cet accès. C'est à cela que sert le second argument de bindTo .

La seule façon d'accéder à une propriété si elle est private est qu'elle est accessible à partir d'une étendue qui le permet, c'est-à-dire. la portée de la classe. Dans l'exemple de code précédent, la portée n'a pas été spécifiée, ce qui signifie que la fermeture a été appelée dans la même portée que celle utilisée lorsque la fermeture a été créée. Changeons cela:

<?php

$myClosure = function() {
    echo $this->property;
};

class MyClass
{
    private $property; // $property is now private

    public function __construct($propertyValue)
    {
        $this->property = $propertyValue;
    }
}

$myInstance = new MyClass('Hello world!');
$myBoundClosure = $myClosure->bindTo($myInstance, MyClass::class);

$myBoundClosure(); // Shows "Hello world!"

Comme nous venons de le dire, si ce second paramètre n'est pas utilisé, la fermeture est appelée dans le même contexte que celui utilisé lors de la création de la fermeture. Par exemple, une fermeture créée à l'intérieur d'une classe de méthode appelée dans un contexte d'objet aura la même portée que celle de la méthode:

<?php

class MyClass
{
    private $property;

    public function __construct($propertyValue)
    {
        $this->property = $propertyValue;
    }

    public function getDisplayer()
      {
        return function() {
              echo $this->property;
        };
      }
}

$myInstance = new MyClass('Hello world!');

$displayer = $myInstance->getDisplayer();
$displayer(); // Shows "Hello world!"