OOP no PHP: Overloading, utilizando os métodos mágicos do PHP
por Tobias em 16.04.2009 04:56 Desenvolvimento web, Geral, Internet, OOP, php
E aeeeeew blz? Bom gente voltando do período de preguiça bagarai, vício em jogos online e outras vagabundagens ociosidade vamos dar continuidade a série de artigos sobre OOP no PHP. O assunto de hoje é bem interessante, no post de hoje vamos ver como usar um dos métodos mágicos do php.
Neste artigo vou falar do método mágico __call(), que funciona da seguinte maneira:
Quando uma classe tem o método __call() o php roda esse método sempre que qualquer método da classe for chamado, mesmo se o método que foi chamado não existir um método inexistente ou inacessível for chamado (obrigado Edgar pelo puxão de orelha), isso abre espaço para algumas coisas interessantes.
Vamos a um exemplo do funcionamento de __call():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php class ExemploCall { function __call($m, $a) { print "Método chamado: $m\n"; print "Parametros: \n"; var_dump($a); return $this->x; } } $call = new ExemploCall(); $call->test(1,2,'teste'); //Mostra na tela /* Método chamado: test Parametros: array(3) { [0]=> int(1) [1]=> int(2) [2]=> string(5) "teste" } */ ?> |
O exemplo acima simplesmente exibe na tela o método chamado e os parametros enviados, mas vendo isso a pergunta que surge na cabeça é, pra que ou onde eu vou usar o método __call()?
A resposta pra essa pergunta vai da sua criatividade mas eu vou postar aqui uma forma de uso que o cakephp usava há algum tempo atrás.
Funcionava da seguinte forma, havia um método padrão chamado find que era chamado e fazia consultas ao banco de acordo com os parametros passados, porém, (aqui que vem a mágica) ele também podia ser chamado como findByNomeDoCampo o que em alguns momentos facilitava bastante a vida do programador, vamos fazer algo parecido com isso.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | <?php /** Só vou postar o código relevante aos métodos mágicos, mas supõe-se que deste ponto em diante você já tem incluido no arquivo toda a rotina de conexão com o banco de dados, etc, etc, etc... **/ class Model { public function __construct() { //O conteúdo deste método vai variar de acordo com sua classe } public function __call($method, $params) { // Verifica se o método chamado existe nessa classe if ( method_exists($this,$method) ) { //Caso exista chama o método return call_user_method($method, $this, $params); } else { //Caso não exista, chama um método especial que fará a nossa mágica $this->parseMethods($method,$params); } } private function parseMethods($method,$params) { //Verifica se o método segue o padrão adotado if ( eregi('findBy',$method) === false ) { //Caso não siga dispara um erro dizendo que o método é inválido/não encontrado trigger_error('Método inválido ou inexistente',E_USER_ERROR); die; } else { //Caso seja um método padronizado (findByAlgo) recupera o nome do campo e converte tudo para minúsculo $fieldName = strtolower(str_ireplace('findBy','',$method)); //Formata os parametros para serem passados ao método find padrão $options = $params['1']; $options['conditions'] = array($fieldName=>$params['0']); //Chama o método find original $this->find($options); } } public function find($options) { var_dump($options); //Aqui você faria a consulta usando as informações recebidas } } //Instancia a classe $model = new Model(); //Define parametros a serem passados $options = array ( 'fields' => array ('*') ,'order' => array ('nome ASC') ); //Chama o método mágico // Onde o primeiro parametro é o valor que o campo passado no nome do método deve ter. $model->findByBlog('Technócio',$options); /** O que chega no método options é: array(3) { ["fields"] => array(1) { [0]=> string(1) "*" } ["order"] => array(1) { [0]=> string(8) "nome ASC" } ["conditions"] => array(1) { ["blog"]=> string(9) "Technócio" } } **/ ?> |
O código ta bem comentado e bem simples também, embora não tenha me aprofundado muito no assunto acho que deu pra ter uma noção dessa possibilidade e do que pode ser feito com isso.
Como sempre, para dúvidas, sugestões e puxões de orelha, utilizem os comentários. Até a próxima (que dessa vez não vai ser tão demorada assim).
Tags: call, Desenvolvimento web, metodos magicos, OOP, php, php5, __call


17.04.09 10:55 at 10:55
Bom artigo.
Só uma correção: O método __call não intercepta sempre todos os métodos.
Ele intercepta apenas os métodos inexistentes ou inacessíveis (private e protected)
Abraços
22.04.09 18:23 at 06:23
Valeu Edgar, obrigado pelo puxão de orelha, refiz uns testes aqui e percebi que realmente __call só intercepta métodos inexistentes ou inacessíveis, o post já foi corrigido.
25.04.09 15:18 at 03:18
Fala xará! Muito bom o artigo! Esses métodos são muito legais, especialmente os que dão get e set de graça!
28.04.09 16:56 at 04:56
Opá, e ae Danilo blz, é eu não falei sobre os outros métodos pra não ficar um post muito extenso, mas eu to pensando em falar sobre isso nos próximos posts.