Propriedades Readonly (PHP 8.1)
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 19 de 91.
O PHP 8.1 introduziu propriedades readonly, que só podem ser atribuídas uma vez e não podem ser modificadas posteriormente. Ao contrário das constantes, as propriedades readonly são definidas durante a inicialização do objeto, em vez de no momento da definição da classe.
Você declara uma propriedade readonly adicionando a palavra-chave readonly antes da declaração do tipo:
<?php
class User {
public readonly string $id;
public readonly string $name;
public function __construct(string $id, string $name) {
$this->id = $id;
$this->name = $name;
}
}
$user = new User("U001", "Alice");
echo $user->id . "\n";
echo $user->name;
Saída:
U001
AliceUma vez atribuída, tentar alterar uma propriedade readonly causará um erro. Isso as torna perfeitas para valores que devem permanecer constantes durante o tempo de vida de um objeto, como IDs ou timestamps de criação.
Propriedades readonly devem ter uma declaração de tipo e só podem ser inicializadas uma vez, seja no construtor ou no momento da declaração. Elas funcionam com qualquer modificador de visibilidade:
<?php
class Product {
public function __construct(
public readonly string $sku,
private readonly float $cost
) {}
public function getCost(): float {
return $this->cost;
}
}
$product = new Product("ABC123", 29.99);
echo $product->sku;
Saída:
ABC123Ponto Chave: Propriedades readonly fornecem imutabilidade no nível da propriedade. Elas são ideais para dados que identificam um objeto ou que não devem mudar após a criação, combinando a flexibilidade da inicialização em tempo de execução com a segurança de prevenir modificações acidentais.
Desafio
FácilVamos construir um sistema de configuração imutável que utiliza propriedades readonly para garantir que as configurações críticas não possam ser alteradas acidentalmente após a inicialização.
Você criará dois arquivos que trabalham juntos para gerenciar a configuração da aplicação:
Config.php— Defina uma classeConfigque representa a configuração da aplicação com definições imutáveis. A classe deve ter três propriedades readonly públicas:string $appName,string $versioneint $maxConnections. Use a promoção de construtor (constructor promotion) para declarar e inicializar todas as três propriedades readonly em uma única e limpa definição de construtor. Adicione um métodogetInfo()que retorna uma string no formato"[appName] v[version] (max: [maxConnections] connections)".main.php— Inclua o arquivo da classe Config. Você receberá três entradas: o nome do app, a versão e o número máximo de conexões (como uma string que precisa ser convertida para um inteiro). Crie um objetoConfigusando esses valores. Imprima o resultado degetInfo()na primeira linha. Em seguida, imprima cada propriedade readonly em sua própria linha acessando-as diretamente: o nome do app, a versão e o máximo de conexões.
As propriedades readonly garantem que, uma vez criada uma configuração, seus valores fiquem travados — perfeito para configurações que devem permanecer constantes durante o tempo de execução da sua aplicação. Observe como a promoção de construtor combinada com readonly cria uma maneira muito concisa de definir objetos de valor imutáveis.
Sua saída deve exibir a string de informações formatada seguida por cada valor de propriedade individual, demonstrando que as propriedades readonly ainda podem ser lidas de fora da classe.
Folha de consulta
O PHP 8.1 introduziu as propriedades readonly, que só podem ser atribuídas uma única vez e não podem ser modificadas posteriormente:
<?php
class User {
public readonly string $id;
public readonly string $name;
public function __construct(string $id, string $name) {
$this->id = $id;
$this->name = $name;
}
}
$user = new User("U001", "Alice");
echo $user->id; // U001
Propriedades readonly devem ter uma declaração de tipo e só podem ser inicializadas uma vez. Elas funcionam com qualquer modificador de visibilidade e podem ser combinadas com a promoção de construtor (constructor promotion):
<?php
class Product {
public function __construct(
public readonly string $sku,
private readonly float $cost
) {}
}
$product = new Product("ABC123", 29.99);
echo $product->sku; // ABC123
Propriedades readonly são ideais para valores que devem permanecer constantes durante todo o tempo de vida de um objeto, como IDs, carimbos de data/hora (timestamps) ou configurações.
Experimente você mesmo
<?php
require_once 'Config.php';
// Ler entradas
$appName = trim(fgets(STDIN));
$version = trim(fgets(STDIN));
$maxConnections = intval(trim(fgets(STDIN)));
// TODO: Criar um objeto Config usando os valores de entrada
// TODO: Imprimir o resultado de getInfo()
// TODO: Imprimir cada propriedade readonly em sua própria linha:
// - app name
// - version
// - max connections
?>Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodoA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em DetalhesGetters e SettersOcultação de InformaçãoPromoção de Construtor (8.0)Recapitulação - Sistema de Registro de Alunos10Conceitos Avançados de POO
Composição vs HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibers (PHP 8.1)Mergulho Profundo em Clonagem de ObjetosGeradores e Iteradores13Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository2Namespaces e Autoloading
Introdução a NamespacesA Palavra-chave usePadrão de Autoloading PSR-4Autoloader do ComposerRecapitulação - Projeto Organizado5Interfaces e Contratos
Introdução a InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataType Hinting com InterfacesRecapitulação - Calculadora de Formas8Métodos Mágicos
Introdução aos Métodos Mágicos__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e Clonagem de Objetos__serialize e __unserializeRecapitulação - Coleção Personalizada11Sistema de Tipos e Tratamento de Erros
Declarações de TiposTipos AnuláveisTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadasTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário3Propriedades de Classe
Propriedades de Instância vs EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Readonly (PHP 8.1)Recapitulação - Gerenciador de Conta Bancária6Polimorfismo
Sobrescrita de Métodos RevisitadaPolimorfismo via InterfacesType Hinting e Union TypesLate Static BindingRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos de TraitsMétodos Abstratos em TraitsTraits vs Herança12Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy