Skip to content

gabriellopesmarques/loop-php-day

Repository files navigation

Enums

Introduzida na versão 8.1, proposta por Larry Garfield na RFC

https://www.php.net/manual/en/language.enumerations.php

O que são Enums?

Um enum é uma estrutura que permite criar um tipo de dado que só pode assumir valores pré-definidos. Tornam o código mais legível, seguro e organizado, evitando o uso de números mágicos ou strings soltas.

Como era antes?

Criávamos uma classe e delimitávamos os valores possíveis por meio de constantes.

class Status {
    const ATIVO = 0;
    const INATIVO = 1;
    const PENDENTE = 2;
}

$status = Status::ATIVO; // int(0)

Essa abordagem traz expressividade ao código, porem tem como desvantagem que não é possivel valida-la como parametro. Pois o tipo do valor será primitivo, inteiro, nesse caso, e não Status.

A solução que nós utilizamos na nossa codebase

# ...

include 'Enum.php';

class Status extends Enum
{
    const ATIVO = '0';
    const INATIVO = '1';
    const PENDENTE = '2';
}

$status = Status::ativo(); // object(Status)#1 (1) { ["value":protected]=> string(1) "0" }

outras abordagens

$status = [
    'ativo' => 0,
    'inativo' => 1,
    'pendente' => 2
];
$status['ativo']; // int(0)

Como utilizar?

enum Naipe
{
    case Copas;
    case Ouros;
    case Paus;
    case Espadas;
}

var_dump(Naipe::Copas); // enum(Naipe::Copas)
var_dump(Naipe::Espadas->name); // string(7) "Espadas"

Backed enumerations

O exemplo acima é chamado de 'Enumeração Pura' (Pure Case), pois a enumeração não possuí um outro valor relacionado. Porem é comum precisarmos que algo possua um valor diferente do nome atribuido. Nesses casos que possuímos um escalar embutido, chamamos de Enumerações Apoiadas (Backed enumerations).

enum Naipe: string
{
    case Copas = 'C';
    case Ouros = 'O';
    case Paus = 'P';
    case Espadas = 'E';
}

var_dump(Naipe::Copas); // enum(Naipe::Copas)
var_dump(Naipe::Copas->name); // string(5) "Copas"
var_dump(Naipe::Copas->value); // string(1) "C"

Metodos adicionais

Enumerações Apoiadas implementam uma interface interna BackedEnum, que expõe dois métodos adicionais from e tryFrom.

from
var_dump(Naipe::from('C')); // enum(Naipe::Copas)
var_dump(Naipe::from('J')); // Fatal error: Uncaught ValueError: "J" is not a valid backing value for enum Naipe ...
tryFrom
var_dump(Naipe::from('C')); // enum(Naipe::Copas)
var_dump(Naipe::from('J')); // NULL

Os métodos from() e tryFrom() seguem as regras padrão de tipagem fraca/forte. No modo de tipagem fraca, passar um inteiro ou string é aceitável e o sistema irá coagir o valor de acordo. Porem, como utilizamos declare(strict_types=1); sempre que utilizarmos um tipo diferente do declarado, irá lançar TypeError.

declare(strict_types=1);

enum Status: int
{
    case ATIVO = 0;
}

var_dump(Status::from('0')); // Fatal error: Uncaught TypeError: Status::from(): Argument #1 ($value) must be of type int, string given

importante: Uma Enumeração Apoiada pode conter apenas Casos Apoiados. Uma Enumeração Pura pode conter apenas Casos Puros.

Métodos de enumerações

Enumerações podem conter métodos e podem implementar interfaces.

enum Status: int
{
    case ATIVO = 0;
    case INATIVO = 1;
    case PENDENTE = 2;

    public function canApprove(): bool
    {
        return $this === Status::PENDENTE;
    }
}

$status = Status::from(0);
var_dump($status->canApprove()); // false

Tambem podemos criar metodos estaticos. Apesar de enumerações serem construídas sobre classes e objetos, elas não suportam todas as funcionalidades relacionadas a objetos. Em particular, casos de enumeração são proibidos de ter estado.

  • Construtores e Destrutores são proibidos.
  • Herança não é suportada. Enumerações não podem estender ou ser estendidas.
  • Propriedades estáticas ou de objeto não são permitidas.
  • Clonar um caso de enumeração não é suportado, pois os casos devem ser instâncias únicas.
  • Métodos mágicos, exceto __call, __callStatic, e __invoke não são permitidos.
  • Enumerações sempre precisam ser declaradas antes de serem utilizadas.

Vantagens de migrar para o nativo

Enums no PHP 8.1 não introduzem um conceito novo no nosso projeto. Eles padronizam, simplificam e tornam nativo algo que já fazemos hoje.

  • Evolui com a linguagem
  • Não depende da nossa manutenção (menos custo)
  • Melhor compatibilidade com IDEs

projetos interessantes

https://github.com/myclabs/php-enum https://github.com/archtechx/enums

refs

https://www.youtube.com/watch?v=5hsHMxMxna8 https://www.youtube.com/watch?v=Zf0eszI08tg https://wiki.php.net/rfc/enumerations https://www.php.net/releases/8.1/pt_BR.php https://www.php.net/manual/en/language.enumerations.overview.php https://speakerdeck.com/marcelgsantos/o-que-ha-de-novo-no-php-8-dot-0-e-8-dot-1?slide=132


Named Arguments

Introduzido no 8.0.0 proposta por Nikita Popov, os argumentos nomeados como uma extensão aos parâmetros posicionais. Argumentos nomeados permitem a passagem de argumentos para uma função utilizando-se os nomes dos parâmetros ao invés das posições deles.

// Using positional arguments:
array_fill(0, 100, 50);

// Using named arguments:
array_fill(start_index: 0, num: 100, value: 50);
htmlspecialchars(
    string $string,
    int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,
    ?string $encoding = null,
    bool $double_encode = true
): string

htmlspecialchars($string, double_encode: false);

// Same as
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);

refs

https://wiki.php.net/rfc/named_params https://www.php.net/manual/pt_BR/functions.arguments.php#functions.named-arguments https://www.youtube.com/watch?v=epla4NyobjU


new sem parênteses

Introduzido na versão 8.4, RFC proposta por Valentin Udaltsov. Permite que expressões com argumentos de construtor agora são desreferenciáveis, o que significa que permitem encadear chamadas de métodos, acessos a propriedades etc., sem colocar a expressão entre parênteses.

// OK
$request = (new Request())->withMethod('GET')->withUri('/hello-world');

// PHP Parse error: syntax error, unexpected token "->"
$request = new Request()->withMethod('GET')->withUri('/hello-world');

refs

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages