Classes de Exceção
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy. Lição 66 de 91.
No PHP, as exceções são objetos usados para sinalizar que algo deu errado durante a execução. A classe base para todas as exceções é Exception, e compreender sua estrutura ajuda você a lidar com erros de maneira eficaz em suas aplicações de POO.
Ao lançar uma exceção, você cria uma instância da classe Exception (ou de uma subclasse) com uma mensagem descrevendo o que deu errado:
<?php
class BankAccount {
public function __construct(private float $balance = 0) {}
public function withdraw(float $amount): float {
if ($amount > $this->balance) {
throw new Exception("Insufficient funds");
}
$this->balance -= $amount;
return $amount;
}
}
$account = new BankAccount(100);
$account->withdraw(150);
Isso produziria um erro de exceção não capturada com a mensagem "Insufficient funds".
O PHP fornece várias classes de exceção integradas para diferentes situações. InvalidArgumentException sinaliza uma entrada inválida, RuntimeException indica erros durante a execução, e LogicException representa erros de programação:
<?php
class Calculator {
public function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException("Cannot divide by zero");
}
return $a / $b;
}
}
Todo objeto de exceção contém informações úteis: getMessage() retorna a mensagem de erro, getCode() retorna um código de erro opcional, getFile() e getLine() informam onde a exceção foi lançada. Usar tipos de exceção específicos torna a intenção do seu código mais clara e permite um tratamento de erros mais preciso.
Desafio
FácilVamos criar um sistema de gerenciamento de estoque que usa as classes de exceção integradas do PHP para sinalizar diferentes tipos de problemas. Você criará um inventário de produtos no qual as operações podem falhar de maneiras específicas e significativas.
Você organizará seu código em três arquivos:
Product.php: crie uma classeProductque represente um item no inventário. Use a promoção de construtor para um$sku(string) público, um$name(string) público e um$quantity(int) privado. Sua classe deve ter:- Um método
getQuantity(): intque retorna a quantidade atual - Um método
addStock(int $amount): voidque aumenta a quantidade. Se o valor for menor que 1, lance umaInvalidArgumentExceptioncom a mensagem"Amount must be positive" - Um método
removeStock(int $amount): voidque diminui a quantidade. Se o valor for menor que 1, lance umaInvalidArgumentExceptioncom a mensagem"Amount must be positive". Se o valor exceder a quantidade atual, lance umaRuntimeExceptioncom a mensagem"Insufficient stock"
- Um método
Inventory.php: crie uma classeInventoryque gerencie uma coleção de produtos. Inclua o arquivo Product. Sua classe deve ter:- Um array privado para armazenar produtos indexados por SKU
- Um método
addProduct(Product $product): voidque adiciona um produto. Se já existir um produto com o mesmo SKU, lance umaLogicExceptioncom a mensagem"Product already exists: [sku]" - Um método
getProduct(string $sku): Productque retorna um produto pelo SKU. Se não for encontrado, lance umaInvalidArgumentExceptioncom a mensagem"Product not found: [sku]"
main.php: inclua o arquivo Inventory. Você receberá três entradas: um SKU, um nome de produto e uma operação ("add","remove"ou"duplicate").Crie um
Inventorye adicione um novoProductcom o SKU, o nome e uma quantidade inicial de10fornecidos.Com base na operação:
"add": chameaddStock(5)no produto e, em seguida, imprima"Stock updated: [quantity]""remove": chameremoveStock(15)no produto (isso deve lançar uma exceção)"duplicate": tente adicionar outro produto com o mesmo SKU (isso deve lançar uma exceção)
Quando uma exceção for lançada, imprima o nome da classe da exceção seguido por
": "e pela mensagem da exceção. Use a funçãoget_class()do PHP para obter o nome da classe.
Este desafio demonstra como diferentes tipos de exceção comunicam diferentes tipos de problemas — entrada inválida, falhas em tempo de execução e erros de lógica — tornando o tratamento de erros do seu código mais preciso e significativo.
Experimente você mesmo
<?php
require_once 'Inventory.php';
// Ler entradas
$sku = trim(fgets(STDIN));
$name = trim(fgets(STDIN));
$operation = trim(fgets(STDIN));
try {
// TODO: Criar um Inventory
// TODO: Criar um Product com o SKU, name e quantidade inicial de 10 fornecidos
// TODO: Adicionar o produto ao inventário
// TODO: Com base na operação:
// - "add": Call addStock(5) on the product, then print "Stock updated: [quantity]"
// - "remove": Chamar removeStock(15) no produto
// - "duplicate": Tentar adicionar outro produto com o mesmo SKU
} catch (Exception $e) {
// TODO: Imprimir o nome da classe da exceção seguido de ": " e a mensagem
// Hint: Use get_class($e) para obter o nome da classe
}
?>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 OOP
Arquivos externosIntrodução à OOPClasses vs. objetosA palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodosA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em ProfundidadeGetters e SettersOcultação de InformaçõesPromoção de Construtor (8.0)Recapitulação - Sistema de Registros de Alunos10Conceitos Avançados de OOP
Composição vs. HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibras (PHP 8.1)Análise Profunda da 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 às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataTipagem 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 NulosTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadaTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários3Propriedades de Classes
Propriedades de Instância vs. EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Somente para Leitura (PHP 8.1)Recapitulação - Gerenciador de Contas Bancárias6Polimorfismo
Revisão da Sobrescrita de MétodosPolimorfismo via InterfacesIndicação de Tipos e Tipos UnionVinculação Estática TardiaRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos entre 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 StrategyPratique por conta própria: Compilador de PHP online