There is no rule without exception
An exception is something which happens out of the normal flow of things. It's an unusual behavior, or simply an error.
What are exceptions and why should I mind?
If you've been developing applications for a while you must have heard of Exceptions
or at least Errors
. Two phenomenon that are common to all programming language and to which all programmers are used to. They sound negative. There are what programmers may not like to hear about. In fact, to many of us, it's a nightmare. This ideology has made them to become a dark-side of coding that most training resources don't talk much about.
But, for good programmers, this is some kind of Yin & Yang, you remember? This natural principle in which the good doesn't exist if the bad doesn't, and vice-versa. You can't have the good if you don't handle the bad very well.
In this post I would like to share with you what Exceptions are in PHP and how useful it's to handle them.
Errors are abnormal behaviors of your code, or a software. We can't avoid errors when coding. It might be that you forgot a semi-colon, a bracket, a quote, or an entire function, etc. then PHP will yell at you to make you understand that something is missing. Errors are our first, closest guides and mentors in software development. Even the famous TDD strategy is based on that. And, like I use to say, I love coding with PHP because of how it handles errors. It's to me a complete guide to new learners.
As you may have noticed it, PHP has many ways of handling errors and how to show them. Aside the normal PHP handling you as a programmer can also decide of how to handle errors too. Let's see how error handling can be done both PHP side and user(programmer) side:
E_ERROR: They are fatal run-time errors. When something important that is required(missing semi-colon, brackets,...) for the application to run is missing then PHP gives such type of errors. When such errors occur, PHP stops executing at the place it happened.
Example:
<?php
echo $apple
You receive this:
PHP Parse error: syntax error, unexpected end of file, expecting ',' or ';' in ... on line ...
E_NOTICE: Are notices. This level of error call your attention on some little things which could make you application to mis-behave.
Example:
<?php
echo $apple;
You receive this:
PHP Notice: Undefined variable: apple in ... on line ...
These are cases where PHP handles errors for us. But let look at the following case:
<?php
function post()
{
$data = $_POST;
return $data;
}
var_dump(post());
Basically it won't cause any PHP error like a warning, a notice, etc. But this code contains errors which could harm your application if you don't handle them appropriately. Imagine we need to access a specific data in `$_POST` like `$_POST['name']`, PHP will yell an error. So, you must handle such cases yourself like following:
<?php
function post()
{
$data = isset($_POST) && sizeof($_POST) > 0 ? $_POST : null;
if (!is_null($data)) {
// save data
return true;
}
return false;
}
var_dump(post());
With this we has less options of outcome now, either the data exists and saved and we have true
or there is no data and we have false
;
Now imagine a case(an example of file upload) where we can have many possibilities of returning values like in following:
<?php
function upload($file)
{
if ($file['error'] != 0) {
// Upload error
return 0;
}
if ($file['size'] > 20000) {
// File too heavy
return 1;
}
if (!in_array($file_extension, $accepted_extensions)) {
// Extension not accepted
return 2;
}
//...
}
We have to specify an error code in order to distinguish at what point in time something went wrong when calling the function. In time this becomes very inconsistent and unclean. So, the best way to do that is through exceptions.
Exception handling
Exception handling is not a standard practice which has a specific formula. Based on the case, the programmer makes sure of this: if something MUST go wrong somewhere, halt the execution and move to a different section of code to handle the case. This can literally be illustrated with this:
<?php
if(true){
// do the right thing
}elseif(false){
// do some alert thing
}else{
// do some final warning thing
}
But this is not an exception in PHP. For an error to be an exception it must be thrown with the key word throw
and/or cought with the key word catch()
. But before something can be thrown and cought it must belong to the Exception
class which implements the throwable
interface(as of PHP 7). Now let look at an example of how to catch a PDO exception:
<?php
try{
$dsn ='mysql:host=localhost;dbname=test;';
$user = '';
$password = '';
$db = new PDO($dsn, $user, $password);
}catch(PDOException $e)
{
echo $e->getMessage();
}
This will display: SQLSTATE[28000] [1045] Access denied for user 'zooboole'@'localhost' (using password: NO)
Note the object($e
) which contains the error message is of PDOException
type which extends Exception
.
Throwing exceptions
We saw how to can catch exception through the try...catch
structure. But it's not every time you must catch your exceptions. Sometimes you will just throw them and later on you can handle them. Let see how we can throw and exception of Exception
type:
<?php
function divideByTwo($number)
{
if (!$number) {
throw new Exception('Division by zero not possible');
}else{
return $number / 2;
}
}
try{
// try with 0
echo divideByTwo(2); // 1
}catch(Exception $e)
{
echo $e->getMessage();
}
Note: DivisionByZeroError exception class is available in PHP 7
When you run this code you will have 1. If you provide zero(0) as value the divideByTwo()
method, an exception of Exception
type will be thrown.
If I don't catch the exception(by just calling echo divideByTwo(2);
) or I try to catch a different type of exception PHP will warn me on some uncaught exception(Uncaught exception 'Exception' with message 'Division by zero not possible' in...on line ...
). And here come sometimes a big problem with Exception
class. Every time an exception it its type is thrown, it must be cought otherwise it will raise a warning.
Custom exception
To create a custom exception class, your class must extend Exception
and/or implement throwable
interface. You can also extend any child class of Exception
. You may ask me why would we need to create our custom exception? The answer is simple, it's to customize the way Exception
works. When creating applications like a framework, you may like to organize your exceptions based on its structure. You may have exceptions for HTTP requests, your dependency container, not found exceptions, etc. A great example of this is the famous symfony HttpKernel package.
So let's see how we can create a simple excpetion class:
<?php
/**
* Custom integer exception class
*/
class NotIntegerException extends Exception
{
public function notInt()
{
return 'Not integer';
}
}
//// TEST OUR CUSTOM EXCEPTION
function isInter($number)
{
if (!is_int($number)) {
throw new NotIntegerException();
}else{
return $number;
}
}
try {
echo isInter(5); // 5
echo isInter('str'); // Not integer
} catch (NotIntegerException $e) {
echo $e->notInt();
}
Resources
Here are some resources where you can go and improve your knowledge on PHP exceptions:
Standard PHP Library Exceptions
Errors and Exceptions on PHP The Right Way
Outside PHP
Things every Java developer must know about Exception handling
Conclusion
Well, this was a great time reading on Exceptions. I hope from now on you will write more of them to insure some robustness to your applications. I also hope this will help any beginner to know about their existence so that he should be surprise to meet them while reading other people's codes. To finish, I am exception this will be a good starting point to your mastery of exceptions.
Thanks for reading. Help me by sharing this with your friends.
Last updated 2024-01-11 UTC