Até o PHP 8.3, transformar uma propriedade pública em algo com lógica de leitura ou escrita exigia trocá-la por uma propriedade privada mais um par de métodos getFoo()/setFoo() — quebrando toda a API pública da classe. Os property hooks, introduzidos no PHP 8.4, resolvem isso permitindo anexar comportamento diretamente à propriedade, usando os blocos get e set, sem exigir métodos separados nem quebrar quem já usa $objeto->propriedade.
Como funciona
O hook fica declarado junto da propriedade, entre chaves. O hook get é executado em toda leitura (inclusive em isset()), e o set em toda escrita:
class Produto
{
private bool $alterado = false;
public string $nome = '' {
get {
return $this->alterado ? strtoupper($this->nome) : $this->nome;
}
set(string $valor) {
$this->nome = trim($valor);
$this->alterado = true;
}
}
}
$produto = new Produto();
$produto->nome = ' Teclado Mecânico ';
echo $produto->nome; // TECLADO MECÂNICO
Repare que quem usa a classe continua escrevendo $produto->nome normalmente — a diferença toda fica escondida dentro do hook.
Sintaxe curta com arrow function
Quando o hook cabe em uma única expressão, dá para usar a forma curta com =>. No hook set, o valor recebido já vem disponível na variável implícita $value, sem precisar declarar parâmetro:
class Usuario
{
public string $email {
set => strtolower(trim($value));
}
}
$usuario = new Usuario();
$usuario->email = ' JOAO@Exemplo.COM ';
echo $usuario->email; // joao@exemplo.com
Propriedades virtuais (sem armazenamento próprio)
Um hook get não precisa ler um valor guardado — ele pode calcular tudo a partir de outras propriedades. Nesse caso a propriedade é virtual: não ocupa espaço nenhum no objeto, só existe como uma computação:
class Pedido
{
public function __construct(
public readonly float $subtotal,
public readonly float $desconto,
) {}
public float $total {
get => $this->subtotal - $this->desconto;
}
}
$pedido = new Pedido(subtotal: 200.0, desconto: 30.0);
echo $pedido->total; // 170
Tentar atribuir um valor a $pedido->total gera erro, já que não existe hook set declarado para essa propriedade.
Hook parcial: só get ou só set
Não é preciso declarar os dois hooks. Se você define apenas get, a escrita continua funcionando do jeito padrão (respeitando tipo e visibilidade); se define apenas set, a leitura devolve o valor armazenado diretamente:
class Configuracao
{
public array $opcoes = [] {
set(array $valor) {
$this->opcoes = array_filter($valor);
}
}
}
Quando usar
- Validar ou normalizar um valor no momento da escrita (trim, lowercase, faixa de valores) sem trocar a API pública da classe.
- Expor propriedades computadas (totais, propriedades derivadas de outras) como se fossem dados simples.
- Migrar uma propriedade pública existente para ter lógica, sem quebrar código que já faz
$objeto->propriedade. - Declarar hooks em interfaces e classes abstratas, obrigando implementações a fornecer comportamento de leitura/escrita para uma propriedade.
Cuidados
Hooks só podem ser aplicados a propriedades de instância — propriedades static não suportam hooks. Dentro do próprio hook, atribuir à propriedade usando $this->propriedade = ... acessa o armazenamento real (não reentra no hook), o que evita recursão infinita, mas também é uma armadilha comum para quem espera que a atribuição interna também passe pelo set. Hooks também podem ser marcados como final para impedir que uma subclasse os sobrescreva.
Compatibilidade
Property hooks foram introduzidos no PHP 8.4 (lançado em novembro de 2024) e exigem essa versão ou superior — não há como fazer polyfill dessa sintaxe em versões anteriores.
Conclusão
Property hooks eliminam boa parte do boilerplate de getters e setters no PHP, mantendo a sintaxe simples de acesso direto à propriedade enquanto permitem validação, normalização e valores computados por trás dos panos. É uma mudança que aproxima o PHP de linguagens que já tinham esse recurso há tempos, como C# e Kotlin.
0 Comentário
Deixe seu Comentário!