private function runEnableErrors() { global $_php_error_is_ini_enabled; if ($_php_error_is_ini_enabled) { $catchSurpressedErrors =& $this->catchSurpressedErrors; $self = $this; // all errors \o/ ! error_reporting($this->defaultErrorReportingOn); if (ErrorHandler::isIIS()) { @ini_set('log_errors', false); } set_error_handler(function ($code, $message, $file, $line, $context) use($self, &$catchSurpressedErrors) { /* * DO NOT! log the error. * * Either it's thrown as an exception, and so logged by the exception handler, * or we return false, and it's logged by PHP. * * Also DO NOT! throw an exception, instead report it. * This is because if an operation raises both a user AND * fatal error (such as require), then the exception is * silently ignored. */ if ($self->isOn()) { /* * Turning off 'html_errors' at this point avoids interference * with xDebugs 'var_dump()'-overload, thus preserving prettyfied dumps */ @ini_set('html_errors', false); /* * When using an @, the error reporting drops to 0. */ if (error_reporting() !== 0 || $catchSurpressedErrors) { $ex = new ErrorException($message, $code, $code, $file, $line); if ($self->throwErrors) { throw $ex; } else { $self->reportException($ex); } } } else { return false; } }, $this->defaultErrorReportingOn); set_exception_handler(function ($ex) use($self) { if ($self->isOn()) { /* * Turning off 'html_errors' at this point avoids interference * with xDebugs 'var_dump()'-overload, thus preserving prettyfied dumps */ @ini_set('html_errors', false); $self->reportException($ex); } else { return false; } }); if (!$self->isShutdownRegistered) { if ($self->catchClassNotFound) { $classException =& $self->classNotFoundException; $autoloaderFuns = ErrorHandler::$SAFE_AUTOLOADER_FUNCTIONS; /* * When this is called, the key point is that we don't error! * * Instead we record that an error has occurred, * if we believe one has, and then let PHP error as normal. * The stack trace we record is then used later. * * This is done for two reasons: * - functions like 'class_exists' will run the autoloader, and we shouldn't error on them * - on PHP 5.3.0, the class loader registered functions does *not* return closure objects, so we can't do anything clever. * * So we watch, but don't touch. */ spl_autoload_register(function ($className) use($self, &$classException, &$autoloaderFuns) { if ($self->isOn()) { $classException = null; // search the stack first, to check if we are running from 'class_exists' before we error if (defined('DEBUG_BACKTRACE_IGNORE_ARGS')) { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); } else { $trace = debug_backtrace(); } $error = true; foreach ($trace as $row) { if (isset($row['function'])) { $function = $row['function']; // they are just checking, so don't error if (in_array($function, $autoloaderFuns, true)) { $error = false; break; // not us, and not the autoloader, so error! } else { if ($function !== '__autoload' && $function !== 'spl_autoload_call' && strpos($function, 'php_error\\') === false) { break; } } } } if ($error) { $classException = new ErrorException("Class '{$className}' not found", E_ERROR, E_ERROR, __FILE__, __LINE__); } } }); } $self->isShutdownRegistered = true; } } }