Cursos

[Noticias][grids]

Como usar propriedades somente leitura no PHP 8.1

 

PHP 8.1 adiciona suporte para um modificador somente leitura nas propriedades da classe. Uma propriedade marcada desta forma só pode ser definida uma vez. Tentar alterar o valor de uma propriedade somente leitura &’ após a inicialização gerará um erro.

“ Somente leitura ” é um termo bastante vago, com implicações variáveis ​​em linguagens de programação individuais. Nesse contexto, “ somente leitura ” realmente significa “ imutável ” — você pode definir o valor de uma propriedade, mas não pode ser alterado posteriormente.

Gravando propriedades somente leitura

Adicione o modificador somente leitura para tornar uma propriedade somente leitura. Deve ser colocado entre o modificador de acesso da propriedade e sua dica de tipo.

classe Demo & # 123;   public string $ Mutable;   public readonly string $ Immutable;   função pública __construir & # 40; string $ Mutable, string $ Immutable & # 41; & # 123;   $ this- > Mutable = $ Mutable; $ this- > Immutable = $ Immutable; & # 125;   & # 125;

$ Mutable é uma propriedade pública normal. Você pode alterar seu valor a qualquer momento, dentro dos métodos de classe ou de fora:

$ demo = new Demo & # 40; " A ", " X " & # 41 ;; $ demo- > Mutable = " B & quot ;;

$ Immutable é um pouco diferente. Você ainda pode ler seu valor sempre que quiser, mas qualquer modificação falhará com um erro:

// Lança um erro $ demo- > Immutable = " Y & quot ;;

Publicidade

O modificador somente leitura também é compatível com as propriedades do construtor promovidas:

class Demo & # 123; publicfunction __construct & # 40; public readonly string $ Immutable = " foobar " & # 41; & # 123; & # 125; & # 125;

Você ainda pode definir a propriedade manualmente em seu construtor ao usar uma promoção com um valor padrão. É o parâmetro da função que recebe o valor padrão, não a instância da propriedade. A promoção desugars para o mesmo código mostrado no exemplo anterior.

Advertências

As propriedades somente leitura são um aprimoramento de sintaxe simples que você pode adotar quando quiser. Não há implicações de compatibilidade com versões anteriores e seu uso é totalmente opcional. Se você começar a adicioná-los, há algumas advertências e limitações a serem observadas.

Ao contrário das propriedades regulares, as propriedades somente leitura não podem ter um valor padrão em sua definição:

classe Demo & # 123; string somente leitura protegida $ foo = " bar & quot ;; & # 125;

Esta instrução define e inicializa $ foo. Você não pode alterar seu valor após a inicialização, então a propriedade é efetivamente uma constante. Como resultado, os valores padrão são proibidos e você deve usar uma constante real em seu lugar:

classe Demo & # 123; const foo = " bar & quot ;; & # 125;

Seguindo com esta restrição, somente leitura é suportado apenas em propriedades digitadas. A seguinte propriedade tem uma definição ilegal:

classe Demo & # 123; protegida somente leitura $ foo; & # 125;

Publicidade

Uma propriedade sem tipo, como $ foo acima, tem um valor padrão implícito de null. Se somente leitura fosse permitido, o “ sem constantes implícitas ” regra iria ressurgir. As propriedades digitadas distinguem entre “ não inicializado ” e “ null ” estados, então eles existem sem qualquer valor até que você defina um explicitamente.

O modificador somente leitura tem regras especiais quando usado como parte da herança de classe. As classes filhas não podem adicionar ou remover somente leitura em propriedades definidas por seus pais.

Tornar uma propriedade gravável somente leitura quebraria a classe pai se seus métodos alterassem o valor. Embora a remoção da restrição seja aparentemente inócua, a RFC considera somente leitura como uma “ restrição intencional ” de recursos que seriam perdidos se as substituições de herança fossem permitidas. É proibido para que as classes pai possam afirmar que os filhos não podem causar efeitos colaterais ao modificar propriedades que devem ser somente leitura.

As propriedades somente leitura podem ser definidas apenas no escopo em que são definidas. Isso significa que as propriedades públicas não podem ser definidas fora de uma classe, mesmo que não tenham sido inicializadas anteriormente:

