[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/symfony/debug/Symfony/Component/Debug/ -> ErrorHandler.php (source)

   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  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1