PHP POO Intermediário
Visibilidade e readonly
Em PHP, visibilidade controla quem pode acessar propriedades e métodos de uma classe. Temos public (todos acessam), protected (a própria classe e suas subclasses) e private (somente a própria classe). Escolher a visibilidade correta é o primeiro passo para encapsular bem um objeto.
Desde o PHP 8.1, o modificador readonly permite declarar propriedades que só podem ser inicializadas uma vez, normalmente no construtor. Isso elimina setters desnecessários e torna o objeto imutável depois de criado, evitando bugs causados por alterações inesperadas de estado.
No PHP 8.2 surgiram as readonly classes: ao marcar readonly class, todas as propriedades da classe ganham automaticamente o modificador readonly. Isso é útil para classes de valor (Value Objects), como Dinheiro, CPF ou Coordenada.
A combinação de visibilidade restritiva com readonly é a base da imutabilidade em PHP: os dados são definidos uma única vez e não podem mais ser alterados, o que simplifica o raciocínio sobre o código e facilita testes.
Pontos-chave
publicé acessível de qualquer lugar;protectedsó de dentro da classe e subclasses;privateapenas da própria classe.- Propriedades
readonlysó podem ser atribuídas uma vez, geralmente no construtor. readonly classaplicareadonlya todas as propriedades da classe de uma só vez.- Objetos imutáveis são mais seguros, previsíveis e fáceis de testar.
- Tentar alterar uma propriedade
readonlyjá inicializada lançaError.
<?php
declare(strict_types=1);
// readonly class: todas as propriedades são readonly automaticamente
readonly class Conta
{
public function __construct(
private string $titular,
private float $saldoInicial,
) {}
// Método público expõe o titular, mas não permite alterá-lo
public function titular(): string
{
return $this->titular;
}
// protected: só subclasses podem ver o saldo bruto
protected function saldoBruto(): float
{
return $this->saldoInicial;
}
// Retorna uma NOVA instância em vez de mutar a atual
public function depositar(float $valor): self
{
return new self($this->titular, $this->saldoInicial + $valor);
}
public function saldoComTaxa(float $taxa): float
{
return $this->saldoBruto() * (1 - $taxa);
}
}
$conta = new Conta('Ana', 1000.0);
$novaConta = $conta->depositar(500.0);
echo $conta->titular(), PHP_EOL;
echo $conta->saldoComTaxa(0.1), PHP_EOL;
echo $novaConta->saldoComTaxa(0.1), PHP_EOL;