PHP Demo Application - Source Code
/Framework/Controller/Libraries/Error.php
<?php
/**
* Script Contents: Apeel_Framework_Model_Handlers_Error Class
* @package Apeel_Framework_Controller
*/
/**
* Error handling library
*
* A static library providing error/exception handling methods that direct the
* user to a "friendly" error page.
*
* If in debug mode, the actual error message will be displayed, however if the
* application is not running in debug mode then a friendly error message will
* be shown to the end user, with the actual error message logged to the error
* log for the developer to examine.
*
* The precise details of the error are not shown to the end-user in
* production mode as the technical details of the problem are unlikely to
* be useful to the end user, and could give away secrets of the internal
* workings of your application to potential hackers.
*
* Debug mode can be turned on/off by setting the APEEL_DEBUG_MODE value to 1
* or 0 respectively, it can be found under:
* /Application/Model/MetaData/Configuration.php
*
* @package Apeel_Framework_Controller
* @version 1.1.0
* @author John W. King (email: contact@apeelframework.net)
* @copyright City Business Logic Limited 2001-2011
* @license Dual MIT / GNU Lesser General Public License Version 3
*/
class Apeel_Framework_Model_Handlers_Error {
/**
* Stores value of APEEL_DEBUG_MODE to identify whether in debug or
* production mode.
*
* @var boolean
*/
private static $isInDebugMode = '';
/**
* Tells class whether or not to display error messages within a decorative
* template. This is typically true for web pages and false for ajax
* requests for example.
*
* @var boolean
*/
private static $useTemplate = '';
/**
* Holds the address of the template to display, (if $useTemplate is true)
*
* @var string
*/
private static $templateFile = '';
/**
* Initialise Error Handling Library
*
* This method is the public entry point to setup error handling.
* It sets the class variables to the supplied parameter values, attempts to
* turn full PHP error reporting on if in debug mode, or turn it off if in
* production mode, and finally sets the custom error and exception handlers.
*
* @param boolean $isInDebugMode
* @param boolean $useTemplate [optional]
* @param string $templateFile [optional]
* @return boolean
*/
public static function initErrorHandling($isInDebugMode, $useTemplate = false, $templateFile = '') {
self::$isInDebugMode = $isInDebugMode;
self::$useTemplate = $useTemplate;
self::$templateFile = $templateFile;
if ($isInDebugMode) {
if (ini_get('display_errors') != '1') {
@ini_set('display_errors', 1);
@error_reporting(E_ALL|E_STRICT);
}
} else {
error_reporting(0);
}
set_exception_handler(array('Apeel_Framework_Model_Handlers_Error', 'exceptionHandler'));
set_error_handler(array('Apeel_Framework_Model_Handlers_Error', 'errorHandler'));
return true;
}
/**
* Custom Exception Handler
*
* All exceptions are passed by PHP to this method, which passes them on to
* the combined exception/error handling method - processError.
*
* @param Exception $exception
* @return void
*/
public static function exceptionHandler($exception) {
$message = $exception->getMessage();
self::processError($message, -1, $exception->getTraceAsString());
}
/**
* Custom Error Handler
*
* All errors are passed by PHP to this method, which looks up the error
* code and gives it a name, before passing them on to the combined
* exception/error handling method - processError.
*
* @param Exception $exception
* @return void
*/
public static function errorHandler($errorNumber, $errorString, $errorFile, $errorLine, $errorContext) {
$errorNames = array(
E_ERROR => 'E_ERROR',
E_WARNING => 'E_WARNING',
E_PARSE => 'E_PARSE',
E_NOTICE => 'E_NOTICE',
E_CORE_ERROR => 'E_CORE_ERROR',
E_CORE_WARNING => 'E_CORE_WARNING',
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
E_USER_ERROR => 'E_USER_ERROR',
E_USER_WARNING => 'E_USER_WARNING',
E_USER_NOTICE => 'E_USER_NOTICE'
);
$message = $errorString;
if (isset($errorNames[$errorNumber])) {
$message .= ' (Error Code: ' . $errorNames[$errorNumber] . ' / Line: ' . $errorLine . ')' . ' in ' . $errorFile;
}
self::processError($message, $errorNumber);
}
/**
* Error/Exception Processor
*
* Errors and Exceptions are passed to this method by the custom handlers,
* they are first sent to the error log and then displayed to the user if
* in Debug mode.
*
* If in production mode, minor errors such as E_NOTICE are simply ignored,
* but more serious errors force execution to be halted and the user is
* informed an error has occurred.
* @param string $message
* @param integer $errorNumber
* @param string $errorTrace
* @return void
*/
private static function processError($message, $errorNumber, $errorTrace = '') {
self::logError($message, $errorTrace);
if (self::$isInDebugMode) {
self::displayError($message, $errorTrace);
} else {
if ($errorNumber >= E_NOTICE) {
// Minor error and not in debug mode, so exit error handling
return false;
} else {
self::displayError(APEEL_LANGUAGE_ERROR_OCCURRED);
}
}
exit;
}
/**
* Error Logger
*
* This method handles recording error messages and error traces (if
* available) to the standard error log.
*
* If you would like an email to be sent to an operative every time an
* error occurs, this would be an ideal location to add the code to send it.
* @param string $message
* @param string $errorTrace
* @return void
*/
private static function logError($message, $errorTrace) {
@Error_log('Apeel Error: ' . $message);
if ($errorTrace) {
@Error_log('Trace: ' . $errorTrace);
}
}
/**
* Display Error to User
*
* This method handles the nitty gritty of outputing errors to the user.
*
* If the static property $useTemplate is true then the template file
* specified by $templateFile is read, tokens are replaced and it is
* output to the user.
*
* The template file will typically contain a form with a button to submit
* in order to try again (for example in response to a temporary database
* error). This script reads all posted values and passes them in as
* hidden fields. The current URL replaces the form's action token.
*
* If $useTemplate is false then the error message is simply output.
* @param string $message
* @param string $errorTrace
* @staticvar boolean $useTemplate
* @staticvar string $templateFile
* @return void
*/
private static function displayError($message, $errorTrace) {
$url = $_SERVER["REQUEST_URI"];
$posts = '';
if ($_POST) {
foreach ($_POST as $index => $value) {
$posts .= '<input type="hidden" name="' . $index . '" value="' . $value . '" />';
}
}
if (self::$useTemplate) {
ob_clean();
if ($errorTrace) {
$message .= "\r\n" . 'TRACE: ' . $errorTrace;
}
$display = file_get_contents(self::$templateFile);
$display = str_replace('{##ERROR_MESSAGE##}', $message, $display);
$display = str_replace('{##URL##}', $url, $display);
$display = str_replace('{##POSTS##}', $posts, $display);
$display = str_replace('{##TRY_AGAIN##}', APEEL_LANGUAGE_TRY_AGAIN, $display);
echo $display;
} else {
echo "\r\nERROR: " . $message . "\r\n";
}
}
}
?>