This post covers the Exceptions section of the OOP chapter when studying for the Zend PHP 7 Certification.
An exception can be thrown and caught within PHP like many other programming languages. In PHP, the throw
keyword is used to throw an exception.
When wrapping code within a try
block, the catch
part of the block is used to facilitate the catching of potential exceptions.
Each try
must have at least one corresponding catch
or finally
block.
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo "Hello World\n";
This would output the following.
0.2
Caught exception: Division by zero.
Hello World
So although an exception has been caught, execution continues as normal.
The thrown object must be an instance of the Exception
class or a subclass of Exception
. Trying to throw an object that is not will result in a fatal error.
In PHP 5.5 and later, a finally
block may also be specified after or instead of catch
blocks. Code within the finally
block will always be executed after the try
and catch
blocks, regardless of whether an exception has been thrown, and before normal execution resumes.
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo "First finally.\n";
}
try {
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo "Second finally.\n";
}
// Continue execution
echo "Hello World\n";
Using a finally
block would be useful if the user needs to clean resources such as closing a connection, or deleting temporary files.
When catching an exception inside a namespace it is important that you escape to the global space.
<?php
namespace SomeNamespace;
class SomeClass {
function SomeFunction() {
try {
throw new Exception('Some Error Message');
} catch (\Exception $e) {
var_dump($e->getMessage());
}
}
}
This would output:
0.2
First finally.
Caught exception: Division by zero.
Second finally.
Hello World
In PHP 7, a TypeError
can be thrown from mis-matched parameter or return types.
<?php
function add(int $num1, int $num2)
{
return $num1 + $num2;
}
try {
$value = add('num1', 'num2');
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
Outputs: Argument 1 passed to add() must be of the type integer, string given
Also in PHP 7, a Throwable
interface is introduced. This is the base interface for any object that can be thrown via a throw
statement, including the base Error
and Exception
classes.
The Exception
class contains some useful methods that can be used when throwing an exception.
final public string getMessage ( void )
final public Exception getPrevious ( void )
final public mixed getCode ( void )
final public string getFile ( void )
final public int getLine ( void )
final public array getTrace ( void )
final public string getTraceAsString ( void )
Even though a Throwable
interface exists in PHP 7, any custom exceptions classes created must extend the base Exception
class.
<?php
class MyExceptionClass extends Exception
{
public function __construct($message, $code = 0, Exception $previous = null) {
// some code
parent::__construct($message, $code, $previous);
}
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function customFunction() {
echo "A custom function for this type of exception\n";
}
}
View the other sections:
Note: This article is based on PHP version 7.0