PHP Error Handling Explained

December 8th, 2011 Leave a comment
Like the article?

Error handling is the process of catching errors and unexpected behavior from your program and dealing with them appropriately. When developers write code they always seem to leave error handling for the end instead of making it part of the development process. Part of being a good developer is setting up your applications to handle errors gracefully and without causing trouble for the user. Developers that are new to PHP sometimes complain that there is no built-in error handling functionality, but what they haven’t learned yet is that the functionality is there – you just have to make it work for you. It is very easy to use error and exception handling in PHP. This article talks about some of the methods of error checking that are available in PHP and provides some hands-on examples for you to use as well as the reasons you should use it.

The Try/Catch Block

Exceptions are a simple way of helping the program flow determine if there is an error and recover if one was encountered. This gives you a chance to handle the error in a manner that helps the script recover and continue running so the whole thing doesn’t come to a stop. You can also customize exceptions to have a specific error for the user if the problem is something preventable or fixable by them, such as input problems or a bad file.

When handling exceptions in PHP we use the try...catch block:

try {
	$firstNumber = 100;
	
	if ($firstNumber < 200) {
		throw new Exception("Number too low");
	}
} catch (Exception $ex) {
	echo "Caught Exception\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
}

The try catch block allows you to specify any amount of code in the try section that may generate an error and then handle the error in the catch portion of the block. Otherwise, the catch code does not execute and no error message is printed. These try...catch structures provide a safety-net for code that has the potential to create an error and keeps the code from breaking if one occurs. They are considered to be the easiest and simplest form of error handling.

Generally speaking, catching a generic "Exception" class isn’t recommended and multiple catch blocks are an acceptable way to deal with different types of exceptions that may occur by specifying which exception type should be caught by each block. When we specify different catch blocks with different exceptions, PHP makes the determination which catch block to run so you can be more specific in how you handle different error situations. For example:

<?php
class MyException extends Exception { }

try {
	$firstNumber = 100;

	if ($firstNumber < 200) {
		throw new MyException("Number too low");
	} else {
		echo $firstNumber;
	}
} catch (MyException $ex) {
	echo "Caught MyException\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
} catch (Exception $ex) {
	echo "Caught Exception\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
}
?>

In this example we have a generic "Exception" catch block and a more specific exception we have defined as "MyException". When we throw the MyException, the appropriate block fires to handle it. If the statement proceeds to the else section and the MyException is never thrown the try...catch structure would still continue to protect us by catching any other exceptions that may occur and executing the generic "Exception" block to handle it.

In PHP, exceptions will always match to the first block that can handle that exception’s particular class or any parent of that class. Here is an example of why this can get tricky:

<?php
class MyException extends Exception { }
class OtherException extends MyException { }

try {
	$firstNumber = 100;

	if ($firstNumber < 200) {
		throw new OtherException("Number too low");
	} else {
		echo $firstNumber;
	}
} catch (MyException $ex) {
	echo "Caught MyException\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
} catch (OtherException $ex) {
	echo "Caught OtherException\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
} catch (Exception $ex) {
	echo "Caught Exception\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
}
?>

The output of this code may not be what you think. When the if statement throws the OtherException the MyException block will execute, not the OtherException. Confused? Well, like I said before, PHP matches the first catch block with an exception class that can handle the exception. Since OtherException inherits from MyException, it is qualified to handle it. If you wanted to ensure this wouldn’t happen, you would have to reorder the catch blocks, like so:

<?php
class MyException extends Exception { }
class OtherException extends MyException { }

try {
	$firstNumber = 100;

	if ($firstNumber < 200) {
		throw new OtherException("Number too low");
	} else {
		echo $firstNumber;
	}
} catch (OtherException $ex) {
	echo "Caught OtherException\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
} catch (MyException $ex) {
	echo "Caught MyException\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
} catch (Exception $ex) {
	echo "Caught Exception\n";
	echo "Message: {
		$ex->getMessage()
	}\n";
}
?>

Now, when OtherException is thrown, it’s catch block will handle it instead of MyException because we have change the order of the catch blocks. Using the try...catch form of debugging is an excellent way to get started using exception handling in your PHP code. Remember to put any code that can break inside the try section and write the appropriate catch blocks to handle errors.

Writing Custom Exceptions

As we saw in the previous section, we can create our own custom exception classes that allow us to define how the exception will be handled. We set up these custom exceptions in the first part of our example but we didn’t define any behaviors for them. An exception is an object and we can define constructors and functions for the new exception object. So let’s write a new exception:

class MyCustomException extends Exception {
	private $messageText;

	function __construct($messageText) {
		$this->message = $messageText;
	}
	
	function getMessage() {
		return $this->message;
	}
}

In this example we have a custom exception class named MyCustomException. Your next exception classes must extend from the base Exception class or they will not be able to be thrown. This custom exception receives a string for the message text in its constructor and has one function that allows that message to be returned when necessary. Of course you can add more functionality to your custom exceptions that allows you to handle the exception for the user and keep the program moving.

If you would like more information on the Exception class in PHP, you can find the documentation here:

Custom Error Handlers

PHP has a built-in system for handling errors that arise during programming execution. These error handlers are functions that you write to deal with these errors as they occur. This is a little different solution than what we have talked about this far with the try…catch structure. For this method, you create a function that will handle the error, such as:

function MyErrorHandler($number, $string, $file, $line, $context) {
	//code to handle the error goes here
}

When writing a custom error handler function there are some different parameters involved, which I will explain:

  • $number is the integer number for the Error Reporting Level
  • $string is the error description
  • $file defines the file in which the error occurred
  • $line is the line number where the error occurred
  • $context (optional) contains an array of every variable that was in scope when the error occurred.

The code in the function should be used to log errors using either text files, XML, or database storage. You may also want to have an email alert in certain error handling functions. You may also put code that deals with any consequences of the error such as freeing resources or closing connections.

Once you have your function ready to handle errors, you just need to register it with the set_error_handler() function so PHP knows that this function is your error handler for these types of problems.

set_error_handler("MyErrorHandler");

Done! Your new custom error handler function is ready to use.

When recording or reporting errors it is important to have the necessary details, such as:

  • The file name and path where the error occurred
  • The line number and function name
  • The error type (conversion, validation etc…)
  • A short description of the problem for the user
  • A more detailed diagnostic description for the administrator. Stack trace data or object flush data is often very helpful.

There are many reasons why error handling should become an intimate part of your PHP application development. Now that you understand how to use the different types of exception and error handling methods available, there is no reason not to use them.

Help us spread the word!
  • Twitter
  • Facebook
  • LinkedIn
  • Pinterest
  • Delicious
  • DZone
  • Reddit
  • Sphinn
  • StumbleUpon
  • Google Plus
  • RSS
  • Email
  • Print
If you liked this article, consider enrolling in one of these related courses:
Don't miss another post! Receive updates via email!

Comment