Every well-constructed PHP application should have error handling. While there is no definitive method for handling errors since it varies depending on application needs and a developer's style, nonetheless, there are some "best practices" that should be implemented in all PHP applications.
The answer may seem straightforward but actually requires a bit of discussion. An "error" is an expected or unexpected event that occurs when your PHP code is running. An "expected" error can be a database query that returns no result or an html form that is missing values for designated required fields. An "unexpected" error is one that assumes a particular application state which, for some as yet unknown reason, does not exist. The most obvious unexpected error is a database that is not running or a missing file that one of your scripts expects to find.
The recommended "best practice" has three parts:
We can set these three parameters in one of two ways.
error_reporting = E_ALL
log_errors = On
display_errors = Off
error_reporting(E_ALL);
ini_set('log_errors','1');
ini_set('display_errors','0');
When "log_errors" is set to "On", errors will go into one of two places:
tail -f /path/to/your/log/error_logThe " -f " setting will show the errors as they are appended to the file. If the error has already occurred, you can use the following command to view the last 100 lines of the log. tail -100 error_log | more The number "100" can be changed to any number of lines you may want to view and piping the output to the more command will show a screen's worth of data at a time.
In either case, the file that PHP will write its errors to can be changed in either the php.ini file
in the "Error Handling and Logging" section, specifically, error_log = filename or,
if you do not have control over php.ini, you can set the file in your code by
using the following:
ini_set('error_log', '/full/path/to/your/file/my-errors.log');
This type of error can be the the result of something a website visitor has done such as providing invalid form input (the visitor omitted some values or entered letters in a field that is expecting numbers) or it can be a database query that returns no records. For example, you may have a form that requires that particular fields be completed before submitting or particular fields may require a particular type of input such as only numbers and dashes in a field that captures phone numbers. Therefore, your PHP code should ALWAYS check for acceptable values.
Illustrated below is a simple example that illustrates the concept. Click here to see it in action.
<?php
/**************************************************************
Check values entered by user.
The code shown here is meant solely to illustrate the concept
in the main article. There are many different coding methods
that one can use to validate form input.
***************************************************************/
//Initialize array to an empty array
$errMsg = array();
/*
Check to see if the form has been posted. If true, then
check values.
*/
if (isset($_POST['submit'])){
if (trim($_POST['Name']) === ''){
$errMsg[] = 'Please enter your name';
}
//We want to make sure that the phone number is in the format we want
if (!preg_match("/^[0-9]{3}[-]{1,1}[0-9]{4}$/", $_POST['Phone'])){
$errMsg[] = 'Phone number should be entered as digits in the following format: ###-####';
}
/*
If an error has occurred, the array "$errMsg" will have a count greater than zero
so display our error message to the user
*/
if (count($errMsg)!== 0){
foreach ($errMsg as $key => $value){
$tmp .= "<li>$value</li>";
}
echo "An error has occurred:<ul>$tmp</ul>";
} else {
echo "Congratulations! You successfully entered your Name and Phone Number!";
}
}
//Note below that we are echoing back to the user any values already entered and we are
//making those values browser-safe with the "htmlentities" function
//(See Note 2)
?>
<form name="myForm" method="POST" action="<?php echo $_SERVER['PHP_SELF']?>">
Name: <input name="Name" type="text" value="<?php echo htmlentities($_POST['Name'])?>">
<br />
Phone: <input name="Phone" type="text" value="<?php echo htmlentities($_POST['Phone'])?>">
<input type="submit" name="submit" value="Submit">
</form>
Unexpected errors are errors that are not part of the normal operation of your PHP application such as a database that suddenly stops running. When an unexpected error occurs, you want to:
Below are general guidelines for implementing our recommended best practices for notifying the developer of unexpected errors.
set_error_handler('myErrHandler');
if(!mysql_connect("myDatabase","myUser","myPassword")){
trigger_error('Can not connect to database',E_USER_ERROR);
}
So what should your error handler look like? We've provided a sample error handler though the exact error handler you use is solely up to you. However, the sample code below fulfills the five basic requirements of an error handler as noted above.
<?php
function myErrHandler($code, $message, $errFile, $errLine) {
//Set message/log info
$subject = "$message: MAJOR PROBLEM at " . APP_NAME . ': ' . date("F j, Y, g:i a");
$body = "errFile: $errFile\r\n"
. "errLine: $errLine\r\n"
. trigger_dump($GLOBALS);
/*
An email will be sent to the site administrator.
Its subject line will have the date and time it occurred while
the body will contain the state of all of the global variables. This information
is obtained through the function trigger_dump.
*/
mail(ADMIN_EMAIL_ADDR,$subject,$body);
//The same subject line and body of the email will get written to the error log.
error_log("$subject\r\n $body");
/*
We don't want users to know the true nature of the problem so
we just redirect them to a generic error page that has been created.
The generic page should have a simple message, such as "System down
for maintenance." The key idea is not to let any potentially malicious
user learn about the actual problem that had occurred.
*/
header ("Location: http://{$_SERVER['HTTP_HOST']}/". GENERIC_ERR_PAGE );
exit;
}
/*
The function below is called by the mail
and error_log calls above.
*/
function trigger_dump( $mixed,$type = 0 ) {
/*
$mixed will handle whatever you may decide to pass to it.
$type will determine what this function should do with the
information obtained by var_dump
*/
switch( (int) $type ) {
case 0:
/*
Grab the contents of the output buffer
when you want to send the information
back to the calling function
*/
ob_start();
var_dump($mixed);
//If you are using PHP ver. 4.3 use the
//code below:
return ob_get_clean();
//If you are using an earlier version
//of PHP, then use the code below:
$ob_contents = ob_get_contents();
ob_end_clean();
return $ob_contents;
case 1:
/*
When you want to display the information to the browser
*/
print '<pre>';
var_dump($mixed);
print '</pre>';
break;
case 2:
//When you want your error handler to deal with the information
ob_start();
var_dump($mixed);
//If you are using PHP ver. 4.3 use the
//code below:
trigger_error(ob_get_clean());
break;
//If you are using an earlier version
//of PHP, then use the code below:
$ob_contents = ob_get_contents();
ob_end_clean();
trigger_error($ob_contents);
break;
}
}
?>
The constants used in the sample code are part of a sample include file.
Click here to view the file.
Case 2 will always send the output of var_dump to your own error handler,
via the trigger_dump function.
For additional information see var_dump
and also trigger_error.
1 - For additional information on php.ini settings, see the latest version of
php.ini-recommended. See also the
PHundamentals article
PHP Initialization.
A list of configuration settings that can be changed via ini_set can be
found here.
2 - For additional information on the use of htmlentities see the PHundamentals
article
"Storing Data Submitted From a Form and Displaying Data from a Database".
While you can use JavaScript to trap form-related user errors, you should NEVER
solely rely on it. Users can intentionally turn off JavaScript and thereby bypass your error checking.
For a discussion of
other form-related issues, see the PHundamentals article
Spoofed Form Submissions.
3 - Whether to show a generic "System down for maintenance" message or not is, of course, a
judgement call on the part of the developer. For example, one could simply redirect the user to the home page
which would be a visual indicator (to the user) that something had gone awry but it does not
tip off the user as to "what" went awry. In the case of "expected" errors,
such as a search function that uses URL parameters, you might want to implement a set of
"default" search parameters.
For example, your site might have a URL like the following:
http://mydomain.com/search.php?location=USA. If a user should alter the search
parameter, e.g., location=123, your code could handle this by automatically substituting
the default search parameters. Alternately, you could display a message such as "No records were
found. Please try again."
Contributors to this note include the following:
John F. Andrews
Mark Armendariz
David Mintz
Mitch Pirtle
Chris Shiflett
Hans Zaunere
the PHundamentals Team: Jeff Siegel, Michael Southwell
free PHP thumbnail maker CSS & Javascript minify gzip pipeline online API and console
Free API and developer tools console for PageSpeed optimization.