Header Ads

Promoção de propriedade de construtor em PHP 8

A promoção da propriedade do construtor é um novo recurso de conveniência do PHP 8 que ajuda a minimizar a repetição de código. Ele permite combinar a definição e inicialização de propriedades em uma única instrução do construtor.

Uma aula tradicional

A promoção da propriedade do construtor (CPP a partir daqui) é mais útil no contexto de objetos de valor. Estas tendem a ser classes simples que descrevem uma estrutura de dados. Aqui está como se parece no PHP 7.4:

classe BlogPost & # 123;   string protegida $ Title;   string protegida $ Content;   protegido DateTimeImmutable $ PostedDate;     função pública __construir & # 40; string $ Title, string $ Content, DateTimeImmutable $ PostedDate & # 41; & # 123;   $ this- > Title = $ Title; $ this- > Content = $ Content; $ this- > PostedDate = $ PostedDate; & # 125;   & # 125;

Nós criamos uma classe razoavelmente longa, apesar de ter apenas três propriedades! Cada nome de propriedade ocorre quatro vezes, com as dicas de tipo sendo gravadas duas vezes. Se você precisasse corrigir uma das propriedades ou adicionar outra, estaria tocando em três linhas de código.

Adicionando promoção de propriedade de construtor

Aqui está o mesmo exemplo, reescrito para usar CPP no PHP 8:

classe BlogPost & # 123; publicfunction __construct & # 40; string protegida $ Title, string protegida $ Content, protected DateTimeImmutable $ PostedDate & # 41; & # 123; & # 125; & # 125;

Ao usar o CPP, reduzimos drasticamente o tamanho de nossa classe. Você só precisa adicionar ou alterar uma linha de código ao trabalhar com esta classe &’ propriedades.

Um olhar mais atento

O CPP combina a definição de propriedade com a lista de parâmetros do construtor. Para criar uma propriedade promovida, prefixe seu nome com um modificador de visibilidade de classe – público, protegido ou privado.

Depois de promovida, a propriedade se comporta como qualquer outra propriedade de classe. Você pode acessá-lo dentro da classe usando $ this - > Propriedade ou externamente (se for uma propriedade pública). Internamente, o PHP está simplesmente transformando a sintaxe compacta na versão muito mais longa suportada pelo PHP 7.

Você não precisa usar dicas de tipo com propriedades promovidas – é aceitável escrever $ Title protegido, por exemplo. Você pode definir valores padrão usando a mesma sintaxe de um parâmetro de construtor regular (string protegida $ Title = "Exemplo de postagem").

Usando com um corpo de construtor

Seu construtor nem sempre será tão simples quanto nosso exemplo. Pode ser necessário realizar algumas verificações de validação ou transformar um valor.

Você ainda pode escrever um corpo de construtor ao usar CPP. Você poderá acessar os valores de suas propriedades promovidas como a variável de instância promovida ou usando a variável local:

publicfunction __construct & # 40; string protegida $ Title & # 41; & # 123; if & # 40;! $ this- > Title & # 41; & # 123; thrownew InvalidArgumentException & # 40; " O título não pode estar vazio. " & # 41 ;; & # 125; // ORif & # 40;! $ Title & # 41; & # 123; thrownew InvalidArgumentException & # 40; " O título não pode estar vazio. " & # 41 ;; & # 125; & # 125;

Qualquer que seja a abordagem escolhida, a variável ou a propriedade, você trabalhará com o mesmo valor. PHP simplesmente esconde o $ this - > Título = $ linha de título que você normalmente escreveria manualmente.

Combinando com propriedades e parâmetros regulares

Você pode misturar livremente propriedades promovidas com definições de propriedade regulares. Além disso, você pode combinar propriedades promovidas e não promovidas em seus parâmetros de construtor.

class BlogPost & # 123; public? DateTimeImmutable $ PostedDate = null;   publicfunction __construct & # 40; public string $ Title, bool $ isPosted = true & # 41; & # 123; if & # 40; $ isPosted & # 41; $ this- > PostedDate = new \ DateTimeImmutable & # 40; & # 41 ;; & # 125; & # 125;

Você deve ter cuidado ao misturar essas sintaxes. As propriedades promovidas podem ser facilmente ignoradas durante a leitura do código, especialmente se precedidas por definições de propriedade de classe regular. Se sua classe já possui várias propriedades usando a forma tradicional, usar a nova sintaxe para uma adição extra pode não ser a melhor abordagem para esse arquivo.

Use com atributos

Um dos outros novos recursos do PHP 8 são os atributos. Isso permite que você anote metadados extras em entidades em sua base de código.

Os atributos são totalmente suportados nas propriedades promovidas. Como é ambíguo se o atributo se aplica a uma definição de propriedade ou a um parâmetro de método, o PHP o aplicará a ambos.

Isso significa que você obterá o mesmo valor de volta, independentemente de estar inspecionando novamente a propriedade ou o parâmetro do construtor. Essa abordagem flexível garante que você não perca nenhuma funcionalidade dos atributos ao adotar a promoção da propriedade do construtor.

Reflexão

Propriedades promovidas – e argumentos do construtor que promovem uma propriedade – se comporte intuitivamente quando for examinado por meio das APIs do Reflection. O Reflection analisa as propriedades promovidas em seu estado pós-transpilação, para que pareçam idênticas a uma propriedade explicitamente declarada.

Ambas as classes ReflectionProperty e ReflectionParameter têm novos métodos isPromoted () para permitir que você verifique se eles estavam envolvidos com CPP. Geralmente, isso não deve ser considerado, a menos que você esteja escrevendo uma ferramenta que deseja replicar a estrutura de origem exata.

Possíveis truques

Você não pode declarar classes duplicadas e nomes de propriedades promovidas. O exemplo a seguir resultaria em um erro de tempo de execução:

class BlogPost & # 123; public string $ Title;   publicfunction __construct & # 40; public string $ Title & # 41; & # 123; & # 125; & # 125;

Isso ocorre porque o PHP realmente não faz nada de especial com as definições de propriedades promovidas. Ele simplesmente transpila seu código-fonte conciso para o estilo PHP 7.4. Isso resultaria em duas linhas públicas de string $ Title, o que sempre foi proibido.

Existem outros casos em que o CPP pode resultar em erro. Propriedades promovidas são proibidas em classes abstratas, embora possam ser usadas em características. Você não pode usar o tipo chamável com eles porque não é compatível com definições de propriedade. Por fim, não há suporte para parâmetros variáveis ​​(por exemplo, string pública ... $ strings) porque a propriedade acabaria sendo uma matriz de instâncias de string, não uma string em si.

Conclusão

A promoção da propriedade do construtor torna muito mais rápido escrever novos objetos de valor em sua base de código. Ele pode reduzir o número de linhas em até dois terços! O CPP também ajuda a secar (não se repita) seu código, evitando a repetição desagradável de dicas de tipo e nomes de propriedade que o PHP 7.4 exigiu.

A adoção do CPP é opcional e nem sempre fará sentido para as classes existentes. É mais adequado para classes simples do tipo struct, em que você deseja fornecer tipagem forte para dados que serão transmitidos por meio de sua base de código.

Nenhum comentário