The first part of this article demonstrated basic errorhandling in PHP, explaining the various error types and illustrating theprocess of building a custom error handler. But that's just the tip ofthe iceberg - this concluding part goes a step further, showing you totrigger your own errors, and log error messages to a file, database oremail address.
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.