Example #1
0
 /**
  * = Options =
  * 
  * All options are optional, and so is passing in an options item.
  * You don't have to supply any, it's up to you.
  * 
  * Note that if 'php_error.force_disable' is true, then this object
  * will try to look like it works, but won't actually do anything.
  * 
  * All options can also be passed in from 'php.ini'. You do this
  * by setting it with 'php_error.' prefix. For example:
  * 
  *      php_error.catch_ajax_errors = On
  *      php_error.error_reporting_on = E_ALL | E_STRICT
  * 
  * Includes:
  *  = Types of errors this will catch =
  *  - catch_ajax_errors         When on, this will inject JS Ajax wrapping code, to allow this to catch any future JSON errors. Defaults to true.
  *  - catch_supressed_errors    The @ supresses errors. If set to true, then they are still reported anyway, but respected when false. Defaults to false.
  *  - catch_class_not_found     When true, loading a class that does not exist will be caught. This defaults to true.
  * 
  *  = Error reporting level =
  *  - error_reporting_on        value for when errors are on, defaults to all errors
  *  - error_reporting_off       value for when errors are off, defaults to php.ini's error_reporting.
  * 
  *  = Setup Details =
  *  - application_root          When it's working out hte stack trace, this is the root folder of the application, to use as it's base.
  *                              Defaults to the servers root directory.
  * 
  *                              A relative path can be given, but lets be honest, an explicit path is the way to guarantee that you
  *                              will get the path you want. My relative might not be the same as your relative.
  * 
  *  - snippet_num_lines         The number of lines to display in the code snippet. 
  *                              That includes the line being reported.
  * 
  *  - server_name               The name for this server, defaults to "$_SERVER['SERVER_NAME']"
  * 
  *  - ignore_folders            This is allows you to highlight non-framework code in a stack trace.
  *                              An array of folders to ignore, when working out the stack trace.
  *                              This is folder prefixes in relation to the application_root, whatever that might be.
  *                              They are only ignored if there is a file found outside of them.
  *                              If you still don't get what this does, don't worry, it's here cos I use it.
  * 
  *  - application_folders       Just like ignore, but anything found in these folders takes precedence
  *                              over anything else.
  * 
  *  - background_text           The text that appeares in the background. By default this is blank.
  *                              Why? You can replace this with the name of your framework, for extra customization spice.
  * 
  *  - html_only                 By default, PHP Error only runs on ajax and HTML pages.
  *                              If this is false, then it will also run when on non-HTML
  *                              pages too, such as replying with images of JavaScript
  *                              from your PHP. Defaults to true.
  * 
  *  - throw_errors              By default, PHP Error will stop execution on trigerred errors.
  *                              You can enabled it to throw errors instead.
  *  - error_page                Error page to show if display_errors is disabled.
  *                              Should be an absolute path to .html or .php file
  * 
  *  - error_log                 Defines where to log messages.
  *                              FALSE - disables logging
  *                              0 - logs to the syslog, equivalent of php's error_log($message, 0) (default)
  *                              absolute path - logs to the provided file path, equivalent of php's error_log($message, 3, $path)
  *                              email - sends an email, equivalent of php's error_log($message, 1, $email)
  * 
  *  - error_log_format          Format of log messages with printf() directives.
  *                              %1$s - timestamp (empty if error_log is set to 0, because syslog is using it's own timestamp)
  *                              %2$s - error message
  *                              %3$s - file
  *                              %4$s - line
  *                              %5$s - stack trace (starts on the newline and is indented)
  *                              Defaults to "%s%s\n           %s, %s %s"
  *                              
  *  - error_log_time_format     Format of log's timestamp compatible with strftime()
  *                              Defaults to "[%c] "
  * 
  * @param options Optional, an array of values to customize this handler.
  * @throws Exception This is raised if given an options that does *not* exist (so you know that option is meaningless).
  */
 public function __construct($options = null)
 {
     // there can only be one to rule them all
     global $_php_error_global_handler;
     if ($_php_error_global_handler !== null) {
         $this->lastGlobalErrorHandler = $_php_error_global_handler;
     } else {
         $this->lastGlobalErrorHandler = null;
     }
     $_php_error_global_handler = $this;
     $this->cachedFiles = array();
     $this->isShutdownRegistered = false;
     $this->isOn = false;
     /*
      * Deal with the options.
      * 
      * They are removed one by one, and any left, will raise an error.
      */
     $ignoreFolders = ErrorHandler::optionsPop($options, 'ignore_folders', null);
     $appFolders = ErrorHandler::optionsPop($options, 'application_folders', null);
     if ($ignoreFolders !== null) {
         ErrorHandler::setFolders($this->ignoreFolders, $this->ignoreFoldersLongest, $ignoreFolders);
     }
     if ($appFolders !== null) {
         ErrorHandler::setFolders($this->applicationFolders, $this->applicationFoldersLongest, $appFolders);
     }
     $this->defaultErrorReportingOn = ErrorHandler::optionsPop($options, 'error_reporting_on', -1);
     $this->defaultErrorReportingOff = ErrorHandler::optionsPop($options, 'error_reporting_off', error_reporting());
     $this->applicationRoot = ErrorHandler::optionsPop($options, 'application_root', $_SERVER['DOCUMENT_ROOT']);
     $this->serverName = ErrorHandler::optionsPop($options, 'server_name', isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : null);
     /*
      * Relative paths might be given for document root,
      * so we make it explicit.
      */
     $dir = @realpath($this->applicationRoot);
     if (!is_string($dir)) {
         throw new Exception("Document root not found: " . $this->applicationRoot);
     } else {
         $this->applicationRoot = str_replace('\\', '/', $dir);
     }
     $this->catchClassNotFound = !!ErrorHandler::optionsPop($options, 'catch_class_not_found', true);
     $this->catchSurpressedErrors = !!ErrorHandler::optionsPop($options, 'catch_supressed_errors', false);
     $this->catchAjaxErrors = !!ErrorHandler::optionsPop($options, 'catch_ajax_errors', true);
     $this->backgroundText = ErrorHandler::optionsPop($options, 'background_text', '');
     $this->numLines = ErrorHandler::optionsPop($options, 'snippet_num_lines', ErrorHandler::NUM_FILE_LINES);
     $this->displayLineNumber = ErrorHandler::optionsPop($options, 'display_line_numbers', false);
     $this->htmlOnly = !!ErrorHandler::optionsPop($options, 'html_only', true);
     $this->throwErrors = !!ErrorHandler::optionsPop($options, 'throw_errors', false);
     $this->errorPage = ErrorHandler::optionsPop($options, 'error_page', false);
     $this->errorLog = ErrorHandler::optionsPop($options, 'error_log', 0);
     $this->errorLogFormat = ErrorHandler::optionsPop($options, 'error_log_format', "%s%s\n           %s, %s %s");
     $this->errorLogTimeFormat = ErrorHandler::optionsPop($options, 'error_log_time_format', '[%c] ');
     $this->classNotFoundException = null;
     $wordpress = ErrorHandler::optionsPop($options, 'wordpress', false);
     if ($wordpress) {
         // php doesn't like | in constants and privates, so just set it directly : (
         $this->defaultErrorReportingOn = E_ERROR | E_WARNING | E_PARSE | E_USER_DEPRECATED & ~E_DEPRECATED & ~E_STRICT;
     }
     if ($options) {
         foreach ($options as $key => $val) {
             throw new InvalidArgumentException("Unknown option given {$key}");
         }
     }
     $this->isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest' || isset($_REQUEST['php_error_is_ajax']);
     $this->isBufferSetup = false;
     $this->startBuffer();
 }