Posts da Tag: php 8 - Blog da TreinaWeb

PHP

União de Tipos no PHP 8: o que é e como usar

Nesse artigo vamos falar sobre união de tipos no PHP, ou também conhecido como union types. Recurso adicionado a linguagem na versão 8 e possui a finalidade de melhorar o uso de tipos.

A comunidade vem trabalhando para melhorar a questão de tipos na linguagem PHP há algum tempo. A versão 7.0 trouxe vários detalhes importantes, como uso de tipos primitivos em parâmetros e retornos, tipagem estrita e melhorou o tratamento de erros para tipos. A versão 7.1 trouxe a opção de definir um parâmetro como anulável e também o retorno void. A 7.4 permitiu a definição de tipos em propriedades e a 8 trouxe como principal novidade a união de tipos.

O que é união de tipos no PHP

Quando trabalhamos com tipo e principalmente quando trabalhamos tipagem estrita, os dados que enviamos para um parâmetro ou que retornamos precisam ser exatamente do tipo declarado e isso pode tornar as coisas um pouco inflexíveis.

A união de tipos permite que você declare mais de um tipo para um parâmetro ou retorno. Veja o exemplo:

function andar(int|string $velocidadeMaxima): string|float {
    return $aceleracao . ' ' . $velocidadeMaxima;
}

No exemplo acima, a função andar pode receber a velocidade máxima como sendo um inteiro ou uma string e pode retornar uma string ou um float.

Sintaxe de uso do Union Type

A Sintaxe para utilização da união de tipos no PHP é muito simples. Basta separar os tipos por pipes |, conforme o exemplo abaixo:

function nomeFuncao(
    tipo1|tipo2|tipoN $nomeparametro1, 
    tipo1|tipo2|tipoN $nomeparametro2,
): tipo1|tipo2|tipoN {
    //código da função
}

Podemos usar dentro da união de tipos no php qualquer tipo válido na linguagem, com algumas exceções que vamos ver abaixo.

Permitindo null na união de tipos

Usando definição de um único tipo no PHP podemos tornar um parâmetro ou retorno anulável usando sinal de interrogação, conforme o exemplo abaixo:

function somar(?int $num1, ?int $num2): ?int
{
    if ($num1 === null || $num2 == null) {
        return null;
    }

    return $num1 + $num2;
}

Já com uso de union type precisamos usar a palavra null:

function somar(int|float|null $num1, int|float|null $num2): int|float|null
{
    if ($num1 === null || $num2 == null) {
        return null;
    }

    return $num1 + $num2;
}

Void na união de tipos

Quando uma função ou método não possui retorno, nós podemos declarar o retorno como void:

function mostrar(string $valor): void
{
    echo $valor;
}

Porém uso de void não é permitido para a união de tipos.

function mostrar(string $valor): void|string
{
    echo $valor;
}

Se tentar usar ele apresentará o seguinte erro:

Fatal error: Void can only be used as a standalone type in xxx on line N

Mixed na união de tipos

Na versão 8.0 o PHP ganhou a anotação de tipo mixed. Esse tipo já existe na documentação da linguagem, porém não existia como tipo realmente. Ele indica que um parâmetro ou retorno pode ser de qualquer tipo válido na linguagem. Veja o exemplo:

function mostrar(mixed $valor): void
{
    echo $valor;
}

O parâmetro $valor pode ser de qualquer tipo válido, consequentemente não faz sentido usar ele junto com outros tipos no union type:

function mostrar(string|mixed $valor): void
{
    echo $valor;
}

O código acima apresentará o seguinte erro:

Fatal error: Type mixed can only be used as a standalone type in xxx on line N

Indicador false

Ao usar união de tipos no PHP (union Type), podemos usar a palavra reservada false para indicar que uma função retornará um determinado tipo ou false, veja o exemplo abaixo:

class Carro {
    protected int $velocidadeAtual = 0; 

    public function estaAndando(): int|false
    {
        if ($this->velocidadeAtual > 0) {
            return $this->velocidadeAtual;
        }

        return false;
    }
}

A palavra false não pode ser usado junto com o tipo bool e também vale ressaltar que a palavra true não pode ser usada.

Considerações Finais

O recurso de união de tipos no PHP é algo extremamente interessante, principalmente para ajudar na migração gradual de aplicações que não utilizam tipos estritos para utilização de tipos estritos. Ela também garante um nível de leitura maior para aplicações que não adotaram o uso de tipo estrito, uma vez que é possível usar union type para declarar os tipos válidos de entrada e saída sem estar preso a tipagem estrita.


