Estou verificando alguns PHP 5.3.0
recursos e deparei com um código no site que parece bem engraçado:
public function getTotal($tax)
{
$total = 0.00;
$callback =
/* This line here: */
function ($quantity, $product) use ($tax, &$total)
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};
array_walk($this->products, $callback);
return round($total, 2);
}
como um dos exemplos de funções anônimas .
Alguém sabe sobre isso? Alguma documentação? E parece mal, deveria ser usado?
use
palavra-chave também é usada para aliasing namespaces . É incrível que, mais de três anos após o lançamento do PHP 5.3.0, a sintaxefunction ... use
ainda não esteja documentada oficialmente, o que torna o fechamento um recurso não documentado. O documento até confunde funções e fechamentos anônimos . A única documentação (beta e não oficial)use ()
que encontrei no php.net foi a RFC para fechamento .use
também é usado para incluir umtrait
em umclass
!Uma resposta mais simples.
function ($quantity) use ($tax, &$total) { .. };
$tax
dentro do fechamento não tem efeito externo, a menos que seja um ponteiro, como um objeto.&$total
. Dessa forma, modificando o valor de$total
TEM UM efeito externo, o valor da variável original muda.Como o @Mytskine apontou, provavelmente a melhor explicação detalhada é a RFC para fechamentos . (Vote nele por isso.)
fonte
$closure = function ($value) use ($localVar as $alias) { //stuff};
determinado erro é:Parse: syntax error, unexpected 'as' (T_AS), expecting ',' or ')'
&$total
tem um efeito interno. Em outras palavras, se você alterar o valor de$total
fora do fechamento depois que ele for definido, o novo valor somente será passado se for um ponteiro.global
apenas permite o acesso ao espaço para nome global, ao passo queuse
permite acessar variáveis no espaço para nome pai. Variáveis globais são geralmente consideradas más. Acessar o escopo pai geralmente é o próprio objetivo de criar um fechamento. Não é "mau", pois seu escopo é muito limitado. Outras linguagens como JS usam implicitamente as variáveis do escopo pai (como ponteiro, não como valor copiado).You can pass in variables as pointers like in case of &$total. This way, modifying the value of $total DOES HAVE an external effect, the original variable's value changes.
o
function () use () {}
fechamento é semelhante ao PHP.Sem
use
, a função não pode acessar a variável de escopo paiO
use
valor da variável é de quando a função é definida, não quando chamadause
variável por referência com&
fonte
fechamentos são lindos! eles resolvem muitos problemas que vêm com funções anônimas e tornam possíveis códigos realmente elegantes (pelo menos enquanto falamos sobre php).
programadores javascript usam fechamentos o tempo todo, às vezes até sem saber, porque as variáveis vinculadas não são explicitamente definidas - é para isso que serve o "uso" no php.
existem melhores exemplos do mundo real do que o anterior. digamos que você precise classificar uma matriz multidimensional por um subvalor, mas a chave muda.
aviso: código não testado (eu não tenho o php5.3 instalado no atm), mas deve se parecer com algo assim.
há uma desvantagem: muitos desenvolvedores de php podem ficar um pouco impotentes se você os confrontar com fechamentos.
para entender melhor a boa aparência dos fechamentos, darei outro exemplo - desta vez em javascript. um dos problemas é o escopo e a assincronia inerente ao navegador. especialmente, se for
window.setTimeout();
(ou -interval). então, você passa uma função para setTimeout, mas não pode realmente fornecer nenhum parâmetro, porque fornecer parâmetros executa o código!myFunction retorna uma função com um tipo de parâmetro predefinido!
para ser sincero, eu gosto muito mais de php desde 5.3 e funções / fechamentos anônimos. os namespaces podem ser mais importantes, mas são muito menos sexy .
fonte
O Zupa fez um ótimo trabalho explicando fechamentos com 'use' e a diferença entre EarlyBinding e Referencing as variáveis que são 'usadas'.
Então, eu fiz um exemplo de código com ligação antecipada de uma variável (= cópia):
Exemplo com referência a uma variável (observe o caractere '&' antes da variável);
fonte
Até anos muito recentes, o PHP definiu seu interpretador AST e PHP isolou o analisador da parte da avaliação. Durante o tempo em que o fechamento é introduzido, o analisador do PHP é altamente associado à avaliação.
Portanto, quando o fechamento foi introduzido pela primeira vez no PHP, o intérprete não tem método para saber quais variáveis serão usadas no fechamento, porque ele ainda não foi analisado. Portanto, o usuário precisa agradar o mecanismo do zend por importação explícita, fazendo o dever de casa que o zend deve fazer.
Essa é a chamada maneira simples em PHP.
fonte