Métodos mágicos com PHP – Parte I | About(code)
Os métodos mágicos
O PHP nos oferece vários métodos mágicos que tendem a simplificar a maneira que desenvolvemos, alguns desses métodos acabam sendo mais utilizados, outros acabam caindo no esquecimento, e poucas vezes são lembrados.
Vou tentar abordar nesta série todos esses métodos, explicar seu funcionamento através de exemplos práticos que farão com que você compreenda o verdadeiro poder desses métodos e faça com que você passe a utiliza-los com mais frequência em seus projetos.
__set() e __get()
O __set() e __get() tem seu propósito explícito em seus nomes, e servem para facilitar a nossa vida, quando desejamos acessar propriedades privadas ou protegidas dentro de uma classe, sem a necessidade de implementar uma função para cada uma dessas propriedades.
__set() é executado ao se escrever dados para membros inacessíveis.
__get() é utilizados para ler dados de membros inacessíveis.
Vamos tentar colocar as coisas de uma forma mais visível; Observe o código abaixo:
Repare no código acima, que possuímos duas propriedades privadas ($name e $age), obviamente estas não podem ser acessadas diretamente através da instância da classe, por este motivo criamos funções que alteram e resgatam seus valores.
Deixe-me apenas exemplificar a utilização da classe acima, supostamente contida no arquivo human.class.php:
@require_once 'human.class.php';
$human->setName('Ricardo');
$human->setAge(28);
echo 'This human named '.$this->getName().' has '.$this->getAge().' years old.';
Agora, vamos ver como ficaria o mesmo exemplo, caso utilizássemos os métodos mágicos __set() e __get().
public static function __set($name, $value) {
public static function __get($name) {
Agora nossa classe está usando os métodos mágicos, repare como conseguimos reduzir algumas linhas e já deixamos nosso código bem mais compreensível. Mas para entender melhor, vamos utilizar essa nova classe:
$human::name = 'Ricardo';
$human::age = 28;
echo 'This human named '.$human::name.' has '.$human::age.' years old.';
Conseguiram perceber a melhora na legibilidade do nosso código? Mas até aí muita gente pode acabar se perguntando se esta é a única vantagem de utilizar esses métodos. Claro, que em projetos pequenos, a questão de desempenho é sempre menos evidente, porém quando trabalhamos com projetos de grande porte, algumas pessoas podem dizer que métodos mágicos deixam suas aplicações um pouco mais lentas. Isso é relativo, eu até hoje não achei nenhum benchmarking atual sobre o assunto, porém talvez mais confiável que encontrei foi escrito em 2007 por Larry Garfield e está disponível aqui, mas de lá pra cá muita coisa mudou. Tire você suas próprias conclusões.
Espero que tenham gostado, dúvidas/observações/correções deixem comentários.
Estou tendo pouco tempo para postar devido a inúmeros projetos que acabem surgindo no ultimo mês, os quais ainda estou desenvolvendo. Conforme tiver tempo volto a postar, de forma intercalada as publicações sobre Padrões de projetos e métodos mágicos do PHP.
Muito bom o post, parabéns, espero que continue postando.
Muito obrigado, Alair.
Está faltando um pouco de tempo para continuar as postagens, algumas só faltam revisar.
http://www.facebook.com/profile.php?id=100002493356671 Tiago Souza Ribeiro
Ótimo post, aguardo pelos próximos sobre o assunto 😀
Ah, uma coisa: os métodos _set() e _get() devem ser sempre estáticos como no seu código? E por que ao acessar as propriedades você as tratou como estáticas se lá na classe não tinha nenhum static?Obrigado, até mais.
http://www.luders.com.br/ Ricardo Lüders
Não há necessidade de ser estático, desde que seja público.
Repare que mesmo sem eu definir os métodos __set e __get só é útil para definir o local de armazenamento das propriedades de um objeto e de alguma forma manipular os dados na hora de inserir ou recupera-los, pois por padrão é possível atribuir ou resgatar uma propriedade pública de um objeto sem a necessidade de declarar tais métodos.
nome = 'Ricardo';
// Imprime: Meu nome é Ricardo!
echo 'Meu nome é ', $registrador->nome;
Repare que no exemplo acima eu apenas atribuir a propriedade nome ao objeto e posteriormente resgatei o valor armazenado.
Porém, se abaixo do mesmo código eu listar as propriedades e valores do objeto, você verá que 'nome' é uma propriedade do objeto.
// Imprime: Array ( [nome] => Ricardo )
echo print_r(get_object_vars($registrador), true);
Faça alguns testes, atribua vários valores e utilize o comando acima para ver quantas propriedades seu objetos terá.
Agora vamos fazer a mesma coisa porém usando métodos mágicos. Vamos melhorar nossa classe:
class Registrador
public function __set($i, $v)
$this->data[$i] = $v;
public function __get($i)
Agora verifique como está a listagem de propriedades do seu objeto.
Repare que o resultado da listagem será uma array vazia, sabe o motivo?
É simples, altere o encapsulamento da array $data para public e tente novamente.
Descobriu o motivo? Legal, né? Antes não era listado pois seus dados estavam 'protegidos' dentro do objetos e só poderiam ser lidos através de um método publico da própria classe.
Bom, acho que é mais ou menos isso…
Faça alguns testes, não tenha medo de brincar, você sempre vai descobrir coisas novas sobre o PHP, afinal é uma linguagem repleta de truques e funções para fazer praticamente tudo.
Ótimo tópico gostei ajudou bastante… eu procurei isto em tudo que é site e não encontrava, mas aqui eu encontrei (y)
Pode ser usada assim também:
assim você pode adicionar infinitos atributos atributos.
$human->cabelo = "";
$human->olho = "";
$human->sexo= "";
$human->orientacaoSexual= "";
$human->tamanho= "";
$human->signo= "";
e pra resgatar é só usar echo $human->cabelo;
Pode sim cara, sem problema algum. O importante é o conceito. Se você olhar nos comentários ali para baixo, eu já fiz este exemplo. 🙂