PHP

Declarando propriedades no construtor PHP

Neste post vamos aprender como declarar propriedades no construtor PHP, recurso também chamado de promoção de propriedade que pode ser usado a partir da versão 8 da linguagem PHP.

PHP - Novidades do PHP 8.0
Curso de PHP - Novidades do PHP 8.0
CONHEÇA O CURSO

O que é promoção de propriedade

A promoção de propriedade consiste basicamente em realizar 3 ações de forma automática na declaração do construtor de uma classe:

  • Declara as propriedades na classe;
  • Recebe os valores que serão definidos;
  • Atribui esses valores a propriedade da classe.

Isso evita que nossas classe tenham uma série de linhas para realizar uma tarefa simples.

Qual utilidade prática da promoção de propriedades no PHP

Na prática, a promoção de propridade nos permite declarar e atribuir valores a propriedades de uma classe usando bem menos linhas. Isso é muito interessante, pois muitas classes precisam realizar esta tarefa, principalmente pelo uso da injeção de dependência.

Veja o exemplo abaixo, uma classe que possui 2 propriedade, só a parte de declaração e atribuição via construtor ocupa 21 linhas de código:

<?php

namespace Cliente\Actions;

use Cliente\Tasks\GeraToken;
use Cliente\Tasks\CadastraUsuario;

class CadastraCliente
{
    /**
     * Propriedade da task cadastrar usuario
     */
    private CadastraUsuario $cadastraUsuario;

    /**
     * Propriedade da task gerar token
     */
    protected GeraToken $geraToken;

    /**
     * @param CadastraUsuario $cadastraUsuario
     * @param GeraToken $geraToken
     */
    public function __construct(
        CadastraUsuario $cadastraUsuario, 
        GeraToken $geraTokenTask
    )
    {
        $this->cadastraUsuario = $cadastraUsuario;
        $this->geraToken = $geraToken;
    }
}

O exemplo acima possui apenas duas propriedades. Em classes que precisam declarar e receber valores em várias propriedades, a quantidade de código antes do primeiro método fica bem grande.

Sintaxe para declaração de propriedades no construtor PHP

A promoção de propriedades torna o código muito mais simples e legível. O mesmo código do exemplo anterior pode ser definido do seguinte modo:

<?php

namespace Cliente\Actions;

use Cliente\Tasks\GeraToken;
use Cliente\Tasks\CadastraUsuario;

class CadastraCliente
{
    /**
     * @param CadastraUsuario $cadastraUsuario
     * @param GeraToken $geraToken
     */
    public function __construct(
        private CadastraUsuario $cadastraUsuario, 
        protected GeraToken $geraToken
    ) {}
}

Basicamente única coisa que precisamos é declarar a visibilidade da propriedade na hora de definir o parâmetro no construtor. Desse modo ele já realiza todo o processo, tornando o código muito mais limpo.

Desenvolvedor PHP
Formação: Desenvolvedor PHP
Nesta formação você aprenderá todos os conceitos da linguagem PHP, uma das mais utilizadas no mercado. Desde de conceitos de base, até características mais avançadas, como orientação a objetos, práticas de mercado, integração com banco de dados. Ao final, você terá conhecimento para desenvolver aplicações PHP usando as práticas mais modernas do mercado.
CONHEÇA A FORMAÇÃO

Considerações Finais

Recursos que permitem escrever código mais limpo, como é o caso da promoção de propriedades e recursos que aumentam a legibilidade do código, como é o caso dos parâmetros nomeados no PHP são extremamente importantes. Apesar de serem recursos extremamente novos, em breve devem se tornar padrão na maioria dos projetos.


PHP

Como usar parâmetros nomeados no PHP

Neste post vamos conhecer o que são parâmetros nomeados no PHP, qual sua sintaxe e as principais vantagens de utilizá-lo.

PHP - Novidades do PHP 8.0
Curso de PHP - Novidades do PHP 8.0
CONHEÇA O CURSO

O que são parâmetros nomeados

Existem basicamente dois modos de passarmos valores para funções e métodos. Temos os parâmetros posicionais, que devemos passar os valores na mesma ordem que eles são declarados, por exemplo:

function programar(string $linguagem, string $versao) {}

programar('PHP', '8.0')

E existem os parâmetros nomeados, onde indicamos na hora de chamar o método ou função o nome dos parâmetros:

function programar(string $linguagem, string $versao) {}

programar(linguagem: 'PHP', versao: '8.0');

Parâmetros nomeados existem em várias linguagens e cada uma delas possui uma sintaxe específica.