class Demo & # 123; public readonly string $ foo; & # 125;   $ d = new Demo & # 40; & # 41 ;; $ d- > foo = " bar & quot ;; // ilegal

A inicialização deve ocorrer dentro da classe que define a propriedade. Como resultado, as propriedades somente leitura estão mais próximas dos campos imutáveis ​​de outras linguagens de programação, em oposição às propriedades PHP pré-existentes.

O modificador somente leitura se aplica igualmente a todas as gravações. Não faz distinção entre acesso interno e externo. Você não pode ter uma propriedade que seja somente leitura pública, mas gravável dentro da classe, embora uma extensão de especificação futura possa permitir isso.

Publicidade

Uma última pegadinha diz respeito à palavra-chave clone. Este código não funcionará:

class Demo & # 123; publicfunction __construct & # 40; public string $ foo & # 41; & # 123; & # 125; & # 125;   $ d = new Demo & # 40; " bar " & # 41 ;; $ d2 = clone $ d; $ d2- > foo = " foobar & quot ;;

A clonagem segue as mesmas regras dos acessos regulares de propriedade. Mesmo que a mudança para foobar seja a primeira vez que foo é acessado em $ d2, a propriedade já foi inicializada pelo processo de clonagem. Há uma inicialização implícita durante o clone.

Quando usar propriedades somente leitura?

Propriedades somente leitura irão acelerar significativamente a criação de classes simples, que representam estruturas de dados. É comum escrever classes descartáveis ​​para conter parâmetros de solicitação HTTP, objetos de transferência de dados e dados de resposta. Normalmente, eles são imutáveis, em que não se espera que as propriedades mudem após a construção da classe.

Você tinha anteriormente duas opções desagradáveis ​​ao escrever classes semelhantes a estruturas: usar propriedades públicas, acelerar o desenvolvimento, mas permitir modificações, ou gastar tempo adicionando manualmente métodos getter para expor propriedades protegidas.

// Não ideal - as propriedades podem ser modificadas externamente classe UserCreationRequest & # 123; publicfunction __construct & # 40; string pública $ Username, string pública $ Password & # 41; & # 123; & # 125; & # 125;   // Também não é ideal - Muitas codeclass padronizadas UserCreationRequest & # 123; publicfunction __construct & # 40; string protegida $ Username, string protegida $ Password & # 41; & # 123; & # 125;   publicfunction getUsername & # 40; & # 41 ;: string & # 123; return $ this- > Username; & # 125;   publicfunction getPassword & # 40; & # 41 ;: string & # 123; return $ this- > Password; & # 125; & # 125;

As propriedades somente leitura finalmente tornam a abordagem ideal possível:

class UserCreationRequest & # 123; publicfunction __construct & # 40; string pública somente leitura $ Nome de usuário, string pública somente leitura $ Senha & # 41; & # 123; & # 125; & # 125;

As propriedades são acessíveis ao público, mas imutáveis. Combinado com a promoção da propriedade do construtor, as propriedades somente leitura prometem reduzir significativamente o código clichê, permitindo que você escreva classes úteis mais rapidamente.

somente leitura também ajuda na legibilidade do código e indica melhor suas intenções. Qualquer pessoa que esteja lendo ou editando a classe UserCreationRequest sabe que suas propriedades não devem ser alteradas. No primeiro exemplo, não se sabe se outro código no projeto modifica as propriedades da classe diretamente. O segundo exemplo é um pouco mais claro, mas ainda pode induzir um desenvolvedor a implementar métodos setUsername () e setPassword () redundantes.

Conclusão

O modificador somente leitura traz suporte embutido de imutabilidade às propriedades da classe PHP. Isso torna seu código mais claro e evita alterações de valor não intencionais, impondo a imutabilidade no tempo de execução.

Publicidade

Voltando à série de lançamentos do PHP 7, criando uma classe básica semelhante a uma estrutura usada para envolver a definição de propriedades digitadas, escrevendo um construtor que define essas propriedades e, em seguida, adicionando métodos getter para expor seus valores. Com o PHP 8.1, você pode condensar tudo isso em uma única assinatura de construtor, combinando somente leitura pública e promoção de propriedade.

As propriedades somente leitura são implementadas nas últimas compilações de desenvolvimento do PHP 8.1. O lançamento pronto para produção chegará em novembro de 2021.