Error Handling In PHP (part 2) - Raising Hell (
Page 2 of 8 )
Thus
far, we've been dealing with errors which are automatically generated by PHP
when it encounters a problem. However, in addition to these built-in errors, PHP
also allows you to raise errors of your own.
This is accomplished via a
little function named trigger_error(), which allows you to raise any of the
three errors in the E_USER family. These errors can then be caught and handled
either by PHP's built-in error handler, or by a custom handler.
Here's a
simple example which demonstrates how this works:
<?php
// function to validate password integrity
// generates an E_USER_WARNING if password fails a test function
validatePassword($pass) {
// empty string
if(trim($pass) == "")
{
trigger_error("Empty password", E_USER_WARNING);
}
// too short
if(strlen($pass) < 5)
{
trigger_error("Password too short", E_USER_WARNING);
}
// only numeric
if(is_numeric($pass))
{
trigger_error("Password cannot contain only numbers",
E_USER_WARNING);
}
}
echo "<br>-- validating empty string -- <br>";
validatePassword("");
echo "<br>-- validating 12345 -- <br>";
validatePassword(12345);
echo "<br>-- validating Gh3 --<br>";
validatePassword("Gh3");
?>
Here's what the output looks like:
-- validating empty string --
Warning: Empty password in /usr/local/apache/htdocs/x2.php on line 10
Warning: Password too short in /usr/local/apache/htdocs/x2.php on line
16
-- validating 12345 --
Warning: Password cannot contain only numbers in
/usr/local/apache/htdocs/x2.php on line 22
-- validating Gh3 --
Warning: Password too short in /usr/local/apache/htdocs/x2.php on line
16
In this case, every time the argument to validatePassword()
fails one of the tests within the function, an E_USER_WARNING error will be
raised; this error will be caught by PHP's built-in handler and handled in the
same way as "regular" warnings - it will be displayed to the user, but script
processing will not be halted.
It's also possible to raise fatal errors
in this fashion. Consider the next example, which updates the validatePassword()
function to raise a fatal error only if the password string is empty.
<?php
// function to validate password integrity
// generates an E_USER_WARNING if password fails a test function
validatePassword($pass) {
// empty string
// trigger a fatal error
if(trim($pass) == "")
{
trigger_error("Empty password", E_USER_ERROR);
}
// too short
if(strlen($pass) < 5)
{
trigger_error("Password too short", E_USER_WARNING);
}
// only numeric
if(is_numeric($pass))
{
trigger_error("Password cannot contain only numbers",
E_USER_WARNING);
}
}
echo "<br>-- validating 12345 -- <br>";
validatePassword(12345);
echo "<br>-- validating empty string -- <br>";
validatePassword(" ");
echo "<br>-- validating Gh3 --<br>";
validatePassword("Gh3");
?>
In this case, when the second password is evaluated, a fatal
error will be raised, PHP's built-in handler will catch it, note that it is a
fatal error and terminate script execution immediately. Here's what it looks
like:
-- validating 12345 --
Warning: Password cannot contain only numbers in
/usr/local/apache/htdocs/x2.php on line 23
-- validating empty string --
Fatal error: Empty password in /usr/local/apache/htdocs/x2.php on line
11
Note that the script never reaches the third call to
validatePassword().
User-triggered errors can also be caught by a custom
error handler, in much the same way as built-in errors. Let's see how, with a
variant of the example on the previous page:
<?php
// function to validate password integrity
// generates an E_USER_WARNING if password fails a test function
validatePassword($pass) {
// empty string
// trigger a fatal error
if(trim($pass) == "")
{
trigger_error("Empty password", E_USER_ERROR);
}
// too short
if(strlen($pass) < 5)
{
trigger_error("Password too short", E_USER_WARNING);
}
// only numeric
if(is_numeric($pass))
{
trigger_error("Password cannot contain only numbers",
E_USER_WARNING);
}
}
// custom error handler
function eh($type, $msg, $file, $line, $context)
{
switch($type)
{
// user-triggered fatal error
case E_USER_ERROR:
echo "A fatal error occurred at line $line of
file $file. The error message was <b>$msg</b> <br>";
echo "<font color=red><i>Script
terminated</i></font>";
die();
break;
// user-triggered warning
case E_USER_WARNING:
echo "A non-trivial, non-fatal error occurred at
line $line of file $file. The error message was <b>$msg</b> <br>";
break;
// user-triggered notice
case E_USER_NOTICE:
echo "A trivial, non-fatal error occurred at
line $line of file $file. The error message was <b>$msg</b> <br>";
break;
}
}
// define custom handler
set_error_handler("eh");
echo "<br>-- validating 12345 -- <br>";
validatePassword(12345);
echo "<br>-- validating empty string -- <br>";
validatePassword(" ");
echo "<br>-- validating Gh3 --<br>";
validatePassword("Gh3");
?>
In this case, the user-generated errors are routed to the
custom error handler, which prints a user-defined error message and - if the
error was defined as fatal - terminates script execution.
Here's what it
looks like:
-- validating 12345 --
A non-trivial, non-fatal error occurred at line 23 of file
/usr/local/apache/htdocs/x2.php. The error message was Password cannot
contain only numbers
-- validating empty string --
A fatal error occurred at line 11 of file
/usr/local/apache/htdocs/x2.php. The error message was Empty password
Script terminated
And here's a picture:

Note that it is the responsibility of the custom
handler to die() in the event of user-generated fatal errors - PHP will not do
this automatically.