ti-enxame.com

Usando `$ this` em uma função anônima em PHP pré 5.4.0

O manual PHP indica

Não é possível usar $this da função anônima antes de PHP 5.4.0

na página de funções anônimas . Mas eu descobri que posso fazê-lo funcionar atribuindo $this a uma variável e passando a variável para uma instrução use na definição da função.

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

Esta é uma boa prática?
Existe uma maneira melhor de acessar $this dentro de uma função anônima usando PHP 5.3?

85
steampowered

Ele falhará quando você tentar chamar um método protegido ou privado, porque usá-lo dessa maneira conta como chamar de fora. Não há como contornar isso na versão 5.3, tanto quanto eu sei, mas venha PHP 5.4, ele funcionará como esperado, fora da caixa:

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"

Ainda mais, você poderá alterar o que $ this aponta para em tempo de execução, para funções anonymus (religação de fechamento):

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"

Efetivamente, as funções anonymus terão um método bindTo () , onde o primeiro parâmetro pode ser usado para especificar o que $ this aponta, e o segundo parâmetro controla o que deve o nível de visibilidade seja . Se você omitir o segundo parâmetro, a visibilidade será como chamar de "fora", por exemplo. somente propriedades públicas podem ser acessadas. Observe também como o bindTo funciona, ele não modifica a função original; retorna uma nova .

65
K. Norbert

Nem sempre confie em PHP para passar objetos por referência; quando você está atribuindo uma referência em si, o comportamento não é o mesmo que na maioria dos idiomas de [OO _ onde o ponteiro original é modificado .

seu exemplo:

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

deveria estar:

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

OBSERVAÇÃO A REFERÊNCIA "&" e o $ CI devem ser atribuídos após a realização das chamadas finais. Novamente, você pode ter uma saída imprevisível em PHP acessar uma referência nem sempre é o mesmo que acessar a classe original - se isso faz sentido.

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

6
Christof Coetzee

Essa é a maneira normal de fazer isso.
b.t.w, tente remover o &, ele deve funcionar sem isso, pois os objetos passam por ref de qualquer maneira.

5
Itay Moav -Malimovka

Parece bom se você passar por referência é a maneira correta de fazê-lo. Se você estiver usando PHP 5, não precisará do símbolo & antes de $this, pois ele sempre passará por referência, independentemente.

1
fire

Isto é bom. Eu acho que você poderia fazer isso também:

$CI = $this;

... uma vez que atribuições envolvendo objetos sempre copiam referências, não objetos inteiros.

1
halfer