PHP: Interceptar métodos inexistentes (__call)

Palavras-chave: PHP, __call, métodos dinâmicos, orientação a objetos

O PHP tem uma função mágica chamada __call(). Se sua classe declarar um método com este nome, ele será invocado sempre que for feita uma chamada a um método não existente naquela classe.

Esta invocação receberá como parâmetro o nome do método chamado e os argumentos. É um mecanismo tradicional e simples, mas muito poderoso. Já existia no Smalltalk, através da mensagem doesNotUnderstand, que tinha exatamente a mesma semântica.

As aplicações são diversas: interceptação de chamadas, proxying, dynamic dispatching etc. Estas brincadeiras divertidas são muito úteis para a construção de bibliotecas e frameworks dinâmicos, por exemplo, para web ou mapeamento objeto-relacional.

Um exemplo para ilustrar:

class ClasseComTodosOsMetodosDoMundo
{
    public function __call($m, $a)
    {
        echo "Método invocado: $m\n";
    }
}

$o = new ClasseComTodosOsMetodosDoMundo();
$o->umMetodoQualquer();
$o->umMetodoAssimAssado();

Que vai ter a saída:

Método invocado: umMetodoQualquer
Método invocado: umMetodoAssimAssado
This entry was posted in PHP. Bookmark the permalink.

6 Responses to PHP: Interceptar métodos inexistentes (__call)

  1. Pingback: rascunho » Blog Archive » links for 2007-09-29

  2. Rael says:

    A única coisa que conta “contra” isso é o fato dos editores como Zend e PDT não terem como “auto-completar” ou listar os métodos existentes.

  3. Victor says:

    É o mesmo que o method_missing de Ruby. :-)

  4. Ana says:

    No te voy a poder contestar en portugues y he de decir que tu nivel de español es realmente bueno..! Tampoco te hablaré de Java.. pero te mando un beso desde Bilbao, hasta siempre pecoso!
    Ana

  5. Complementando, no PHP 5.3 foi implementado o método __callStatic, para quando for chamado um método de forma estática não-declarado, chame esta função:

    $obj->funcaoInexistente(); // chama o __call
    ObjetoSobrecarregado::funcaoInexistente(); // chama o __callStatic

Leave a Reply

Your email address will not be published. Required fields are marked *