+2

PHP 5.3 parte 3: Lambda e Closures

criado por Douglas V. Pasqua em 05/01/2010 2:14pm
Método __invoke

Foi adicionado no php5.3 um método mágico chamado __invoke, utilizado em classes, que permite que o objeto seja chamado como se fosse uma função, ou closure. Segue o exemplo:

<?php
class DebugAll {
   
public function __invoke($var) {
     var_dump
($var);
   
}
}

$obj1
= new DebugAll;
$obj1
(50);
$obj1
(100);

A saída do script anterior será:

int(50)
int(100)

Comentários:

Mostrando 1 - 3 de 3 comentários
Respondendo a questão: Afinal, onde este método seria útil ?

O método __invoke pode ser usado para que uma classe se comporte como um closure. Imagino que a principal utilidade do closure seria em funções que aceitam callback como parâmetro. Funções como array_map, usort, etc.

Vamos supor que você queira criar diversas funções de comparação para utilizar em uma rotina de ordenação, como usort. Você pode criar diversas classes implementando o método __invoke e passar as instâncias dessas classes como parâmetro para a função usort.

Veja o exemplo abaixo para entender melhor:

<?php

class testeInvoke {
       
public function __invoke($a, $b) {
               
return(strcmp($a, $b));
       
}
}

$o
= new testeInvoke();
$array
= array ("Ziraldo", "Luiz", "Joao", "Rodrigo", "Alberto");

usort
($array, $o);
var_dump
($array);

Criamos uma classe testeInvoke implementando o método mágico __invoke e passamos a sua instância para a função usort ordernar o array.

O resultado do script anterior:

# php invoke.php
array
(5) {
 
[0]=>
 
string(7) "Alberto"
 
[1]=>
 
string(4) "Joao"
 
[2]=>
 
string(4) "Luiz"
 
[3]=>
 
string(7) "Rodrigo"
 
[4]=>
 
string(7) "Ziraldo"
}
06/01/2010 6:05pm (~15 anos atrás)

Aliás, o __invoke só é chamado quando a instância é invocada com os parênteses né? Acho que o primeiro exemplo do "$validacao = validacao()" nem funcionaria...
05/01/2010 9:40pm (~15 anos atrás)

Estive pensando: será que seria uma boa usar o __invoke para retornar a instância de uma classe singleton?

Algo assim:
$validacao = validacao::getInstance();

Ficaria apenas assim:
$validacao = validacao();

Não sei se isso tornaria o código menos intuitivo, já que "getInstance" é consagrado.

Mas se formos parar pra pensar: sempre que se usar o __invoke perderemos um pouco da legibilidade, afinal, estaremos omitindo o nome de um método. Afinal, onde este método seria útil?

Quem sabe para métodos que retornam objetos...
// Obtendo um usuario
$usuario
= $alguma_coisa->usuario;

// Obtendo um usuario com codigo 1
$usuario
= $alguma_coisa->usuario(3);

Enfim, as vezes o PHP tras umas coisas que nos faz pensar nas novas possibilidades...
05/01/2010 9:35pm (~15 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)