Sintaxes dos parâmetros nomeados

A sintaxe dos parâmetros nomeados no PHP é muito simples. No momento da declaração nada muda em relação aos parâmetros posicionais:

function nome($parametro1, $parametro2) {}

A principal diferença é na hora de passar os valores para os parâmetros. Precisamos usar o nome do parâmetro sem $, dois pontos : e em seguida o valor. Veja o exemplo abaixo:

function nome($parametro1, $parametro2) {}

nome(parametro1: 'valor', parametro2: 'valor');

Vantagens na utilização de parâmetros nomeados

Algo que todo mundo quer é escrever um código que seja facilmente lido (legível) e limpo. Esses dois aspectos ajudam muito na hora de realizar uma manutenção ou adicionar uma nova funcionalidade a uma aplicação.

Legibilidade

Os parâmetros nomeados entram exatamente na questão da legibilidade do código. Isso não significa que só por usar parâmetros nomeados o código vai ser incrivelmente legível, porém é um recurso simples que pode ajudar bastante. Veja o seguinte trecho de código:

$uno = new Carro('Fiat', 'Preto',);

$uno->andar(110, 5);

No construtor da classe carro podemos presumir que o primeiro parâmetro é a marca do carro e o segundo é a cor. Já na chamada do método andar, as coisas ficam um pouco mais complicadas.

Veja agora o mesmo trecho de código usando parâmetros nomeados:

$uno = new Carro(marca: 'Fiat', cor: 'Preto');

$uno->andar(velocidadeMaxima: 110, aceleracao: 5);

Ao batermos o olho nesse trecho de código, mesmo sem conhecer a implementação da classe Carro conseguimos saber exatamente o que está acontecendo.

Flexibilidade dos parâmetros nomeados no PHP

Ao utilizarmos parâmetros nomeados não ficamos mais presos a posição em que o parâmetro foi declarado, gerando uma maior flexibilidade na hora da escrita do código, por exemplo:

function andar(int $aceleracao, int $velocidadeMaxima,)
{
    echo $aceleracao . ' ' . $velocidadeMaxima;
}

Podemos agora chamar o método acima dos seguintes modos:

andar(velocidadeMaxima: 110, aceleracao: 5);
andar(aceleracao: 5, velocidadeMaxima: 110);

E podemos usar parâmetros posicionais sem problemas:

andar(110, 5);
Desenvolvedor PHP
Formação: Desenvolvedor PHP
Nesta formação você aprenderá todos os conceitos da linguagem PHP, uma das mais utilizadas no mercado. Desde de conceitos de base, até características mais avançadas, como orientação a objetos, práticas de mercado, integração com banco de dados. Ao final, você terá conhecimento para desenvolver aplicações PHP usando as práticas mais modernas do mercado.
CONHEÇA A FORMAÇÃO

Considerações finais

Parâmetro nomeado não é o recurso que sozinho vai tornar o seu código incrível, porém pode ser considerado como uma opção a mais na hora da escrita. Muitos podem considerar um recurso desnecessário, porém como vimos é um recurso que ajuda bastante na legibilidade.


PHP

Como usar Attributes/Annotations no PHP 8

Nesse artigo vamos conhecer o que são annotations no PHP 8, como usar esse recurso e também como implementar a parte de obtenção dos valores dos attributes.

PHP - Novidades do PHP 8.0
Curso de PHP - Novidades do PHP 8.0
CONHEÇA O CURSO

O que são Annotations

Annotations ou no caso do PHP também chamado de Attributes, é um modo que temos de declararmos meta informações a respeito de um determinado elemento de código. Podemos declarar meta informações sobre uma propriedade, um método ou uma classe. Veja um pseudo código abaixo:

@entidade
class Carro
{
    @validacao(min: 1990, max: 2015)
    propriedade inteira ano;

    @acao
    funcao andar(velocidadeMaxima)
    {}
}

No exemplo acima temos as seguintes meta informações:
@entidade – é uma anotação da classe Carro, que poderia indicar que ela é uma entidade da aplicação.
@validacao – é uma anotação da propriedade, nesse exemplo está indicando que os valores válidos para essa propriedade devem ser entre 1990 e 2015.
@acao – anotação do método, poderia ser utilizado para indicar que esse método realiza uma ação e notificar algum outro trecho de código.

Annotations antes do PHP 8

Mesmo antes do PHP 8 alguns projetos já utilizavam o conceito na linguagem, porém esse processo era realizado de maneira não oficial. As annotations eram definidas dentro de blocos de comentários, com base nisso eles liam esses arquivos e obtinham as meta informações.

