Exception Classes
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 66 of 91.
In PHP, exceptions are objects used to signal that something went wrong during execution. The base class for all exceptions is Exception, and understanding its structure helps you handle errors effectively in your OOP applications.
When you throw an exception, you create an instance of the Exception class (or a subclass) with a message describing what went wrong:
<?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);
This would produce an uncaught exception error with the message "Insufficient funds".
PHP provides several built-in exception classes for different situations. InvalidArgumentException signals bad input, RuntimeException indicates errors during execution, and LogicException represents programming errors:
<?php
class Calculator {
public function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException("Cannot divide by zero");
}
return $a / $b;
}
}
Every exception object carries useful information: getMessage() returns the error message, getCode() returns an optional error code, getFile() and getLine() tell you where the exception was thrown. Using specific exception types makes your code's intent clearer and allows for more precise error handling.
Challenge
EasyLet's build an inventory management system that uses PHP's built-in exception classes to signal different types of problems. You'll create a product inventory where operations can fail in specific, meaningful ways.
You'll organize your code across three files:
Product.php— Create aProductclass that represents an item in inventory. Use constructor promotion for a public$sku(string), a public$name(string), and a private$quantity(int). Your class should have:- A method
getQuantity(): intthat returns the current quantity - A method
addStock(int $amount): voidthat increases the quantity. If the amount is less than 1, throw anInvalidArgumentExceptionwith the message"Amount must be positive" - A method
removeStock(int $amount): voidthat decreases the quantity. If the amount is less than 1, throw anInvalidArgumentExceptionwith the message"Amount must be positive". If the amount exceeds the current quantity, throw aRuntimeExceptionwith the message"Insufficient stock"
- A method
Inventory.php— Create anInventoryclass that manages a collection of products. Include the Product file. Your class should have:- A private array to store products indexed by SKU
- A method
addProduct(Product $product): voidthat adds a product. If a product with the same SKU already exists, throw aLogicExceptionwith the message"Product already exists: [sku]" - A method
getProduct(string $sku): Productthat returns a product by SKU. If not found, throw anInvalidArgumentExceptionwith the message"Product not found: [sku]"
main.php— Include the Inventory file. You'll receive three inputs: a SKU, a product name, and an operation ("add","remove", or"duplicate").Create an
Inventoryand add a newProductwith the given SKU, name, and an initial quantity of10.Based on the operation:
"add": CalladdStock(5)on the product, then print"Stock updated: [quantity]""remove": CallremoveStock(15)on the product (this should throw an exception)"duplicate": Try to add another product with the same SKU (this should throw an exception)
When an exception is thrown, print the exception's class name followed by
": "and the exception's message. Use PHP'sget_class()function to get the class name.
This challenge demonstrates how different exception types communicate different kinds of problems — invalid input, runtime failures, and logic errors — making your code's error handling more precise and meaningful.
Cheat sheet
In PHP, exceptions are objects that signal errors during execution. The base class is Exception.
To throw an exception, create an instance with a descriptive message:
<?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;
}
}
PHP provides built-in exception classes for different situations:
InvalidArgumentException— signals bad inputRuntimeException— indicates errors during executionLogicException— represents programming errors
<?php
class Calculator {
public function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException("Cannot divide by zero");
}
return $a / $b;
}
}
Exception objects provide useful methods:
getMessage()— returns the error messagegetCode()— returns an optional error codegetFile()— returns the file where the exception was throwngetLine()— returns the line number where the exception was thrown
Use get_class() to retrieve the class name of an exception object.
Try it yourself
<?php
require_once 'Inventory.php';
// Read inputs
$sku = trim(fgets(STDIN));
$name = trim(fgets(STDIN));
$operation = trim(fgets(STDIN));
try {
// TODO: Create an Inventory
// TODO: Create a Product with the given SKU, name, and initial quantity of 10
// TODO: Add the product to the inventory
// TODO: Based on the operation:
// - "add": Call addStock(5) on the product, then print "Stock updated: [quantity]"
// - "remove": Call removeStock(15) on the product
// - "duplicate": Try to add another product with the same SKU
} catch (Exception $e) {
// TODO: Print the exception class name followed by ": " and the message
// Hint: Use get_class($e) to get the class name
}
?>This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern