An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. PHP uses exceptions to handle errors and other exceptional events.
As in many other languages, an exception can be thrown, and caught. You can throw an exception using the throw
keyword that in PHP 8 became an expression that may be used in any expression context, while in previous versions it was a statement that had to be in its own line.
To facilitate the catching of exceptions, the code should be surrounded by a try
block that must have at least one matching catch
or finally
blocks. In case an exception gets thrown, and its current scope doesn’t have a catchable block, the exception will "bubble up" or be sent to a "higher scope".
If the handling of an exception implements both the catch
and finally
blocks, be advised that all finally
blocks encountered in the way of the exception event will be executed, even when the event has already passed through the catch
block.
Finally, if an exception went all the way to the global scope without finding a matching catchable block, your code will terminate with a fatal error unless the app has a global exception handler set, like the one that Laravel has.
Content
Throwing exceptions
Now that we understood the structure around exception events, let’s see a couple of examples of how we can throw and catch exceptions.
Let’s say we want to parse a PHP object to JSON, we would probably use the json_encode()
function for that. This function not always will be able to transform the given object to JSON for various reasons, and when this happens, the function will return false
to let us know that the transformation failed.
In some ways, we can say that if the transformation of the object fails our code got disrupted from the normal flow of instructions, since we instructed the code to get us a JSON, and we got a boolean instead.
With that being said, let’s see in the example down below, how we can use an exception to trigger an event informing that something out of the normal flow has happened.
<?php
class Person
{
private $props = [];
public function __construct(
private string $name = '',
private string $lastName = ''
) {
$this->props = [
'name' => $this->name,
'last_name' => $this->lastName,
];
}
public function toJson($options = 0.0)
{
$jsonEncoded = json_encode($this->props, $options);
if ($jsonEncoded === false) {
throw new JsonEncodeException();
}
return $jsonEncoded;
}
}
The toJson()
function is responsible for transforming his class into a JSON, as mentioned before, we were going to use the json_encode()
which is being called at the first line of the function and has its returned value stored at the $jsonEncoded
object.
Next, we have a conditional that checks if the $jsonEncoded
is false
, in case it is an exception will be thrown because the normal flow of our code got disrupted.
Then, if the flow of our code didn’t get disrupted, we would just return the $jsonEncoded
object that at this point is a JSON with the correspondent values of the $props from our Person class.
The try and catch blocks
To catch the exception potentially thrown by the Person class, we have to use a try
with a matching catch
block, as the example down below shows.
try {
$person = new Person('Jack', 'Miras');
$personAsJson = $person->toJson();
} catch(JsonEncodeException $e) {
echo "Exception has been caught";
}
At the first line of the try
block, we are creating a person object, passing a name and a last name as parameters in its constructor.
Next, we are calling the toJson()
function out of the $person
object. If the object got correctly transformed into a JSON, the $personAsJson
object would receive a JSON string as a result. Otherwise, an exception would be thrown, and the catch
block would be triggered.
Thereafter, if an exception gets thrown and the catch
block gets triggered, it would first check if the exception being intercepted is an instance of the JsonEncodeException class. If that’s the case, the catch
block would take this exception event, passing him to its handling block where is printing a message telling that the exception has been caught.
The finally block
Another way of handling the exception potentially thrown by the Person class would be to use a finally
block to match the try
block defined, as the example down below show.
try {
$person = new Person('Jack', 'Miras');
$personAsJson = $person->toJson();
} finnaly {
echo "Converting person to JSON failed";
}
As in the previous example, at the try
block, we are creating a person object and calling the toJson()
function out of it. If the object gets correctly transformed, the $personAsJson
would receive a JSON string. Otherwise, an exception would be thrown.
Thereafter, if an exception gets thrown, the finally
block will be triggered even though the exception event has been already handled by a catch block.
If that’s the case, the finally
block would take in this exception event and printing a message telling that the conversion of the person object into JSON failed.
Now that you have a better understanding of what are exceptions and what they are used for, it’s time for us to move to the next post of this series.
Happy coding!
Top comments (2)
Can't believe I didn't know about the
finally
block (you've got a typo in your code block, by the way –finnaly
)Thanks for the heads-up, I've fixed the typo.
A third and a fourth part of this series will be published in the coming weeks, there is more content there that you may find interesting… In case you have the time, don't forget to check it out.