Se você já trabalhou com Symfony ou Doctrine provavelmente já utilizou annotations, mesmo em versões anteriores do PHP. Veja o seguinte código utilizado no Doctrine:

/**
 * @ORM\Entity(repositoryClass="App\Repository\TaskRepository")
 */
class Task
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     * @Assert\Length(
     *      min = 5,
     *      minMessage = "length.min"
     * )
     * @HasString(
     *      string = "Elton"
     * )
     */
    private $title;
}

Annotations no PHP 8

A partir da versão 8 do PHP as annotations ou como foi chamado na linguagem “attributes”, ganharam uma implementação nativa e padronizada. A sintaxe definida para sinalizar um atributo ficou:

#[AnotacaoSemParametro]

E quando necessário enviar algum parâmetro:

#[AnotacaoComParametro(parametro1: valor, parametro2: valor)]

Será possível usar attributes no PHP 8 para classes, métodos e propriedades.

No Symfony 5.2 já será possível substituir as annotations antigas pelos attributes do php 8:

class SomeController
{
    #[Route('/path', name: 'action')]
    public function someAction()
    {
        // ...
    }
}
Desenvolvedor PHP
Formação: Desenvolvedor PHP
Nesta formação você aprenderá todos os conceitos da linguagem PHP, uma das mais utilizadas no mercado. Desde de conceitos de base, até características mais avançadas, como orientação a objetos, práticas de mercado, integração com banco de dados. Ao final, você terá conhecimento para desenvolver aplicações PHP usando as práticas mais modernas do mercado.
CONHEÇA A FORMAÇÃO

Como obter valores dos attributes no php 8

Se você for apenas usar bibliotecas externas para declarar meta informações sobre seu código, a sintaxe que aprendemos até agora já é suficiente. Agora se quiser criar suas próprias anotações personalizadas, precisará usar um pouco da API de reflection do PHP.

Vamos supor que deseja validar os dados das propriedades de uma classe usando anotações:

class Carro {
    #[Validacao('max', 110)]
    public int $velocidade;
}

Nesse caso a primeira coisa que precisa ter em mente é que o nome da annotation que usamos no PHP é o nome de uma classe e os parâmetros passados são enviados no construtor. No exemplo acima, usamos a seguinte classe para representar essa anotação:

#[Attribute]
class Validacao {
    public function __construct(
        public string $regra,
        public int $valor
    ){}
}
A classe que vai representar o atributo precisa ser marcada com a annotation interna do PHP #[Attribute], conforme a primeira linha do código acima.

Então para pegarmos as meta informações definida nos attributos podemos fazer:

//Cria uma instância de classe reflection com as informações da classe Carro
$informacoesClasseCarro = new reflectionClass(Carro::class);

//Percorre as propriedades da classe Carro
foreach ($informacoesClasseCarro->getProperties() as $propriedade) {
    //Mostra o nome da propriedade  
    echo $propriedade->getName() . ': ';

    //Pega os atributos dessa propriedade em especifico
    $atributosDaPropriedade = $propriedade->getAttributes(Validacao::class);
    //Percorre os atributos definidos na propriedade
    foreach ($atributosDaPropriedade as $atributo) {
        //Cria uma instância da classe que representa a anotação, nesse caso a classe Validacao
        var_dump($atributo->newInstance());
    }
}

O código que usamos acima basicamente já existia nas versões anteriores do PHP, único código diferente é o método getAttributes que foi criado justamente para obter os dados de atributo de uma classe, método ou propriedade.

No Github da Treinaweb têm esse exemplo completo de Attributes, mostrando também como realizar a validação usando a meta informações que definimos lá na propriedade $velocidade da classe Carro.

Desenvolvedor PHP
Formação: Desenvolvedor PHP
Nesta formação você aprenderá todos os conceitos da linguagem PHP, uma das mais utilizadas no mercado. Desde de conceitos de base, até características mais avançadas, como orientação a objetos, práticas de mercado, integração com banco de dados. Ao final, você terá conhecimento para desenvolver aplicações PHP usando as práticas mais modernas do mercado.
CONHEÇA A FORMAÇÃO

Considerações Finais

A implementação do recurso de Attributes ou também conhecido como Annotations no PHP 8 é algo muito positivo. Várias bibliotecas e ferramentas já estão definindo usos bem interessantes para esse recursos mesmo antes do lançamento oficial da versão 8 do PHP. O que indica que dentro de algum tempo teremos um uso em massa desse recurso.