DEV Community

William Martins 🇧🇷
William Martins 🇧🇷

Posted on

2

Property Hooks no PHP 8.4

Property Hooks

Os property hooks são funções que controlam como uma propriedade é setada ou como seu valor é lido. Esta funcionalidade é comum em linguagens orientadas a objeto, mas, até então, o PHP não oferecia suporte nativo. Tradicionalmente, a alternativa era recorrer a funções getter/setter ou fazer uso de métodos mágicos. Contudo, por 35 votos a 1, a RFC dos property hooks foi aprovada para a próxima versão do PHP. Este artigo explora as abordagens atuais e como os property hooks podem nos ajudar na validação dos dados.

Getter e Setter

Nesta abordagem, definimos a propriedade email como privada e a só pode ser acessada através da função getEmail/setEmail. Como queremos validar o email, incluímos essa validação no set.

class User
{
    private string $email;

    public function getEmail(): string
    {
        return $this->email;
    }

    public function setEmail(string $email): void
    {
        if (! filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new Exception('Invalid email');
        }
        $this->email = $email;
    }
}

$user = new User();
$user->setEmail('valido@hotmail.com');
echo $user->getEmail(); //valido@hotmail.com
Enter fullscreen mode Exit fullscreen mode

Essa abordagem é bastante comum, mas é muito verbosa e não funciona bem quando trabalhamos com algum ORM.

Propriedades mágicas

Aqui quem não tá acostumado com a ideia dos métodos mágicos do PHP fica maluco.

A ideia é que sempre que uma propriedade for acessada, vai chamar o método __get e passar o nome da propriedade como parâmetro.
Quando for definir alguma propriedade o método __set é executado, passando o nome da propriedade e o valor.

Não preciso dizer que é fácil ficar confuso quando temos muitas prioridades já que uma única função lida com todas as propriedades da classe.

class User
{
    private string $properties = [];

    public function __get($property)
    {
        return $this->properties[$property] ?? null
    }

    public function __set($property, $value)
    {
        switch ($property) {
            case 'email':
                if (! filter_var($value, FILTER_VALIDATE_EMAIL)) {
                    throw new Exception('Email inválido');
                }
                $this->properties['email'] = $value;
                break;
            case 'name':
                $this->properties['name'] = $value;
                break;
        }
    }
}
//

$user = new User();
$user->name = 'John Doe';
$user->email = 'invalido'; //Exception: Email inválido
echo $user->getEmail();
Enter fullscreen mode Exit fullscreen mode

Normalmente essa é a solução adotadas por ORMs, porque as propriedades não precisam de fato existirem no objeto e tudo é passado para os métodos mágicos.

property hooks

Com a chegada do properties hooks, a definição de como uma propriedade vai ser acessada fica no local da declaração da propriedade, separando melhor as responsabilidades e adotando uma abordagem um pouco mais declarativa.

Exemplo de set

class User
{
    public string $name;
    public string $email {
         set {
            if (! filter_var($value, FILTER_VALIDATE_EMAIL)) {
                throw new Exception('Email inválido');
            }
            $this->_email = $value;
        }
    }
}
//

$user = new User();
$user->name = 'John Doe';
$user->email = 'invalid'; //Exception: Email inválido
echo $user->getEmail();
Enter fullscreen mode Exit fullscreen mode

Exemplo de get

class User
{

    public string $fullName {
        get {
            return "$this->firstName $this->lastName";
        }
    }

    public function __construct(private readonly string $firstName, private readonly string $lastName)
    {
    }


}
//

$user = new User("Roberto", "Murari");
echo $user->fullName; //Roberto Murari
Enter fullscreen mode Exit fullscreen mode

Conclusão

Os property hooks prometem transformar a forma como gerenciamos e acessamos propriedades em classes PHP, oferecendo uma sintaxe mais limpa e um controle mais fino. Não vem como substituição aos métodos mágicos ou uso de funções getter/setter mas uma nova alternativa que podemos utilizar onde fizer mais sentido.

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay