91 votes

En utilisant $this en fonction anonyme

Le manuel PHP unis

Il n'est pas possible d'utiliser $this de fonction anonyme avant de PHP 5.4.0

sur les fonctions anonymes de la page. Mais j'ai trouvé que je peux le faire fonctionner par l'affectation de $à une référence et le dépassement de la référence à un use déclaration à la définition de la fonction.

$CI = $this;
$callback = function () use ($CI) {
    $CI->public_method();
};

Est-ce une bonne pratique, et est-il un meilleur moyen d'accéder à $ce à l'intérieur d'une fonction anonyme à l'aide de PHP 5.3?

Edit: Supprimé les assigner par ref caractère & depuis les objets sont affectés par ref par défaut dans PHP. $CI = &$this devient $CI = $this

70voto

K. Norbert Points 4797

Il échoue lorsque vous essayez d'appeler un protégé ou privé de la méthode sur elle, parce qu'en l'utilisant de cette façon compte que l'appel de l'extérieur. Il n'y a aucun moyen de contourner cela en 5.3 autant que je sache, mais viennent de PHP 5.4, il fonctionnera comme prévu, la sortie de la boîte:

class Hello {

    private $message = "Hello world\n";

    public function createClosure() {
        return function() {
            echo $this->message;
        };
    }

}
$hello = new Hello();
$helloPrinter = $hello->createClosure();
$helloPrinter(); // outputs "Hello world"

Même plus, vous serez en mesure de changer ce que $this points au moment de l'exécution, pour anonymus fonctions (fermeture de la reliaison):

class Hello {

    private $message = "Hello world\n";

    public function createClosure() {
        return function() {
            echo $this->message;
        };
    }

}

class Bye {

    private $message = "Bye world\n";

}

$hello = new Hello();
$helloPrinter = $hello->createClosure();

$bye = new Bye();
$byePrinter = $helloPrinter->bindTo($bye, $bye);
$byePrinter(); // outputs "Bye world"

Effectivement, anonymus fonctions auront un bindTo() la méthode, où le premier paramètre peut être utilisé pour spécifier ce que $cette points de, et le second paramètre contrôles de quel devrait être le niveau de visibilité de l'être. Si vous omettez le deuxième paramètre, la visibilité sera semblable à l'appel de "l'extérieur", par exemple. seul le public peut accéder aux propriétés. Aussi prenez note de la façon bindTo œuvres, elle ne modifie pas la fonction d'origine, elle renvoie un nouveau.

11voto

Ne pas toujours compter sur PHP pour passer des objets par référence, lors de l'affectation d'une référence lui-même, le comportement n'est pas le même que dans la plupart des langages à objets lorsque le pointeur est modifié.

votre exemple:

$CI = $this;
$callback = function () use ($CI) {
$CI->public_method();
};

devrait être:

$CI = $this;
$callback = function () use (&$CI) {
$CI->public_method();
};

NOTEZ LA RÉFÉRENCE " et "" et " $CI doit être attribué après la dernière demande a été fait, encore une fois d'autre, vous pourriez avoir des conséquences imprévisibles sur la sortie, en PHP accéder à une référence n'est pas toujours le même que l'accès à la classe d'origine - si cela fait sens.

http://php.net/manual/en/language.references.pass.php

7voto

Itay Moav -Malimovka Points 17977

C'est la façon normale, il a été fait.
b.t.w, essayez de supprimer l' & il devrait fonctionner sans cela, que les objets passent par réf toute façon.

1voto

fire Points 9036

Qui semble bien, si votre passage par référence, c'est la façon correcte de le faire. Si votre utilisation de PHP 5, vous n'avez pas besoin de l' & symbole avant d' $this comme il le fera toujours passer par référence, peu importe.

1voto

halfer Points 8455

C'est très bien. Je pense que vous pouvez le faire aussi:

$CI = $this;

... depuis des allocations impliquant des objets sera toujours copier les références, et non l'ensemble des objets.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X