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 entender sua estrutura ajuda você a lidar com erros de forma eficaz em suas aplicações OOP.
Quando você lança uma exceção, você cria uma instância da classe Exception (ou 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 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;
}
}
Cada objeto de exceção carrega 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. O uso de 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 construir um sistema de gerenciamento de inventário que utiliza as classes de exceção integradas do PHP para sinalizar diferentes tipos de problemas. Você criará um inventário de produtos onde 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 representa 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 gerencia uma coleção de produtos. Inclua o arquivo Product. Sua classe deve ter:- Um array privado para armazenar produtos indexados pelo SKU
- Um método
addProduct(Product $product): voidque adiciona um produto. Se um produto com o mesmo SKU já existir, 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, 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 a 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.
Folha de consulta
No PHP, as exceções são objetos que sinalizam erros durante a execução. A classe base é Exception.
Para lançar uma exceção, crie uma instância com uma mensagem descritiva:
<?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;
}
}
O PHP fornece classes de exceção integradas para diferentes situações:
InvalidArgumentException— sinaliza uma entrada inválidaRuntimeException— indica erros durante a execuçãoLogicException— 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;
}
}
Objetos de exceção fornecem métodos úteis:
getMessage()— retorna a mensagem de errogetCode()— retorna um código de erro opcionalgetFile()— retorna o arquivo onde a exceção foi lançadagetLine()— retorna o número da linha onde a exceção foi lançada
Use get_class() para recuperar o nome da classe de um objeto de exceção.
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, nome e quantidade inicial de 10 fornecidos
// TODO: Adicionar o produto ao inventário
// TODO: Com base na operação:
// - "add": Chamar addStock(5) no produto, então imprimir "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 por ": " e a mensagem
// Dica: 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 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