Enums (PHP 8.1)
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 59 de 91.
Antes do PHP 8.1, representar um conjunto fixo de valores, como status ou tipos, significava usar constantes de classe ou strings mágicas — ambas abordagens propensas a erros. Enums (enumerações) fornecem uma maneira adequada de definir um tipo que pode conter apenas valores específicos e predefinidos.
Defina um enum usando a palavra-chave enum:
<?php
enum Status {
case Pending;
case Active;
case Completed;
}
$status = Status::Active;
echo $status->name;
Saída:
ActiveEnums também podem ter valores de suporte (backed values) - valores de string ou inteiros associados a cada caso. Isso é útil ao armazenar enums em bancos de dados ou APIs:
<?php
enum Status: string {
case Pending = 'pending';
case Active = 'active';
case Completed = 'completed';
}
$status = Status::Active;
echo $status->value;
Saída:
activeBacked enums fornecem um método from() para criar um enum a partir de seu valor, e tryFrom() que retorna null em vez de lançar um erro para valores inválidos:
<?php
$status = Status::from('active'); // Retorna Status::Active
$invalid = Status::tryFrom('unknown'); // Retorna null
Enums também podem conter métodos, tornando-os poderosos para encapsular lógica relacionada. Eles funcionam perfeitamente com type hints, garantindo que suas funções aceitem apenas valores válidos - sem a necessidade de verificar se uma string corresponde às opções esperadas.
Desafio
FácilVamos construir um sistema de gerenciamento de pedidos que utiliza enums para representar os status dos pedidos de forma segura em termos de tipo. Em vez de depender de strings que podem ser digitadas incorretamente ou ser inválidas, você criará um backed enum que mapeia cada status para um valor amigável ao banco de dados.
Você organizará seu código em três arquivos:
OrderStatus.php— Crie um string-backed enum chamadoOrderStatuscom quatro casos:Pendingassociado a'pending'Processingassociado a'processing'Shippedassociado a'shipped'Deliveredassociado a'delivered'
label()que retorna uma descrição legível para cada status:- Pending retorna
"Awaiting confirmation" - Processing retorna
"Being prepared" - Shipped retorna
"On the way" - Delivered retorna
"Order complete"
Order.php— Crie uma classeOrderque utiliza o enum. Inclua o arquivo OrderStatus. A classe deve:- Aceitar um ID de pedido (string) e um
OrderStatusem seu construtor usando promoção de construtor (constructor promotion) - Ter um método
getInfo()que retorna"Order [id]: [status label]" - Ter um método
getStatusValue()que retorna o valor associado (backed value) do status (útil para armazenamento em banco de dados)
- Aceitar um ID de pedido (string) e um
main.php— Inclua o arquivo Order. Você receberá duas entradas: um ID de pedido e uma string de status (como"shipped"). UsetryFrom()para converter com segurança a string de entrada em um enumOrderStatus. Se o status for válido, crie umOrdere imprima duas linhas:- O resultado de
getInfo() - O resultado de
getStatusValue()
"Invalid status".- O resultado de
Este desafio demonstra como os enums fornecem segurança de tipo — sua classe Order só pode aceitar status válidos, e o método tryFrom() permite que você manipule a entrada do usuário com segurança, sem arriscar valores inválidos.
Folha de consulta
Enums fornecem uma maneira segura em termos de tipo (type-safe) para definir um conjunto fixo de valores. Defina um enum usando a palavra-chave enum:
<?php
enum Status {
case Pending;
case Active;
case Completed;
}
$status = Status::Active;
echo $status->name; // Saída: Active
Backed enums associam valores de string ou inteiros a cada caso:
<?php
enum Status: string {
case Pending = 'pending';
case Active = 'active';
case Completed = 'completed';
}
$status = Status::Active;
echo $status->value; // Saída: active
Use from() para criar um enum a partir de seu valor, ou tryFrom() que retorna null para valores inválidos:
<?php
$status = Status::from('active'); // Retorna Status::Active
$invalid = Status::tryFrom('unknown'); // Retorna null
Enums podem conter métodos para encapsular a lógica relacionada:
<?php
enum Status: string {
case Pending = 'pending';
case Active = 'active';
public function label(): string {
return match($this) {
self::Pending => 'Awaiting',
self::Active => 'In Progress',
};
}
}
Experimente você mesmo
<?php
require_once 'Order.php';
// Ler a entrada
$orderId = trim(fgets(STDIN));
$statusString = trim(fgets(STDIN));
// TODO: Use OrderStatus::tryFrom() para converter com segurança a string de status para um enum
// tryFrom() retorna null se o valor for inválido
// TODO: Se o status for válido, crie um Order e imprima:
// - O resultado de getInfo()
// - O resultado de getStatusValue()
// TODO: Se o status for inválido, imprima "Invalid status"
?>Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodoA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em DetalhesGetters e SettersOcultação de InformaçãoPromoção de Construtor (8.0)Recapitulação - Sistema de Registro de Alunos10Conceitos Avançados de POO
Composição vs HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibers (PHP 8.1)Mergulho Profundo em Clonagem de ObjetosGeradores e Iteradores13Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository2Namespaces e Autoloading
Introdução a NamespacesA Palavra-chave usePadrão de Autoloading PSR-4Autoloader do ComposerRecapitulação - Projeto Organizado5Interfaces e Contratos
Introdução a InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataType Hinting com InterfacesRecapitulação - Calculadora de Formas8Métodos Mágicos
Introdução aos Métodos Mágicos__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e Clonagem de Objetos__serialize e __unserializeRecapitulação - Coleção Personalizada11Sistema de Tipos e Tratamento de Erros
Declarações de TiposTipos AnuláveisTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadasTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário3Propriedades de Classe
Propriedades de Instância vs EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Readonly (PHP 8.1)Recapitulação - Gerenciador de Conta Bancária6Polimorfismo
Sobrescrita de Métodos RevisitadaPolimorfismo via InterfacesType Hinting e Union TypesLate Static BindingRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos de TraitsMétodos Abstratos em TraitsTraits vs Herança12Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy