Try, Catch, Finally
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 68 of 91.
Now that you know how to create and throw exceptions, you need to learn how to catch them. The try-catch-finally structure lets you handle exceptions gracefully instead of letting them crash your application.
Wrap code that might throw an exception in a try block, then handle the exception in a catch block:
<?php
class Calculator {
public function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException("Cannot divide by zero");
}
return $a / $b;
}
}
$calc = new Calculator();
try {
echo $calc->divide(10, 0);
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage();
}
Output:
Error: Cannot divide by zeroYou can catch different exception types with multiple catch blocks. PHP checks them in order, so place more specific exceptions first:
<?php
try {
// risky code
} catch (InvalidArgumentException $e) {
echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
echo "Something went wrong: " . $e->getMessage();
}
The finally block runs regardless of whether an exception was thrown or caught. It's perfect for cleanup tasks like closing connections:
<?php
try {
echo "Attempting operation\n";
throw new Exception("Failed");
} catch (Exception $e) {
echo "Caught: " . $e->getMessage() . "\n";
} finally {
echo "Cleanup complete";
}
Output:
Attempting operation
Caught: Failed
Cleanup completeThe finally block executes even if you return from within the try or catch blocks, making it reliable for essential cleanup operations.
Challenge
EasyLet's build a file processing system that demonstrates how try-catch-finally works together to handle errors gracefully while ensuring cleanup always happens.
You'll organize your code across three files:
FileException.php— Create a customFileExceptionclass that extendsException. This will represent file-related errors in your system.FileProcessor.php— Create aFileProcessorclass that simulates file operations. Include the FileException file. Your class should have:- A private boolean property
$isOpeninitialized tofalse - A method
open(string $filename): voidthat sets$isOpentotrueand prints"Opening: [filename]". If the filename is"invalid.txt", throw aFileExceptionwith the message"Cannot open file" - A method
process(): voidthat prints"Processing file...". If$isOpenisfalse, throw aRuntimeExceptionwith the message"File not open" - A method
close(): voidthat sets$isOpentofalseand prints"File closed" - A method
isOpen(): boolthat returns the current state
- A private boolean property
main.php— Include the FileProcessor file. You'll receive one input: a filename.Create a
FileProcessorand use atry-catch-finallystructure to:- In the
tryblock: callopen()with the filename, then callprocess() - Catch
FileExceptionfirst and print"File error: [message]" - Catch
RuntimeExceptionand print"Runtime error: [message]" - In the
finallyblock: check if the file is open usingisOpen(), and if so, callclose(). Then print"Cleanup complete"
- In the
The finally block ensures that cleanup happens whether the operations succeed or fail. This pattern is essential for managing resources like files, database connections, or network sockets where cleanup must occur regardless of what happens during processing.
Cheat sheet
Use try-catch-finally to handle exceptions gracefully and ensure cleanup code always runs:
<?php
try {
// code that might throw an exception
} catch (ExceptionType $e) {
// handle the exception
echo $e->getMessage();
}
Catch multiple exception types with separate catch blocks. Place more specific exceptions first:
<?php
try {
// risky code
} catch (InvalidArgumentException $e) {
echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
echo "Something went wrong: " . $e->getMessage();
}
The finally block executes regardless of whether an exception was thrown or caught, making it ideal for cleanup operations:
<?php
try {
// attempt operation
} catch (Exception $e) {
// handle error
} finally {
// cleanup code runs always
}
Try it yourself
<?php
require_once 'FileProcessor.php';
// Read input
$filename = trim(fgets(STDIN));
// TODO: Create a FileProcessor instance
// TODO: Use try-catch-finally structure:
// - In try block: call open() with the filename, then call process()
// - Catch FileException first and print "File error: [message]"
// - Catch RuntimeException and print "Runtime error: [message]"
// - In finally block: check if file is open using isOpen(), if so call close()
// Then print "Cleanup complete"
?>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