Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Magic Methods, __set e __get, deve usá-los ao invés de criarmos funções novas?

No curso de PHP OO foi apresentado os magic methods e o link para a documentação do PHP, verifiquei que tinha o set e o get, por quê não usá-los como métodos getters e setters?

5 respostas

Olá, Maxranderson.

O problema de utilizar o __set e o __get como getters e setters, é a perda do controle fino sobre cada propriedade. Se TODOS os atributos de uma classe minha vão ser acessados de alguma forma, costumo fazer assim:

    public function __get($propriedade)
    {
        $metodo = 'get' . ucfirst($propriedade);
        if (method_exists($this, $metodo))
            return $this->$metodo();
        if (property_exists($this, $propriedade))
            return $this->$propriedade;

        throw new \Exception("Propriedade $propriedade não encontrada");
    }

Assim, caso exista um método getter definido para a propriedade em questão, retorno ele. Caso contrário, retorno a propriedade, pois significa que não preciso de nenhum controle extra.

Desta forma, posso acessar os atributos desta forma:

$obj->propriedade;

ao invés de

$obj->getPropriedade();

Mas, se nem todos os atributos serão acessíveis, isso cria um problema.

Espero ter esclarecido um pouco.

Abraços e bons estudos.

Não entendi muito bem sobre o controle fino que falou. Fiz um teste aqui do get e set, a diferença entre criar uma função e eles, não é o uso do $object->propriedade ao invés de $object->getProdriedade()?? E como seria o problema se nem todos os atributos serem acessíveis? Se eu não quiser que seja acessível, é só colocar a propriedade como private e não criar o método get e/ou set, não é isso?

Então, Maxranderson.

Se você tiver o método __get implementado desta forma, todos os atributos serão acessíveis. Caso não queira isso, como você disse, não poderá utilizar este recurso.

Quanto ao controle fino, é caso você queira tratar algum dado antes de retornar, por exemplo. Um exemplo simples seria se você quisesse que um nome sempre tivesse as letras iniciais maiúsculas:


public function getNome()
{
    return ucwords($this->nome);
}

Com o exemplo que eu te passei esse tipo de controle continua sendo possível, entendeu?

Acho que agora entendi!!! Pensei que se você colocasse a propriedade dentro do get, por exemplo, get($nome), você estaria fazendo a mesma coisa do getNome(), porque achei muito estranho na implementação do __get, por exemplo:

public function __get($nome) {
    return $this->nome;
    }

Pensei que o parâmetro passado no get era a propriedade que você deseja utilizar, e que você poderia fazer um get e __set para cada propriedade, fazendo uma sobrecarga desse método como foi dito na documentação.

solução!

Não não.

Você consegue criar apenas um método __get e um __set, e não um para cada propriedade.

Sempre que você tentar acessar uma propriedade inacessível ou inexistente de uma classe, o método __get vai ser chamado. E sempre que você tentar atribuir um valor a uma propriedade inacessível ou inexistente, o método __set será chamado.

:-)