Enum ou Enumerations no PHP
Tags: php, webdev, php8, enum
Published: 2023-03-05 15:31:44

Neste artigo, veremos a funcionalidade de Enums no PHP v8.1, o que são casos puros e com suporte em Enums e a diferença entre classes regulares e Enums.

## Sintaxe Básica
O PHP 8.1 utiliza a palavra-chave enum para declarar Enums. A sintaxe é semelhante à sintaxe de traits, classes e interfaces. Veja como fica um enum simples:

```php
enum Senioridade {
    case Junior;
    case Pleno;
    case Senior;
    case Especialista;
}
```
A palavra-chave `case` é usada para descrever os valores específicos que o Enum aceita. Os casos do Enum são referenciados da mesma forma que as constantes de classe:

```php
$nivel = Senioridade::Especialista;
```
A vantagem dos enums é que eles abordam uma coleção de valores constantes. Enums agem basicamente da mesma maneira que classes e interfaces. Portanto, é possível fazer uma tipagem de que uma função aceite apenas um valor definido em um enum:

```php
class Programador {

    public function __construct(
        public string $nome,
        public Senioridade $nivel
    ){}
}
```
Neste exemplo, você pode passar o Enum `Senioridade` na classe `Programador`:

```php
$programador = new Programador("Marcello", Senioridade::Especialista);
```

## Backed enum (definindo valores)
Os valores do Enum são representados internamente por objetos, mas você pode atribuir um valor a eles se quiser; isso é útil, por exemplo, para serializá-los em um banco de dados.

```php
enum Senioridade: int {
    case Junior = 1;
    case Pleno = 2;
    case Senior = 3;
    case Especialista = 4;
}
```
Aqui, o enum `Senioridade` foi modificado para criar um enum suportado do tipo `int`.

**Aqui estão algumas regras para Enums suportados:**

- Ele deve declarar o tipo escalar na declaração do Enum. E apenas `string` ou `int` são permitidos.
- Ele deve atribuir um valor para todos os casos.
- Os valores atribuídos a cada caso devem ser do mesmo tipo escalar.
- Não deve conter casos ou valores duplicados.

Para obter o valor atribuído, utilize a propriedade `->value`:
```php
$programador->nivel->value
```
Mas, caso precise obter o nome, utilize a propriedade `->name`:
```php
$programador->nivel->name
```

## Valor Escalar para Enum

Quando queremos obter de volta o valor escalar para o Enum, podemos utilizar o método `from()`. Este método recebe o valor de string ou inteiro e o converte de volta para o Enum.

```php
Senioridade::from(3) // Senior
```
Se um valor for passado que não corresponda aos valores permitidos, haverá um erro fatal.

```php
Senioridade::from(100); // PHP fatal error
```
O código acima resultará em um erro fatal do PHP, pois o valor "100" não está presente no enum Senioridade.
Para tornar isso mais seguro, o PHP 8.1 nos fornece um método `tryFrom()` que retornará nulo em vez de lançar um erro.

```php
Senioridade::tryFrom(100) // NULL
```

## Métodos em enums
Enums podem conter métodos. Eles também suportam modificadores de visibilidade de método padrão, bem como métodos estáticos.
Por exemplo, declarando um método `label(): string` que retorna uma etiqueta amigável para um caso de enumeração.

```php
enum Senioridade: int {
    case Junior = 1;
    case Pleno = 2;
    case Senior = 3;
    case Especialista = 4;

    public function label(): string {
        return match ($this) {
            self::Junior => "Dev Junior",
            self::Pleno => "Dev Pleno",
            self::Senior => "Dev Sênior",
            self::Especialista => "Dev Especialista"
        };
    }
}
```
Para obter o valor da label, é só chamar o método que criamos  `label()`:
```php
$programador = new Programador("Marcello", Senioridade::Especialista);

$programador->nivel->label() // Dev Especialista
```
## Listando valores de enums
Você pode usar o método estático `Enum::cases()` para obter uma lista de todos os casos disponíveis dentro de um enum. Este método retorna uma matriz contendo os objetos enum reais:

```php
Senioridade::cases()
```

## Considerações finais
Esse é o grosso de um enum, mas existem muitas outras coisas que podem ser exploradas ao usar enums, as quais podem ser conferidas no RFC (Request for Comments).
Aqui está o link da RFC para a leitura completa:
https://wiki.php.net/rfc/enumerations