Property Hooks no PHP 8.4

RMAG news

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

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();

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();

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

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.

Leave a Reply

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