[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Component\Debug; 13 14 use Symfony\Component\Debug\Exception\FatalErrorException; 15 use Symfony\Component\Debug\Exception\ContextErrorException; 16 use Symfony\Component\Debug\Exception\DummyException; 17 use Psr\Log\LoggerInterface; 18 19 /** 20 * ErrorHandler. 21 * 22 * @author Fabien Potencier <fabien@symfony.com> 23 * @author Konstantin Myakshin <koc-dp@yandex.ru> 24 */ 25 class ErrorHandler 26 { 27 const TYPE_DEPRECATION = -100; 28 29 private $levels = array( 30 E_WARNING => 'Warning', 31 E_NOTICE => 'Notice', 32 E_USER_ERROR => 'User Error', 33 E_USER_WARNING => 'User Warning', 34 E_USER_NOTICE => 'User Notice', 35 E_STRICT => 'Runtime Notice', 36 E_RECOVERABLE_ERROR => 'Catchable Fatal Error', 37 E_DEPRECATED => 'Deprecated', 38 E_USER_DEPRECATED => 'User Deprecated', 39 E_ERROR => 'Error', 40 E_CORE_ERROR => 'Core Error', 41 E_COMPILE_ERROR => 'Compile Error', 42 E_PARSE => 'Parse', 43 ); 44 45 private $level; 46 47 private $reservedMemory; 48 49 private $displayErrors; 50 51 /** 52 * @var LoggerInterface[] Loggers for channels 53 */ 54 private static $loggers = array(); 55 56 /** 57 * Registers the error handler. 58 * 59 * @param int $level The level at which the conversion to Exception is done (null to use the error_reporting() value and 0 to disable) 60 * @param bool $displayErrors Display errors (for dev environment) or just log they (production usage) 61 * 62 * @return ErrorHandler The registered error handler 63 */ 64 public static function register($level = null, $displayErrors = true) 65 { 66 $handler = new static(); 67 $handler->setLevel($level); 68 $handler->setDisplayErrors($displayErrors); 69 70 ini_set('display_errors', 0); 71 set_error_handler(array($handler, 'handle')); 72 register_shutdown_function(array($handler, 'handleFatal')); 73 $handler->reservedMemory = str_repeat('x', 10240); 74 75 return $handler; 76 } 77 78 public function setLevel($level) 79 { 80 $this->level = null === $level ? error_reporting() : $level; 81 } 82 83 public function setDisplayErrors($displayErrors) 84 { 85 $this->displayErrors = $displayErrors; 86 } 87 88 public static function setLogger(LoggerInterface $logger, $channel = 'deprecation') 89 { 90 self::$loggers[$channel] = $logger; 91 } 92 93 /** 94 * @throws ContextErrorException When error_reporting returns error 95 */ 96 public function handle($level, $message, $file = 'unknown', $line = 0, $context = array()) 97 { 98 if (0 === $this->level) { 99 return false; 100 } 101 102 if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) { 103 if (isset(self::$loggers['deprecation'])) { 104 if (PHP_VERSION_ID < 50400) { 105 $stack = array_map( 106 function ($row) { 107 unset($row['args']); 108 109 return $row; 110 }, 111 array_slice(debug_backtrace(false), 0, 10) 112 ); 113 } else { 114 $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10); 115 } 116 117 self::$loggers['deprecation']->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack)); 118 } 119 120 return true; 121 } 122 123 if ($this->displayErrors && error_reporting() & $level && $this->level & $level) { 124 // make sure the ContextErrorException class is loaded (https://bugs.php.net/bug.php?id=65322) 125 if (!class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) { 126 require __DIR__.'/Exception/ContextErrorException.php'; 127 } 128 if (!class_exists('Symfony\Component\Debug\Exception\FlattenException')) { 129 require __DIR__.'/Exception/FlattenException.php'; 130 } 131 132 if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && is_array($context)) { 133 unset($context['GLOBALS']); 134 } 135 136 $level &= E_ALL | E_STRICT; 137 $exception = new ContextErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line), 0, $level, $file, $line, $context); 138 139 // Exceptions thrown from error handlers are sometimes not caught by the exception 140 // handler, so we invoke it directly (https://bugs.php.net/bug.php?id=54275) 141 $exceptionHandler = set_exception_handler(function () {}); 142 restore_exception_handler(); 143 144 if (is_array($exceptionHandler) && $exceptionHandler[0] instanceof ExceptionHandler) { 145 $exceptionHandler[0]->handle($exception); 146 147 if (!class_exists('Symfony\Component\Debug\Exception\DummyException')) { 148 require __DIR__.'/Exception/DummyException.php'; 149 } 150 151 // we must stop the PHP script execution, as the exception has 152 // already been dealt with, so, let's throw an exception that 153 // will be caught by a dummy exception handler 154 set_exception_handler(function (\Exception $e) use ($exceptionHandler) { 155 if (!$e instanceof DummyException) { 156 // happens if our dummy exception is caught by a 157 // catch-all from user code, in which case, let's the 158 // current handler handle this "new" exception 159 call_user_func($exceptionHandler, $e); 160 } 161 }); 162 163 throw new DummyException(); 164 } 165 } 166 167 return false; 168 } 169 170 public function handleFatal() 171 { 172 if (null === $error = error_get_last()) { 173 return; 174 } 175 176 $this->reservedMemory = ''; 177 $type = $error['type'] & (E_ALL | E_STRICT); 178 if (0 === $this->level || !in_array($type, array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE))) { 179 return; 180 } 181 182 if (isset(self::$loggers['emergency'])) { 183 $fatal = array( 184 'type' => $type, 185 'file' => $error['file'], 186 'line' => $error['line'], 187 ); 188 189 self::$loggers['emergency']->emerg($error['message'], $fatal); 190 } 191 192 if (!$this->displayErrors) { 193 return; 194 } 195 196 // get current exception handler 197 $exceptionHandler = set_exception_handler(function () {}); 198 restore_exception_handler(); 199 200 if (PHP_VERSION_ID >= 70000 && $exceptionHandler instanceof \Closure) { 201 $reflector = new \ReflectionFunction($exceptionHandler); 202 foreach ($reflector->getStaticVariables() as $exceptionHandler) { 203 break; 204 } 205 } 206 if (is_array($exceptionHandler) && $exceptionHandler[0] instanceof ExceptionHandler) { 207 $level = isset($this->levels[$type]) ? $this->levels[$type] : $type; 208 $message = sprintf('%s: %s in %s line %d', $level, $error['message'], $error['file'], $error['line']); 209 $exception = new FatalErrorException($message, 0, $type, $error['file'], $error['line']); 210 $exceptionHandler[0]->handle($exception); 211 } 212 } 213 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |