Compare commits

..

25 Commits

Author SHA1 Message Date
Fabien Potencier
de73f48977 Merge branch '3.4' into 4.2
* 3.4:
  Removed non-existing parameters for LogoutUrlGenerator calls
  [HttpKernel] Correctly merging cache directives in HttpCache/ResponseCacheStrategy
  [Validator] Add the missing translations for the Latvian ("lv") locale
  Fixed the DebugClassLoader compatibility with eval()'d code on Darwin
  [Validator] Update Serbian translation file
2019-03-03 19:11:24 +01:00
Pascal Luna
8d8a9e877b Fixed the DebugClassLoader compatibility with eval()'d code on Darwin 2019-02-24 16:45:11 +01:00
Nicolas Grekas
9359ad70a1 Merge branch '3.4' into 4.2
* 3.4: (24 commits)
  Apply php-cs-fixer rule for array_key_exists()
  [Security] Change FormAuthenticator if condition
  handles multi-byte characters in autocomplete
  speed up tests running them without debug flag
  [Translations] added missing Croatian validators
  Fix getItems() performance issue with RedisCluster (php-redis)
  [VarDumper] Keep a ref to objects to ensure their handle cannot be reused while cloning
  IntegerType: reject submitted non-integer numbers
  be keen to newcomers
  [HttpKernel] Fix possible infinite loop of exceptions
  fixed CS
  [Validator] Added missing translations for Afrikaans
  do not validate non-submitted form fields in PATCH requests
  Update usage example in ArrayInput doc block.
  [Console] Prevent ArgvInput::getFirstArgument() from returning an option value
  [Validator] Fixed duplicate UUID
  fixed CS
  [EventDispatcher] Fix unknown priority
  Avoid mutating the Finder when building the iterator
  [Validator] Add the missing translations for the Greek (el) locale
  ...
2019-02-23 16:17:42 +01:00
Nicolas Grekas
1fe36a98e2 Apply php-cs-fixer rule for array_key_exists() 2019-02-23 16:06:07 +01:00
Fabien Potencier
945530598e Merge branch '3.4' into 4.2
* 3.4:
  [TwigBridge] Fix test
  Remove unnecessary ProgressBar stdout writes (fixes flickering)
  [Validator] improve translations for albanian ("sq") locale
  [VarDumper] fix serializing Stub instances
  Don't resolve the Deprecation error handler mode until a deprecation is triggered
  bug #30245 fix lost namespace in eval (fizzka)
  [Twig] removed usage of non-namespaced classes
  added missing dot
  Update validators.lt.xlf
  #30172 Add the missing validation translations for the Luxembourgish …
  [Debug][ErrorHandler] Preserve next error handler
2019-02-18 07:49:49 +01:00
Thomas Calvet
8b8b8b7e57 [Debug][ErrorHandler] Preserve next error handler
Co-authored-by: Joe <cuchac@email.cz>
2019-02-16 11:38:56 +01:00
Nicolas Grekas
cf9b2e33f7 Merge branch '4.1' into 4.2
* 4.1:
  [HttpFoundation] Check file exists before unlink
  [Console] Fixed #29835: ConfirmationQuestion with default true for answer '0'
  [Translation] Concatenated translation messages
  [Form] ensure compatibility with older PHPUnit mocks
  [Serializer] Docblock about throwing exceptions on serializer
  [Debug][ErrorHandler] Preserve our error handler when a logger set another one
  [Form] Changed UrlType input type to text when default_protocol is not null
  [Bugfix] MemcachedSessionHandler::close() must close connection
2019-01-25 15:35:16 +01:00
Nicolas Grekas
caf0f3fa57 Merge branch '3.4' into 4.1
* 3.4:
  [HttpFoundation] Check file exists before unlink
  [Console] Fixed #29835: ConfirmationQuestion with default true for answer '0'
  [Translation] Concatenated translation messages
  [Form] ensure compatibility with older PHPUnit mocks
  [Serializer] Docblock about throwing exceptions on serializer
  [Debug][ErrorHandler] Preserve our error handler when a logger set another one
  [Form] Changed UrlType input type to text when default_protocol is not null
  [Bugfix] MemcachedSessionHandler::close() must close connection
2019-01-25 15:34:37 +01:00
Nicolas Grekas
667a26c4dd bug #29869 [Debug][ErrorHandler] Preserve our error handler when a logger sets another one (fancyweb)
This PR was merged into the 3.4 branch.

Discussion
----------

[Debug][ErrorHandler] Preserve our error handler when a logger sets another one

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

When logging errors handled by the `ErrorHandler::handleError()` method, the logger can temporarily set its own custom error handler. This is for example the case of `Monolog` in the `StreamHandler` class (cf ebb804e432/src/Monolog/Handler/StreamHandler.php (L101)).

However, when the previous error handler is restored by the logger, it "skips" the real previous handler (the `ErrorHandler::handleError()` one) in the pile and goes back directly to the one before. I guess this is because the `restore_error_handler()` call is technically done in the error handler itself, so it logically restore it to the one before and not to itself.

Here is an easy small example that shows the PHP behavior : https://3v4l.org/4OZNZ

The only solution I have found to fix it is to set our error handler everytime an error is logged.

Here are the things I discovered while trying to find a cleaner fix :
- Setting the same error handler in the error handler itself doesn't actually add it to the pile. This is why adding a check is useless.
- Checking if the logger modified the error handler is impossible anyway : to get the current error handler, you need to set a new one temporarirly and then revert it. However, when you revert it by calling `restore_error_handler()` you end up having the same problem you are trying to fix...
- Also trying to get the current error handler in the error handler itself will return NULL if it is itself.

Commits
-------

b979fff6b8 [Debug][ErrorHandler] Preserve our error handler when a logger set another one
2019-01-25 11:19:25 +01:00
Nicolas Grekas
7ae7883ea2 Merge branch '4.1' into 4.2
* 4.1:
  Bump phpunit bridge cache id
  [appveyor] fix create-project phpunit
  Fix HttpKernel Debug requirement
  Fix heredoc
  use final annotation to allow mocking the class
  synchronise the form builder docblock
  Grammar fix in exception message
  fix tests
  forward the parse error to the calling code
  [Debug][DebugClassLoader] Match more cases for final, deprecated and internal classes / methods extends
  ensure compatibility with older PHPUnit mocks
  [Security] Do not mix usage of password_*() functions and sodium_*() ones
2019-01-24 22:39:51 +01:00
Nicolas Grekas
4174d02351 Merge branch '3.4' into 4.1
* 3.4:
  Bump phpunit bridge cache id
  [appveyor] fix create-project phpunit
  Fix HttpKernel Debug requirement
  Fix heredoc
  use final annotation to allow mocking the class
  synchronise the form builder docblock
  Grammar fix in exception message
  fix tests
  forward the parse error to the calling code
  [Debug][DebugClassLoader] Match more cases for final, deprecated and internal classes / methods extends
  ensure compatibility with older PHPUnit mocks
  [Security] Do not mix usage of password_*() functions and sodium_*() ones
2019-01-24 22:39:39 +01:00
Thomas Calvet
b624515da8 [Debug][ErrorHandler] Preserve our error handler when a logger set another one 2019-01-24 21:41:57 +01:00
Thomas Calvet
970d9da53e [Debug][DebugClassLoader] Match more cases for final, deprecated and internal classes / methods extends 2019-01-17 18:28:22 +01:00
Fabien Potencier
2e1483cd0d fixed CS 2019-01-16 22:31:25 +01:00
Fabien Potencier
f6bdc0a7df fixed CS 2019-01-16 21:35:37 +01:00
Fabien Potencier
00db8f8b37 Merge branch '4.1' into 4.2
* 4.1:
  fixed tests
  fixed CS
  fixed CS
  fixed CS
  fixed short array CS in comments
  fixed CS in ExpressionLanguage fixtures
  fixed CS in generated files
  fixed CS on generated container files
  fixed CS on Form PHP templates
  fixed CS on YAML fixtures
  fixed fixtures
  switched array() to []
2019-01-16 21:31:39 +01:00
Fabien Potencier
45c6e7759f fixed CS 2019-01-16 20:07:26 +01:00
Fabien Potencier
d1815d4beb fixed CS 2019-01-16 19:35:49 +01:00
Fabien Potencier
8747fd01a7 Merge branch '3.4' into 4.1
* 3.4:
  fixed CS
  fixed short array CS in comments
  fixed CS in ExpressionLanguage fixtures
  fixed CS in generated files
  fixed CS on generated container files
  fixed CS on Form PHP templates
  fixed CS on YAML fixtures
  fixed fixtures
  switched array() to []
2019-01-16 19:21:11 +01:00
Fabien Potencier
2574a83be3 fixed short array CS in comments 2019-01-16 14:27:11 +01:00
Fabien Potencier
4d92150508 switched array() to [] 2019-01-16 10:39:14 +01:00
Fabien Potencier
1a53cddc50 Merge branch '4.1' into 4.2
* 4.1:
  bump required Twig version
  fix compatibility with Twig >= 2.6.1
  [Form] SA fix
  fix compatibility with PHPUnit 4.8
  remove return type hint for PHP 5 compatibility
  SCA: minor code tweaks
  Component CssSelector tests
  [DebugClassLoader] Readd findFile() method
  [Console] Fix composer.json suggest/provide
  Revert "bug #29597 [DI] fix reporting bindings on overriden services as unused (nicolas-grekas)"
  Fixed exception wording
  Fix SwiftMailerHandler to support Monolog's latest reset functionality
2019-01-14 16:33:52 +01:00
Christian Flothmann
ab51c79f5e Merge branch '3.4' into 4.1
* 3.4:
  fix compatibility with Twig >= 2.6.1
  [Form] SA fix
  fix compatibility with PHPUnit 4.8
  remove return type hint for PHP 5 compatibility
  Component CssSelector tests
  [DebugClassLoader] Readd findFile() method
  [Console] Fix composer.json suggest/provide
  Revert "bug #29597 [DI] fix reporting bindings on overriden services as unused (nicolas-grekas)"
  Fixed exception wording
  Fix SwiftMailerHandler to support Monolog's latest reset functionality
2019-01-14 12:04:47 +01:00
Christian Flothmann
5ca61fb12e remove return type hint for PHP 5 compatibility 2019-01-14 09:43:48 +01:00
Thomas Calvet
ce763d24ed [DebugClassLoader] Readd findFile() method 2019-01-13 17:36:47 +01:00
27 changed files with 583 additions and 367 deletions

View File

@@ -20,17 +20,17 @@ use Psr\Log\AbstractLogger;
*/
class BufferingLogger extends AbstractLogger
{
private $logs = array();
private $logs = [];
public function log($level, $message, array $context = array())
public function log($level, $message, array $context = [])
{
$this->logs[] = array($level, $message, $context);
$this->logs[] = [$level, $message, $context];
}
public function cleanLogs()
{
$logs = $this->logs;
$this->logs = array();
$this->logs = [];
return $logs;
}

View File

@@ -42,7 +42,7 @@ class Debug
error_reporting(E_ALL);
}
if (!\in_array(\PHP_SAPI, array('cli', 'phpdbg'), true)) {
if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
ini_set('display_errors', 0);
ExceptionHandler::register();
} elseif ($displayErrors && (!filter_var(ini_get('log_errors'), FILTER_VALIDATE_BOOLEAN) || ini_get('error_log'))) {

View File

@@ -29,16 +29,16 @@ class DebugClassLoader
{
private $classLoader;
private $isFinder;
private $loaded = array();
private $loaded = [];
private static $caseCheck;
private static $checkedClasses = array();
private static $final = array();
private static $finalMethods = array();
private static $deprecated = array();
private static $internal = array();
private static $internalMethods = array();
private static $annotatedParameters = array();
private static $darwinCache = array('/' => array('/', array()));
private static $checkedClasses = [];
private static $final = [];
private static $finalMethods = [];
private static $deprecated = [];
private static $internal = [];
private static $internalMethods = [];
private static $annotatedParameters = [];
private static $darwinCache = ['/' => ['/', []]];
public function __construct(callable $classLoader)
{
@@ -98,7 +98,7 @@ class DebugClassLoader
foreach ($functions as $function) {
if (!\is_array($function) || !$function[0] instanceof self) {
$function = array(new static($function), 'loadClass');
$function = [new static($function), 'loadClass'];
}
spl_autoload_register($function);
@@ -127,6 +127,14 @@ class DebugClassLoader
}
}
/**
* @return string|null
*/
public function findFile($class)
{
return $this->isFinder ? $this->classLoader[0]->findFile($class) ?: null : null;
}
/**
* Loads the given class or interface.
*
@@ -211,7 +219,7 @@ class DebugClassLoader
public function checkAnnotations(\ReflectionClass $refl, $class)
{
$deprecations = array();
$deprecations = [];
// Don't trigger deprecations for classes in the same vendor
if (2 > $len = 1 + (\strpos($class, '\\') ?: \strpos($class, '_'))) {
@@ -223,9 +231,9 @@ class DebugClassLoader
// Detect annotations on the class
if (false !== $doc = $refl->getDocComment()) {
foreach (array('final', 'deprecated', 'internal') as $annotation) {
if (false !== \strpos($doc, $annotation) && preg_match('#\n \* @'.$annotation.'(?:( .+?)\.?)?\r?\n \*(?: @|/$)#s', $doc, $notice)) {
self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : '';
foreach (['final', 'deprecated', 'internal'] as $annotation) {
if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$)#s', $doc, $notice)) {
self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : '';
}
}
}
@@ -265,11 +273,11 @@ class DebugClassLoader
}
// Inherit @final, @internal and @param annotations for methods
self::$finalMethods[$class] = array();
self::$internalMethods[$class] = array();
self::$annotatedParameters[$class] = array();
self::$finalMethods[$class] = [];
self::$internalMethods[$class] = [];
self::$annotatedParameters[$class] = [];
foreach ($parentAndOwnInterfaces as $use) {
foreach (array('finalMethods', 'internalMethods', 'annotatedParameters') as $property) {
foreach (['finalMethods', 'internalMethods', 'annotatedParameters'] as $property) {
if (isset(self::${$property}[$use])) {
self::${$property}[$class] = self::${$property}[$class] ? self::${$property}[$use] + self::${$property}[$class] : self::${$property}[$use];
}
@@ -297,7 +305,7 @@ class DebugClassLoader
$doc = $method->getDocComment();
if (isset(self::$annotatedParameters[$class][$method->name])) {
$definedParameters = array();
$definedParameters = [];
foreach ($method->getParameters() as $parameter) {
$definedParameters[$parameter->name] = true;
}
@@ -315,10 +323,10 @@ class DebugClassLoader
$finalOrInternal = false;
foreach (array('final', 'internal') as $annotation) {
foreach (['final', 'internal'] as $annotation) {
if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$)#s', $doc, $notice)) {
$message = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : '';
self::${$annotation.'Methods'}[$class][$method->name] = array($class, $message);
$message = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : '';
self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message];
$finalOrInternal = true;
}
}
@@ -330,7 +338,7 @@ class DebugClassLoader
continue;
}
if (!isset(self::$annotatedParameters[$class][$method->name])) {
$definedParameters = array();
$definedParameters = [];
foreach ($method->getParameters() as $parameter) {
$definedParameters[$parameter->name] = true;
}
@@ -376,7 +384,7 @@ class DebugClassLoader
if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
&& 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
) {
return array(substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1));
return [substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)];
}
}
@@ -406,7 +414,7 @@ class DebugClassLoader
$k = $kDir;
$i = \strlen($dir) - 1;
while (!isset(self::$darwinCache[$k])) {
self::$darwinCache[$k] = array($dir, array());
self::$darwinCache[$k] = [$dir, []];
self::$darwinCache[$dir] = &self::$darwinCache[$k];
while ('/' !== $dir[--$i]) {
@@ -419,6 +427,11 @@ class DebugClassLoader
$dirFiles = self::$darwinCache[$kDir][1];
if (!isset($dirFiles[$file]) && ') : eval()\'d code' === substr($file, -17)) {
// Get the file name from "file_name.php(123) : eval()'d code"
$file = substr($file, 0, strrpos($file, '(', -17));
}
if (isset($dirFiles[$file])) {
return $real .= $dirFiles[$file];
}

View File

@@ -48,7 +48,7 @@ use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
*/
class ErrorHandler
{
private $levels = array(
private $levels = [
E_DEPRECATED => 'Deprecated',
E_USER_DEPRECATED => 'User Deprecated',
E_NOTICE => 'Notice',
@@ -64,25 +64,25 @@ class ErrorHandler
E_PARSE => 'Parse Error',
E_ERROR => 'Error',
E_CORE_ERROR => 'Core Error',
);
];
private $loggers = array(
E_DEPRECATED => array(null, LogLevel::INFO),
E_USER_DEPRECATED => array(null, LogLevel::INFO),
E_NOTICE => array(null, LogLevel::WARNING),
E_USER_NOTICE => array(null, LogLevel::WARNING),
E_STRICT => array(null, LogLevel::WARNING),
E_WARNING => array(null, LogLevel::WARNING),
E_USER_WARNING => array(null, LogLevel::WARNING),
E_COMPILE_WARNING => array(null, LogLevel::WARNING),
E_CORE_WARNING => array(null, LogLevel::WARNING),
E_USER_ERROR => array(null, LogLevel::CRITICAL),
E_RECOVERABLE_ERROR => array(null, LogLevel::CRITICAL),
E_COMPILE_ERROR => array(null, LogLevel::CRITICAL),
E_PARSE => array(null, LogLevel::CRITICAL),
E_ERROR => array(null, LogLevel::CRITICAL),
E_CORE_ERROR => array(null, LogLevel::CRITICAL),
);
private $loggers = [
E_DEPRECATED => [null, LogLevel::INFO],
E_USER_DEPRECATED => [null, LogLevel::INFO],
E_NOTICE => [null, LogLevel::WARNING],
E_USER_NOTICE => [null, LogLevel::WARNING],
E_STRICT => [null, LogLevel::WARNING],
E_WARNING => [null, LogLevel::WARNING],
E_USER_WARNING => [null, LogLevel::WARNING],
E_COMPILE_WARNING => [null, LogLevel::WARNING],
E_CORE_WARNING => [null, LogLevel::WARNING],
E_USER_ERROR => [null, LogLevel::CRITICAL],
E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL],
E_COMPILE_ERROR => [null, LogLevel::CRITICAL],
E_PARSE => [null, LogLevel::CRITICAL],
E_ERROR => [null, LogLevel::CRITICAL],
E_CORE_ERROR => [null, LogLevel::CRITICAL],
];
private $thrownErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED
private $scopedErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED
@@ -98,7 +98,7 @@ class ErrorHandler
private static $reservedMemory;
private static $toStringException = null;
private static $silencedErrorCache = array();
private static $silencedErrorCache = [];
private static $silencedErrorCount = 0;
private static $exitCode = 0;
@@ -121,10 +121,10 @@ class ErrorHandler
$handler = new static();
}
if (null === $prev = set_error_handler(array($handler, 'handleError'))) {
if (null === $prev = set_error_handler([$handler, 'handleError'])) {
restore_error_handler();
// Specifying the error types earlier would expose us to https://bugs.php.net/63206
set_error_handler(array($handler, 'handleError'), $handler->thrownErrors | $handler->loggedErrors);
set_error_handler([$handler, 'handleError'], $handler->thrownErrors | $handler->loggedErrors);
$handler->isRoot = true;
}
@@ -138,12 +138,12 @@ class ErrorHandler
} else {
$handlerIsRegistered = true;
}
if (\is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] instanceof self) {
if (\is_array($prev = set_exception_handler([$handler, 'handleException'])) && $prev[0] instanceof self) {
restore_exception_handler();
if (!$handlerIsRegistered) {
$handler = $prev[0];
} elseif ($handler !== $prev[0] && $replace) {
set_exception_handler(array($handler, 'handleException'));
set_exception_handler([$handler, 'handleException']);
$p = $prev[0]->setExceptionHandler(null);
$handler->setExceptionHandler($p);
$prev[0]->setExceptionHandler($p);
@@ -176,12 +176,12 @@ class ErrorHandler
*/
public function setDefaultLogger(LoggerInterface $logger, $levels = E_ALL, $replace = false)
{
$loggers = array();
$loggers = [];
if (\is_array($levels)) {
foreach ($levels as $type => $logLevel) {
if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] === $this->bootstrappingLogger) {
$loggers[$type] = array($logger, $logLevel);
$loggers[$type] = [$logger, $logLevel];
}
}
} else {
@@ -212,15 +212,15 @@ class ErrorHandler
{
$prevLogged = $this->loggedErrors;
$prev = $this->loggers;
$flush = array();
$flush = [];
foreach ($loggers as $type => $log) {
if (!isset($prev[$type])) {
throw new \InvalidArgumentException('Unknown error type: '.$type);
}
if (!\is_array($log)) {
$log = array($log);
} elseif (!array_key_exists(0, $log)) {
$log = [$log];
} elseif (!\array_key_exists(0, $log)) {
throw new \InvalidArgumentException('No logger provided');
}
if (null === $log[0]) {
@@ -356,9 +356,9 @@ class ErrorHandler
if ($handler === $this) {
restore_error_handler();
if ($this->isRoot) {
set_error_handler(array($this, 'handleError'), $this->thrownErrors | $this->loggedErrors);
set_error_handler([$this, 'handleError'], $this->thrownErrors | $this->loggedErrors);
} else {
set_error_handler(array($this, 'handleError'));
set_error_handler([$this, 'handleError']);
}
}
}
@@ -395,9 +395,9 @@ class ErrorHandler
$scope = $this->scopedErrors & $type;
if (4 < $numArgs = \func_num_args()) {
$context = $scope ? (func_get_arg(4) ?: array()) : array();
$context = $scope ? (func_get_arg(4) ?: []) : [];
} else {
$context = array();
$context = [];
}
if (isset($context['GLOBALS']) && $scope) {
@@ -417,19 +417,19 @@ class ErrorHandler
self::$toStringException = null;
} elseif (!$throw && !($type & $level)) {
if (!isset(self::$silencedErrorCache[$id = $file.':'.$line])) {
$lightTrace = $this->tracedErrors & $type ? $this->cleanTrace(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5), $type, $file, $line, false) : array();
$errorAsException = new SilencedErrorContext($type, $file, $line, isset($lightTrace[1]) ? array($lightTrace[0]) : $lightTrace);
$lightTrace = $this->tracedErrors & $type ? $this->cleanTrace(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5), $type, $file, $line, false) : [];
$errorAsException = new SilencedErrorContext($type, $file, $line, isset($lightTrace[1]) ? [$lightTrace[0]] : $lightTrace);
} elseif (isset(self::$silencedErrorCache[$id][$message])) {
$lightTrace = null;
$errorAsException = self::$silencedErrorCache[$id][$message];
++$errorAsException->count;
} else {
$lightTrace = array();
$lightTrace = [];
$errorAsException = null;
}
if (100 < ++self::$silencedErrorCount) {
self::$silencedErrorCache = $lightTrace = array();
self::$silencedErrorCache = $lightTrace = [];
self::$silencedErrorCount = 1;
}
if ($errorAsException) {
@@ -446,8 +446,8 @@ class ErrorHandler
$lightTrace = $this->cleanTrace($backtrace, $type, $file, $line, $throw);
$this->traceReflector->setValue($errorAsException, $lightTrace);
} else {
$this->traceReflector->setValue($errorAsException, array());
$backtrace = array();
$this->traceReflector->setValue($errorAsException, []);
$backtrace = [];
}
}
@@ -490,12 +490,21 @@ class ErrorHandler
if ($this->isRecursive) {
$log = 0;
} else {
if (!\defined('HHVM_VERSION')) {
$currentErrorHandler = set_error_handler('var_dump');
restore_error_handler();
}
try {
$this->isRecursive = true;
$level = ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG;
$this->loggers[$type][0]->log($level, $logMessage, $errorAsException ? array('exception' => $errorAsException) : array());
$this->loggers[$type][0]->log($level, $logMessage, $errorAsException ? ['exception' => $errorAsException] : []);
} finally {
$this->isRecursive = false;
if (!\defined('HHVM_VERSION')) {
set_error_handler($currentErrorHandler);
}
}
}
@@ -527,12 +536,12 @@ class ErrorHandler
}
if ($exception instanceof FatalErrorException) {
if ($exception instanceof FatalThrowableError) {
$error = array(
$error = [
'type' => $type,
'message' => $message,
'file' => $exception->getFile(),
'line' => $exception->getLine(),
);
];
} else {
$message = 'Fatal '.$message;
}
@@ -544,7 +553,7 @@ class ErrorHandler
}
if ($this->loggedErrors & $type) {
try {
$this->loggers[$type][0]->log($this->loggers[$type][1], $message, array('exception' => $exception));
$this->loggers[$type][0]->log($this->loggers[$type][1], $message, ['exception' => $exception]);
} catch (\Throwable $handlerException) {
}
}
@@ -586,7 +595,7 @@ class ErrorHandler
}
$handler = self::$reservedMemory = null;
$handlers = array();
$handlers = [];
$previousHandler = null;
$sameHandlerLimit = 10;
@@ -617,7 +626,7 @@ class ErrorHandler
$handler[0]->setExceptionHandler($h);
}
$handler = $handler[0];
$handlers = array();
$handlers = [];
if ($exit = null === $error) {
$error = error_get_last();
@@ -661,11 +670,11 @@ class ErrorHandler
*/
protected function getFatalErrorHandlers()
{
return array(
return [
new UndefinedFunctionFatalErrorHandler(),
new UndefinedMethodFatalErrorHandler(),
new ClassNotFoundFatalErrorHandler(),
);
];
}
/**

View File

@@ -61,7 +61,7 @@ class FatalErrorException extends \ErrorException
unset($frame);
$trace = array_reverse($trace);
} else {
$trace = array();
$trace = [];
}
$this->setTrace($trace);

View File

@@ -33,12 +33,12 @@ class FlattenException
private $file;
private $line;
public static function create(\Exception $exception, $statusCode = null, array $headers = array())
public static function create(\Exception $exception, $statusCode = null, array $headers = [])
{
return static::createFromThrowable($exception, $statusCode, $headers);
}
public static function createFromThrowable(\Throwable $exception, ?int $statusCode = null, array $headers = array()): self
public static function createFromThrowable(\Throwable $exception, ?int $statusCode = null, array $headers = []): self
{
$e = new static();
$e->setMessage($exception->getMessage());
@@ -73,13 +73,13 @@ class FlattenException
public function toArray()
{
$exceptions = array();
foreach (array_merge(array($this), $this->getAllPrevious()) as $exception) {
$exceptions[] = array(
$exceptions = [];
foreach (array_merge([$this], $this->getAllPrevious()) as $exception) {
$exceptions[] = [
'message' => $exception->getMessage(),
'class' => $exception->getClass(),
'trace' => $exception->getTrace(),
);
];
}
return $exceptions;
@@ -213,7 +213,7 @@ class FlattenException
public function getAllPrevious()
{
$exceptions = array();
$exceptions = [];
$e = $this;
while ($e = $e->getPrevious()) {
$exceptions[] = $e;
@@ -247,8 +247,8 @@ class FlattenException
*/
public function setTrace($trace, $file, $line)
{
$this->trace = array();
$this->trace[] = array(
$this->trace = [];
$this->trace[] = [
'namespace' => '',
'short_class' => '',
'class' => '',
@@ -256,8 +256,8 @@ class FlattenException
'function' => '',
'file' => $file,
'line' => $line,
'args' => array(),
);
'args' => [],
];
foreach ($trace as $entry) {
$class = '';
$namespace = '';
@@ -267,7 +267,7 @@ class FlattenException
$namespace = implode('\\', $parts);
}
$this->trace[] = array(
$this->trace[] = [
'namespace' => $namespace,
'short_class' => $class,
'class' => isset($entry['class']) ? $entry['class'] : '',
@@ -275,8 +275,8 @@ class FlattenException
'function' => isset($entry['function']) ? $entry['function'] : null,
'file' => isset($entry['file']) ? $entry['file'] : null,
'line' => isset($entry['line']) ? $entry['line'] : null,
'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : array(),
);
'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : [],
];
}
return $this;
@@ -284,34 +284,34 @@ class FlattenException
private function flattenArgs($args, $level = 0, &$count = 0)
{
$result = array();
$result = [];
foreach ($args as $key => $value) {
if (++$count > 1e4) {
return array('array', '*SKIPPED over 10000 entries*');
return ['array', '*SKIPPED over 10000 entries*'];
}
if ($value instanceof \__PHP_Incomplete_Class) {
// is_object() returns false on PHP<=7.1
$result[$key] = array('incomplete-object', $this->getClassNameFromIncomplete($value));
$result[$key] = ['incomplete-object', $this->getClassNameFromIncomplete($value)];
} elseif (\is_object($value)) {
$result[$key] = array('object', \get_class($value));
$result[$key] = ['object', \get_class($value)];
} elseif (\is_array($value)) {
if ($level > 10) {
$result[$key] = array('array', '*DEEP NESTED ARRAY*');
$result[$key] = ['array', '*DEEP NESTED ARRAY*'];
} else {
$result[$key] = array('array', $this->flattenArgs($value, $level + 1, $count));
$result[$key] = ['array', $this->flattenArgs($value, $level + 1, $count)];
}
} elseif (null === $value) {
$result[$key] = array('null', null);
$result[$key] = ['null', null];
} elseif (\is_bool($value)) {
$result[$key] = array('boolean', $value);
$result[$key] = ['boolean', $value];
} elseif (\is_int($value)) {
$result[$key] = array('integer', $value);
$result[$key] = ['integer', $value];
} elseif (\is_float($value)) {
$result[$key] = array('float', $value);
$result[$key] = ['float', $value];
} elseif (\is_resource($value)) {
$result[$key] = array('resource', get_resource_type($value));
$result[$key] = ['resource', get_resource_type($value)];
} else {
$result[$key] = array('string', (string) $value);
$result[$key] = ['string', (string) $value];
}
}

View File

@@ -25,7 +25,7 @@ class SilencedErrorContext implements \JsonSerializable
private $line;
private $trace;
public function __construct(int $severity, string $file, int $line, array $trace = array(), int $count = 1)
public function __construct(int $severity, string $file, int $line, array $trace = [], int $count = 1)
{
$this->severity = $severity;
$this->file = $file;
@@ -56,12 +56,12 @@ class SilencedErrorContext implements \JsonSerializable
public function JsonSerialize()
{
return array(
return [
'severity' => $this->severity,
'file' => $this->file,
'line' => $this->line,
'trace' => $this->trace,
'count' => $this->count,
);
];
}
}

View File

@@ -56,10 +56,10 @@ class ExceptionHandler
{
$handler = new static($debug, $charset, $fileLinkFormat);
$prev = set_exception_handler(array($handler, 'handle'));
$prev = set_exception_handler([$handler, 'handle']);
if (\is_array($prev) && $prev[0] instanceof ErrorHandler) {
restore_exception_handler();
$prev[0]->setExceptionHandler(array($handler, 'handle'));
$prev[0]->setExceptionHandler([$handler, 'handle']);
}
return $handler;
@@ -378,7 +378,7 @@ EOF;
if (\is_string($fmt)) {
$i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f);
$fmt = array(substr($f, 0, $i)) + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE);
$fmt = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 1; isset($fmt[$i]); ++$i) {
if (0 === strpos($path, $k = $fmt[$i++])) {
@@ -387,7 +387,7 @@ EOF;
}
}
$link = strtr($fmt[0], array('%f' => $path, '%l' => $line));
$link = strtr($fmt[0], ['%f' => $path, '%l' => $line]);
} else {
$link = $fmt->format($path, $line);
}
@@ -404,7 +404,7 @@ EOF;
*/
private function formatArgs(array $args)
{
$result = array();
$result = [];
foreach ($args as $key => $item) {
if ('object' === $item[0]) {
$formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));

View File

@@ -40,7 +40,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
return;
}
foreach (array('class', 'interface', 'trait') as $typeName) {
foreach (['class', 'interface', 'trait'] as $typeName) {
$prefix = ucfirst($typeName).' \'';
$prefixLen = \strlen($prefix);
if (0 !== strpos($error['message'], $prefix)) {
@@ -86,11 +86,11 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
private function getClassCandidates(string $class): array
{
if (!\is_array($functions = spl_autoload_functions())) {
return array();
return [];
}
// find Symfony and Composer autoloaders
$classes = array();
$classes = [];
foreach ($functions as $function) {
if (!\is_array($function)) {
@@ -127,10 +127,10 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
private function findClassInPath(string $path, string $class, string $prefix): array
{
if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.\dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
return array();
return [];
}
$classes = array();
$classes = [];
$filename = $class.'.php';
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) {
@@ -143,9 +143,9 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
private function convertFileToClass(string $path, string $file, string $prefix): ?string
{
$candidates = array(
$candidates = [
// namespaced class
$namespacedClass = str_replace(array($path.\DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
$namespacedClass = str_replace([$path.\DIRECTORY_SEPARATOR, '.php', '/'], ['', '', '\\'], $file),
// namespaced class (with target dir)
$prefix.$namespacedClass,
// namespaced class (with target dir and separator)
@@ -156,7 +156,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
str_replace('\\', '_', $prefix.$namespacedClass),
// PEAR class (with target dir and separator)
str_replace('\\', '_', $prefix.'\\'.$namespacedClass),
);
];
if ($prefix) {
$candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); });

View File

@@ -53,7 +53,7 @@ class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
$message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName);
}
$candidates = array();
$candidates = [];
foreach (get_defined_functions() as $type => $definedFunctionNames) {
foreach ($definedFunctionNames as $definedFunctionName) {
if (false !== $namespaceSeparatorIndex = strrpos($definedFunctionName, '\\')) {

View File

@@ -41,7 +41,7 @@ class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
return new UndefinedMethodException($message, $exception);
}
$candidates = array();
$candidates = [];
foreach ($methods as $definedMethodName) {
$lev = levenshtein($methodName, $definedMethodName);
if ($lev <= \strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {

View File

@@ -27,14 +27,14 @@ class DebugClassLoaderTest extends TestCase
{
$this->errorReporting = error_reporting(E_ALL);
$this->loader = new ClassLoader();
spl_autoload_register(array($this->loader, 'loadClass'), true, true);
spl_autoload_register([$this->loader, 'loadClass'], true, true);
DebugClassLoader::enable();
}
protected function tearDown()
{
DebugClassLoader::disable();
spl_autoload_unregister(array($this->loader, 'loadClass'));
spl_autoload_unregister([$this->loader, 'loadClass']);
error_reporting($this->errorReporting);
}
@@ -44,7 +44,7 @@ class DebugClassLoaderTest extends TestCase
$functions = spl_autoload_functions();
foreach ($functions as $function) {
if (is_array($function) && $function[0] instanceof DebugClassLoader) {
if (\is_array($function) && $function[0] instanceof DebugClassLoader) {
$reflClass = new \ReflectionClass($function[0]);
$reflProp = $reflClass->getProperty('classLoader');
$reflProp->setAccessible(true);
@@ -136,20 +136,20 @@ class DebugClassLoaderTest extends TestCase
$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);
$xError = array(
$xError = [
'type' => E_USER_DEPRECATED,
'message' => 'The "Test\Symfony\Component\Debug\Tests\\'.$class.'" class '.$type.' "Symfony\Component\Debug\Tests\Fixtures\\'.$super.'" that is deprecated but this is a test deprecation notice.',
);
];
$this->assertSame($xError, $lastError);
}
public function provideDeprecatedSuper()
{
return array(
array('DeprecatedInterfaceClass', 'DeprecatedInterface', 'implements'),
array('DeprecatedParentClass', 'DeprecatedClass', 'extends'),
);
return [
['DeprecatedInterfaceClass', 'DeprecatedInterface', 'implements'],
['DeprecatedParentClass', 'DeprecatedClass', 'extends'],
];
}
public function testInterfaceExtendsDeprecatedInterface()
@@ -166,10 +166,10 @@ class DebugClassLoaderTest extends TestCase
$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);
$xError = array(
$xError = [
'type' => E_USER_NOTICE,
'message' => '',
);
];
$this->assertSame($xError, $lastError);
}
@@ -188,39 +188,46 @@ class DebugClassLoaderTest extends TestCase
$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);
$xError = array(
$xError = [
'type' => E_USER_NOTICE,
'message' => '',
);
];
$this->assertSame($xError, $lastError);
}
public function testExtendedFinalClass()
{
set_error_handler(function () { return false; });
$e = error_reporting(0);
trigger_error('', E_USER_NOTICE);
$deprecations = [];
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists('Test\\'.__NAMESPACE__.'\\ExtendsFinalClass', true);
require __DIR__.'/Fixtures/FinalClasses.php';
$i = 1;
while (class_exists($finalClass = __NAMESPACE__.'\\Fixtures\\FinalClass'.$i++, false)) {
spl_autoload_call($finalClass);
class_exists('Test\\'.__NAMESPACE__.'\\Extends'.substr($finalClass, strrpos($finalClass, '\\') + 1), true);
}
error_reporting($e);
restore_error_handler();
$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);
$xError = array(
'type' => E_USER_DEPRECATED,
'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass".',
);
$this->assertSame($xError, $lastError);
$this->assertSame([
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass1" class is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass1".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass2" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass2".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass3" class is considered final comment with @@@ and ***. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass3".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass4" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass4".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass5" class is considered final multiline comment. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass5".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass6" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass6".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass7" class is considered final another multiline comment... It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass7".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass8" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass8".',
], $deprecations);
}
public function testExtendedFinalMethod()
{
$deprecations = array();
$deprecations = [];
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
@@ -229,10 +236,10 @@ class DebugClassLoaderTest extends TestCase
error_reporting($e);
restore_error_handler();
$xError = array(
$xError = [
'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
);
];
$this->assertSame($xError, $deprecations);
}
@@ -251,12 +258,12 @@ class DebugClassLoaderTest extends TestCase
$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);
$this->assertSame(array('type' => E_USER_NOTICE, 'message' => ''), $lastError);
$this->assertSame(['type' => E_USER_NOTICE, 'message' => ''], $lastError);
}
public function testInternalsUse()
{
$deprecations = array();
$deprecations = [];
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
@@ -265,17 +272,17 @@ class DebugClassLoaderTest extends TestCase
error_reporting($e);
restore_error_handler();
$this->assertSame($deprecations, array(
$this->assertSame($deprecations, [
'The "Symfony\Component\Debug\Tests\Fixtures\InternalInterface" interface is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".',
'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass" class is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".',
'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait" trait is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".',
'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass::internalMethod()" method is considered internal. It may change without further notice. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".',
));
]);
}
public function testExtendedMethodDefinesNewParameters()
{
$deprecations = array();
$deprecations = [];
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
@@ -284,16 +291,16 @@ class DebugClassLoaderTest extends TestCase
error_reporting($e);
restore_error_handler();
$this->assertSame(array(
$this->assertSame([
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::quzMethod()" method will require a new "Quz $quz" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\ClassWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::whereAmI()" method will require a new "bool $matrix" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::isSymfony()" method will require a new "true $yes" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\ClassWithAnnotatedParameters", not defining it is deprecated.',
), $deprecations);
], $deprecations);
}
public function testUseTraitWithInternalMethod()
{
$deprecations = array();
$deprecations = [];
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
@@ -302,7 +309,12 @@ class DebugClassLoaderTest extends TestCase
error_reporting($e);
restore_error_handler();
$this->assertSame(array(), $deprecations);
$this->assertSame([], $deprecations);
}
public function testEvaluatedCode()
{
$this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\DefinitionInEvaluatedCode', true));
}
}
@@ -314,12 +326,12 @@ class ClassLoader
public function getClassMap()
{
return array(__NAMESPACE__.'\Fixtures\NotPSR0bis' => __DIR__.'/Fixtures/notPsr0Bis.php');
return [__NAMESPACE__.'\Fixtures\NotPSR0bis' => __DIR__.'/Fixtures/notPsr0Bis.php'];
}
public function findFile($class)
{
$fixtureDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR;
$fixtureDir = __DIR__.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR;
if (__NAMESPACE__.'\TestingUnsilencing' === $class) {
eval('-- parse error --');
@@ -328,7 +340,7 @@ class ClassLoader
} elseif (__NAMESPACE__.'\TestingCaseMismatch' === $class) {
eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}');
} elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) {
return $fixtureDir.'psr4'.DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php';
return $fixtureDir.'psr4'.\DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php';
} elseif (__NAMESPACE__.'\Fixtures\NotPSR0' === $class) {
return $fixtureDir.'reallyNotPsr0.php';
} elseif (__NAMESPACE__.'\Fixtures\NotPSR0bis' === $class) {
@@ -343,8 +355,9 @@ class ClassLoader
eval('namespace Test\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\NonDeprecatedInterface {}');
} elseif ('Test\\'.__NAMESPACE__.'\Float' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class Float {}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsFinalClass' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsFinalClass extends \\'.__NAMESPACE__.'\Fixtures\FinalClass {}');
} elseif (0 === strpos($class, 'Test\\'.__NAMESPACE__.'\ExtendsFinalClass')) {
$classShortName = substr($class, strrpos($class, '\\') + 1);
eval('namespace Test\\'.__NAMESPACE__.'; class '.$classShortName.' extends \\'.__NAMESPACE__.'\Fixtures\\'.substr($classShortName, 7).' {}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsAnnotatedClass' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsAnnotatedClass extends \\'.__NAMESPACE__.'\Fixtures\AnnotatedClass {
public function deprecatedMethod() { }

View File

@@ -13,9 +13,12 @@ namespace Symfony\Component\Debug\Tests;
use PHPUnit\Framework\TestCase;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
use Symfony\Component\Debug\BufferingLogger;
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\Exception\SilencedErrorContext;
use Symfony\Component\Debug\Tests\Fixtures\ErrorHandlerThatUsesThePreviousOne;
use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler;
/**
* ErrorHandlerTest.
@@ -38,13 +41,13 @@ class ErrorHandlerTest extends TestCase
$this->assertSame($handler, ErrorHandler::register($newHandler, false));
$h = set_error_handler('var_dump');
restore_error_handler();
$this->assertSame(array($handler, 'handleError'), $h);
$this->assertSame([$handler, 'handleError'], $h);
try {
$this->assertSame($newHandler, ErrorHandler::register($newHandler, true));
$h = set_error_handler('var_dump');
restore_error_handler();
$this->assertSame(array($newHandler, 'handleError'), $h);
$this->assertSame([$newHandler, 'handleError'], $h);
} catch (\Exception $e) {
}
@@ -74,12 +77,12 @@ class ErrorHandlerTest extends TestCase
try {
@trigger_error('Hello', E_USER_WARNING);
$expected = array(
$expected = [
'type' => E_USER_WARNING,
'message' => 'Hello',
'file' => __FILE__,
'line' => __LINE__ - 5,
);
];
$this->assertSame($expected, error_get_last());
} catch (\Exception $e) {
restore_error_handler();
@@ -145,26 +148,26 @@ class ErrorHandlerTest extends TestCase
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$handler->setDefaultLogger($logger, E_NOTICE);
$handler->setDefaultLogger($logger, array(E_USER_NOTICE => LogLevel::CRITICAL));
$handler->setDefaultLogger($logger, [E_USER_NOTICE => LogLevel::CRITICAL]);
$loggers = array(
E_DEPRECATED => array(null, LogLevel::INFO),
E_USER_DEPRECATED => array(null, LogLevel::INFO),
E_NOTICE => array($logger, LogLevel::WARNING),
E_USER_NOTICE => array($logger, LogLevel::CRITICAL),
E_STRICT => array(null, LogLevel::WARNING),
E_WARNING => array(null, LogLevel::WARNING),
E_USER_WARNING => array(null, LogLevel::WARNING),
E_COMPILE_WARNING => array(null, LogLevel::WARNING),
E_CORE_WARNING => array(null, LogLevel::WARNING),
E_USER_ERROR => array(null, LogLevel::CRITICAL),
E_RECOVERABLE_ERROR => array(null, LogLevel::CRITICAL),
E_COMPILE_ERROR => array(null, LogLevel::CRITICAL),
E_PARSE => array(null, LogLevel::CRITICAL),
E_ERROR => array(null, LogLevel::CRITICAL),
E_CORE_ERROR => array(null, LogLevel::CRITICAL),
);
$this->assertSame($loggers, $handler->setLoggers(array()));
$loggers = [
E_DEPRECATED => [null, LogLevel::INFO],
E_USER_DEPRECATED => [null, LogLevel::INFO],
E_NOTICE => [$logger, LogLevel::WARNING],
E_USER_NOTICE => [$logger, LogLevel::CRITICAL],
E_STRICT => [null, LogLevel::WARNING],
E_WARNING => [null, LogLevel::WARNING],
E_USER_WARNING => [null, LogLevel::WARNING],
E_COMPILE_WARNING => [null, LogLevel::WARNING],
E_CORE_WARNING => [null, LogLevel::WARNING],
E_USER_ERROR => [null, LogLevel::CRITICAL],
E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL],
E_COMPILE_ERROR => [null, LogLevel::CRITICAL],
E_PARSE => [null, LogLevel::CRITICAL],
E_ERROR => [null, LogLevel::CRITICAL],
E_CORE_ERROR => [null, LogLevel::CRITICAL],
];
$this->assertSame($loggers, $handler->setLoggers([]));
} finally {
restore_error_handler();
restore_exception_handler();
@@ -176,14 +179,14 @@ class ErrorHandlerTest extends TestCase
try {
$handler = ErrorHandler::register();
$handler->throwAt(0, true);
$this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, array()));
$this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, []));
restore_error_handler();
restore_exception_handler();
$handler = ErrorHandler::register();
$handler->throwAt(3, true);
$this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, array()));
$this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, []));
restore_error_handler();
restore_exception_handler();
@@ -191,7 +194,7 @@ class ErrorHandlerTest extends TestCase
$handler = ErrorHandler::register();
$handler->throwAt(3, true);
try {
$handler->handleError(4, 'foo', 'foo.php', 12, array());
$handler->handleError(4, 'foo', 'foo.php', 12, []);
} catch (\ErrorException $e) {
$this->assertSame('Parse Error: foo', $e->getMessage());
$this->assertSame(4, $e->getSeverity());
@@ -204,14 +207,14 @@ class ErrorHandlerTest extends TestCase
$handler = ErrorHandler::register();
$handler->throwAt(E_USER_DEPRECATED, true);
$this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));
$this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
restore_error_handler();
restore_exception_handler();
$handler = ErrorHandler::register();
$handler->throwAt(E_DEPRECATED, true);
$this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, array()));
$this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, []));
restore_error_handler();
restore_exception_handler();
@@ -236,7 +239,7 @@ class ErrorHandlerTest extends TestCase
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_USER_DEPRECATED);
$this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));
$this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
restore_error_handler();
restore_exception_handler();
@@ -320,7 +323,9 @@ class ErrorHandlerTest extends TestCase
$handler = new ErrorHandler();
$handler->setDefaultLogger($logger);
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, array());
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
restore_error_handler();
}
public function testHandleException()
@@ -369,27 +374,27 @@ class ErrorHandlerTest extends TestCase
$bootLogger = new BufferingLogger();
$handler = new ErrorHandler($bootLogger);
$loggers = array(
E_DEPRECATED => array($bootLogger, LogLevel::INFO),
E_USER_DEPRECATED => array($bootLogger, LogLevel::INFO),
E_NOTICE => array($bootLogger, LogLevel::WARNING),
E_USER_NOTICE => array($bootLogger, LogLevel::WARNING),
E_STRICT => array($bootLogger, LogLevel::WARNING),
E_WARNING => array($bootLogger, LogLevel::WARNING),
E_USER_WARNING => array($bootLogger, LogLevel::WARNING),
E_COMPILE_WARNING => array($bootLogger, LogLevel::WARNING),
E_CORE_WARNING => array($bootLogger, LogLevel::WARNING),
E_USER_ERROR => array($bootLogger, LogLevel::CRITICAL),
E_RECOVERABLE_ERROR => array($bootLogger, LogLevel::CRITICAL),
E_COMPILE_ERROR => array($bootLogger, LogLevel::CRITICAL),
E_PARSE => array($bootLogger, LogLevel::CRITICAL),
E_ERROR => array($bootLogger, LogLevel::CRITICAL),
E_CORE_ERROR => array($bootLogger, LogLevel::CRITICAL),
);
$loggers = [
E_DEPRECATED => [$bootLogger, LogLevel::INFO],
E_USER_DEPRECATED => [$bootLogger, LogLevel::INFO],
E_NOTICE => [$bootLogger, LogLevel::WARNING],
E_USER_NOTICE => [$bootLogger, LogLevel::WARNING],
E_STRICT => [$bootLogger, LogLevel::WARNING],
E_WARNING => [$bootLogger, LogLevel::WARNING],
E_USER_WARNING => [$bootLogger, LogLevel::WARNING],
E_COMPILE_WARNING => [$bootLogger, LogLevel::WARNING],
E_CORE_WARNING => [$bootLogger, LogLevel::WARNING],
E_USER_ERROR => [$bootLogger, LogLevel::CRITICAL],
E_RECOVERABLE_ERROR => [$bootLogger, LogLevel::CRITICAL],
E_COMPILE_ERROR => [$bootLogger, LogLevel::CRITICAL],
E_PARSE => [$bootLogger, LogLevel::CRITICAL],
E_ERROR => [$bootLogger, LogLevel::CRITICAL],
E_CORE_ERROR => [$bootLogger, LogLevel::CRITICAL],
];
$this->assertSame($loggers, $handler->setLoggers(array()));
$this->assertSame($loggers, $handler->setLoggers([]));
$handler->handleError(E_DEPRECATED, 'Foo message', __FILE__, 123, array());
$handler->handleError(E_DEPRECATED, 'Foo message', __FILE__, 123, []);
$logs = $bootLogger->cleanLogs();
@@ -405,14 +410,14 @@ class ErrorHandlerTest extends TestCase
$this->assertSame(123, $exception->getLine());
$this->assertSame(E_DEPRECATED, $exception->getSeverity());
$bootLogger->log(LogLevel::WARNING, 'Foo message', array('exception' => $exception));
$bootLogger->log(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
$mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$mockLogger->expects($this->once())
->method('log')
->with(LogLevel::WARNING, 'Foo message', array('exception' => $exception));
->with(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
$handler->setLoggers(array(E_DEPRECATED => array($mockLogger, LogLevel::WARNING)));
$handler->setLoggers([E_DEPRECATED => [$mockLogger, LogLevel::WARNING]]);
}
public function testSettingLoggerWhenExceptionIsBuffered()
@@ -425,7 +430,7 @@ class ErrorHandlerTest extends TestCase
$mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$mockLogger->expects($this->once())
->method('log')
->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', array('exception' => $exception));
->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', ['exception' => $exception]);
$handler->setExceptionHandler(function () use ($handler, $mockLogger) {
$handler->setDefaultLogger($mockLogger);
@@ -439,12 +444,12 @@ class ErrorHandlerTest extends TestCase
try {
$handler = ErrorHandler::register();
$error = array(
$error = [
'type' => E_PARSE,
'message' => 'foo',
'file' => 'bar',
'line' => 123,
);
];
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
@@ -501,4 +506,58 @@ class ErrorHandlerTest extends TestCase
$handler->handleException(new \Exception());
}
/**
* @dataProvider errorHandlerWhenLoggingProvider
*/
public function testErrorHandlerWhenLogging($previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined)
{
try {
if ($previousHandlerWasDefined) {
set_error_handler('count');
}
$logger = $loggerSetsAnotherHandler ? new LoggerThatSetAnErrorHandler() : new NullLogger();
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger);
if ($nextHandlerIsDefined) {
$handler = ErrorHandlerThatUsesThePreviousOne::register();
}
@trigger_error('foo', E_USER_DEPRECATED);
@trigger_error('bar', E_USER_DEPRECATED);
$this->assertSame([$handler, 'handleError'], set_error_handler('var_dump'));
if ($logger instanceof LoggerThatSetAnErrorHandler) {
$this->assertCount(2, $logger->cleanLogs());
}
restore_error_handler();
if ($previousHandlerWasDefined) {
restore_error_handler();
}
if ($nextHandlerIsDefined) {
restore_error_handler();
}
} finally {
restore_error_handler();
restore_exception_handler();
}
}
public function errorHandlerWhenLoggingProvider()
{
foreach ([false, true] as $previousHandlerWasDefined) {
foreach ([false, true] as $loggerSetsAnotherHandler) {
foreach ([false, true] as $nextHandlerIsDefined) {
yield [$previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined];
}
}
}
}
}

View File

@@ -61,7 +61,7 @@ class FlattenExceptionTest extends TestCase
$flattened = FlattenException::create(new ConflictHttpException());
$this->assertEquals('409', $flattened->getStatusCode());
$flattened = FlattenException::create(new MethodNotAllowedHttpException(array('POST')));
$flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST']));
$this->assertEquals('405', $flattened->getStatusCode());
$flattened = FlattenException::create(new AccessDeniedHttpException());
@@ -96,23 +96,23 @@ class FlattenExceptionTest extends TestCase
public function testHeadersForHttpException()
{
$flattened = FlattenException::create(new MethodNotAllowedHttpException(array('POST')));
$this->assertEquals(array('Allow' => 'POST'), $flattened->getHeaders());
$flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST']));
$this->assertEquals(['Allow' => 'POST'], $flattened->getHeaders());
$flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"'));
$this->assertEquals(array('WWW-Authenticate' => 'Basic realm="My Realm"'), $flattened->getHeaders());
$this->assertEquals(['WWW-Authenticate' => 'Basic realm="My Realm"'], $flattened->getHeaders());
$flattened = FlattenException::create(new ServiceUnavailableHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));
$this->assertEquals(array('Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'), $flattened->getHeaders());
$this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders());
$flattened = FlattenException::create(new ServiceUnavailableHttpException(120));
$this->assertEquals(array('Retry-After' => 120), $flattened->getHeaders());
$this->assertEquals(['Retry-After' => 120], $flattened->getHeaders());
$flattened = FlattenException::create(new TooManyRequestsHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));
$this->assertEquals(array('Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'), $flattened->getHeaders());
$this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders());
$flattened = FlattenException::create(new TooManyRequestsHttpException(120));
$this->assertEquals(array('Retry-After' => 120), $flattened->getHeaders());
$this->assertEquals(['Retry-After' => 120], $flattened->getHeaders());
}
/**
@@ -162,7 +162,7 @@ class FlattenExceptionTest extends TestCase
$this->assertSame($flattened2, $flattened->getPrevious());
$this->assertSame(array($flattened2), $flattened->getAllPrevious());
$this->assertSame([$flattened2], $flattened->getAllPrevious());
}
public function testPreviousError()
@@ -200,18 +200,18 @@ class FlattenExceptionTest extends TestCase
public function testToArray(\Throwable $exception, string $expectedClass)
{
$flattened = FlattenException::createFromThrowable($exception);
$flattened->setTrace(array(), 'foo.php', 123);
$flattened->setTrace([], 'foo.php', 123);
$this->assertEquals(array(
array(
$this->assertEquals([
[
'message' => 'test',
'class' => $expectedClass,
'trace' => array(array(
'trace' => [[
'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123,
'args' => array(),
)),
),
), $flattened->toArray());
'args' => [],
]],
],
], $flattened->toArray());
}
public function testCreate()
@@ -229,10 +229,10 @@ class FlattenExceptionTest extends TestCase
public function flattenDataProvider()
{
return array(
array(new \Exception('test', 123), 'Exception'),
array(new \Error('test', 123), 'Error'),
);
return [
[new \Exception('test', 123), 'Exception'],
[new \Error('test', 123), 'Error'],
];
}
public function testArguments()
@@ -242,15 +242,15 @@ class FlattenExceptionTest extends TestCase
$incomplete = unserialize('O:14:"BogusTestClass":0:{}');
$exception = $this->createException(array(
(object) array('foo' => 1),
$exception = $this->createException([
(object) ['foo' => 1],
new NotFoundHttpException(),
$incomplete,
$dh,
$fh,
function () {},
array(1, 2),
array('foo' => 123),
[1, 2],
['foo' => 123],
null,
true,
false,
@@ -260,7 +260,7 @@ class FlattenExceptionTest extends TestCase
'',
INF,
NAN,
));
]);
$flattened = FlattenException::create($exception);
$trace = $flattened->getTrace();
@@ -271,26 +271,26 @@ class FlattenExceptionTest extends TestCase
fclose($fh);
$i = 0;
$this->assertSame(array('object', 'stdClass'), $array[$i++]);
$this->assertSame(array('object', 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException'), $array[$i++]);
$this->assertSame(array('incomplete-object', 'BogusTestClass'), $array[$i++]);
$this->assertSame(array('resource', 'stream'), $array[$i++]);
$this->assertSame(array('resource', 'stream'), $array[$i++]);
$this->assertSame(['object', 'stdClass'], $array[$i++]);
$this->assertSame(['object', 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException'], $array[$i++]);
$this->assertSame(['incomplete-object', 'BogusTestClass'], $array[$i++]);
$this->assertSame(['resource', 'stream'], $array[$i++]);
$this->assertSame(['resource', 'stream'], $array[$i++]);
$args = $array[$i++];
$this->assertSame($args[0], 'object');
$this->assertTrue('Closure' === $args[1] || is_subclass_of($args[1], '\Closure'), 'Expect object class name to be Closure or a subclass of Closure.');
$this->assertSame(array('array', array(array('integer', 1), array('integer', 2))), $array[$i++]);
$this->assertSame(array('array', array('foo' => array('integer', 123))), $array[$i++]);
$this->assertSame(array('null', null), $array[$i++]);
$this->assertSame(array('boolean', true), $array[$i++]);
$this->assertSame(array('boolean', false), $array[$i++]);
$this->assertSame(array('integer', 0), $array[$i++]);
$this->assertSame(array('float', 0.0), $array[$i++]);
$this->assertSame(array('string', '0'), $array[$i++]);
$this->assertSame(array('string', ''), $array[$i++]);
$this->assertSame(array('float', INF), $array[$i++]);
$this->assertSame(['array', [['integer', 1], ['integer', 2]]], $array[$i++]);
$this->assertSame(['array', ['foo' => ['integer', 123]]], $array[$i++]);
$this->assertSame(['null', null], $array[$i++]);
$this->assertSame(['boolean', true], $array[$i++]);
$this->assertSame(['boolean', false], $array[$i++]);
$this->assertSame(['integer', 0], $array[$i++]);
$this->assertSame(['float', 0.0], $array[$i++]);
$this->assertSame(['string', '0'], $array[$i++]);
$this->assertSame(['string', ''], $array[$i++]);
$this->assertSame(['float', INF], $array[$i++]);
// assertEquals() does not like NAN values.
$this->assertEquals($array[$i][0], 'float');
@@ -300,7 +300,7 @@ class FlattenExceptionTest extends TestCase
public function testRecursionInArguments()
{
$a = null;
$a = array('foo', array(2, &$a));
$a = ['foo', [2, &$a]];
$exception = $this->createException($a);
$flattened = FlattenException::create($exception);
@@ -310,7 +310,7 @@ class FlattenExceptionTest extends TestCase
public function testTooBigArray()
{
$a = array();
$a = [];
for ($i = 0; $i < 20; ++$i) {
for ($j = 0; $j < 50; ++$j) {
for ($k = 0; $k < 10; ++$k) {
@@ -325,7 +325,7 @@ class FlattenExceptionTest extends TestCase
$flattened = FlattenException::create($exception);
$trace = $flattened->getTrace();
$this->assertSame($trace[1]['args'][0], array('array', array('array', '*SKIPPED over 10000 entries*')));
$this->assertSame($trace[1]['args'][0], ['array', ['array', '*SKIPPED over 10000 entries*']]);
$serializeTrace = serialize($trace);

View File

@@ -62,10 +62,10 @@ class ExceptionHandlerTest extends TestCase
$this->assertContains('Sorry, the page you are looking for could not be found.', $response);
$expectedHeaders = array(
array('HTTP/1.0 404', true, null),
array('Content-Type: text/html; charset=iso8859-1', true, null),
);
$expectedHeaders = [
['HTTP/1.0 404', true, null],
['Content-Type: text/html; charset=iso8859-1', true, null],
];
$this->assertSame($expectedHeaders, testHeader());
}
@@ -75,14 +75,14 @@ class ExceptionHandlerTest extends TestCase
$handler = new ExceptionHandler(false, 'iso8859-1');
ob_start();
$handler->sendPhpResponse(new MethodNotAllowedHttpException(array('POST')));
$handler->sendPhpResponse(new MethodNotAllowedHttpException(['POST']));
$response = ob_get_clean();
$expectedHeaders = array(
array('HTTP/1.0 405', true, null),
array('Allow: POST', false, null),
array('Content-Type: text/html; charset=iso8859-1', true, null),
);
$expectedHeaders = [
['HTTP/1.0 405', true, null],
['Allow: POST', false, null],
['Content-Type: text/html; charset=iso8859-1', true, null],
];
$this->assertSame($expectedHeaders, testHeader());
}
@@ -101,7 +101,7 @@ class ExceptionHandlerTest extends TestCase
{
$exception = new \Exception('foo');
$handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(array('sendPhpResponse'))->getMock();
$handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(['sendPhpResponse'])->getMock();
$handler
->expects($this->exactly(2))
->method('sendPhpResponse');
@@ -119,7 +119,7 @@ class ExceptionHandlerTest extends TestCase
{
$exception = new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__);
$handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(array('sendPhpResponse'))->getMock();
$handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(['sendPhpResponse'])->getMock();
$handler
->expects($this->once())
->method('sendPhpResponse');

View File

@@ -72,85 +72,85 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
$autoloader = new ComposerClassLoader();
$autoloader->add('Symfony\Component\Debug\Exception\\', realpath(__DIR__.'/../../Exception'));
$debugClassLoader = new DebugClassLoader(array($autoloader, 'loadClass'));
$debugClassLoader = new DebugClassLoader([$autoloader, 'loadClass']);
return array(
array(
array(
return [
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'WhizBangFactory\' not found',
),
],
"Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?",
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\WhizBangFactory\' not found',
),
],
"Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'UndefinedFunctionException\' not found',
),
],
"Attempted to load class \"UndefinedFunctionException\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'PEARClass\' not found',
),
],
"Attempted to load class \"PEARClass\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony_Component_Debug_Tests_Fixtures_PEARClass\"?",
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
],
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
],
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
array($autoloader, 'loadClass'),
),
array(
array(
[$autoloader, 'loadClass'],
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
],
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
array($debugClassLoader, 'loadClass'),
),
array(
array(
[$debugClassLoader, 'loadClass'],
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
],
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
function ($className) { /* do nothing here */ },
),
);
],
];
}
public function testCannotRedeclareClass()
@@ -161,12 +161,12 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
require_once __DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP';
$error = array(
$error = [
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\RequiredTwice\' not found',
);
];
$handler = new ClassNotFoundFatalErrorHandler();
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));

View File

@@ -35,44 +35,44 @@ class UndefinedFunctionFatalErrorHandlerTest extends TestCase
public function provideUndefinedFunctionData()
{
return array(
array(
array(
return [
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined function test_namespaced_function()',
),
],
"Attempted to call function \"test_namespaced_function\" from the global namespace.\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined function Foo\\Bar\\Baz\\test_namespaced_function()',
),
],
"Attempted to call function \"test_namespaced_function\" from namespace \"Foo\\Bar\\Baz\".\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined function foo()',
),
],
'Attempted to call function "foo" from the global namespace.',
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined function Foo\\Bar\\Baz\\foo()',
),
],
'Attempted to call function "foo" from namespace "Foo\Bar\Baz".',
),
);
],
];
}
}

View File

@@ -34,43 +34,43 @@ class UndefinedMethodFatalErrorHandlerTest extends TestCase
public function provideUndefinedMethodData()
{
return array(
array(
array(
return [
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined method SplObjectStorage::what()',
),
],
'Attempted to call an undefined method named "what" of class "SplObjectStorage".',
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined method SplObjectStorage::walid()',
),
],
"Attempted to call an undefined method named \"walid\" of class \"SplObjectStorage\".\nDid you mean to call \"valid\"?",
),
array(
array(
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined method SplObjectStorage::offsetFet()',
),
],
"Attempted to call an undefined method named \"offsetFet\" of class \"SplObjectStorage\".\nDid you mean to call e.g. \"offsetGet\", \"offsetSet\" or \"offsetUnset\"?",
),
array(
array(
],
[
[
'type' => 1,
'message' => 'Call to undefined method class@anonymous::test()',
'file' => '/home/possum/work/symfony/test.php',
'line' => 11,
),
],
'Attempted to call an undefined method named "test" of class "class@anonymous".',
),
);
],
];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
eval('
namespace Symfony\Component\Debug\Tests\Fixtures;
class DefinitionInEvaluatedCode
{
}
');

View File

@@ -0,0 +1,22 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
class ErrorHandlerThatUsesThePreviousOne
{
private static $previous;
public static function register()
{
$handler = new static();
self::$previous = set_error_handler([$handler, 'handleError']);
return $handler;
}
public function handleError($type, $message, $file, $line, $context)
{
return \call_user_func(self::$previous, $type, $message, $file, $line, $context);
}
}

View File

@@ -1,10 +0,0 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
/**
* @final
*/
class FinalClass
{
}

View File

@@ -0,0 +1,84 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
/**
* @final since version 3.3.
*/
class FinalClass1
{
// simple comment
}
/**
* @final
*/
class FinalClass2
{
// no comment
}
/**
* @final comment with @@@ and ***
*
* @author John Doe
*/
class FinalClass3
{
// with comment and a tag after
}
/**
* @final
* @author John Doe
*/
class FinalClass4
{
// without comment and a tag after
}
/**
* @author John Doe
*
*
* @final multiline
* comment
*/
class FinalClass5
{
// with comment and a tag before
}
/**
* @author John Doe
*
* @final
*/
class FinalClass6
{
// without comment and a tag before
}
/**
* @author John Doe
*
* @final another
*
* multiline comment...
*
* @return string
*/
class FinalClass7
{
// with comment and a tag before and after
}
/**
* @author John Doe
* @final
* @return string
*/
class FinalClass8
{
// without comment and a tag before and after
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
use Symfony\Component\Debug\BufferingLogger;
class LoggerThatSetAnErrorHandler extends BufferingLogger
{
public function log($level, $message, array $context = [])
{
set_error_handler('is_string');
parent::log($level, $message, $context);
restore_error_handler();
}
}

View File

@@ -18,7 +18,7 @@ class ToStringThrower
} catch (\Exception $e) {
// Using user_error() here is on purpose so we do not forget
// that this alias also should work alongside with trigger_error().
return user_error($e, E_USER_ERROR);
return trigger_error($e, E_USER_ERROR);
}
}
}

View File

@@ -25,11 +25,11 @@ namespace Symfony\Component\Debug\Tests;
function testHeader()
{
static $headers = array();
static $headers = [];
if (!$h = \func_get_args()) {
$h = $headers;
$headers = array();
$headers = [];
return $h;
}

View File

@@ -14,7 +14,7 @@ require $vendor.'/vendor/autoload.php';
if (true) {
class TestLogger extends \Psr\Log\AbstractLogger
{
public function log($level, $message, array $context = array())
public function log($level, $message, array $context = [])
{
echo $message, "\n";
}

View File

@@ -17,9 +17,9 @@ ini_set('display_errors', 0);
$eHandler = set_error_handler('var_dump');
$xHandler = set_exception_handler('var_dump');
var_dump(array(
var_dump([
$eHandler[0] === $xHandler[0] ? 'Error and exception handlers do match' : 'Error and exception handlers are different',
));
]);
$eHandler[0]->setExceptionHandler('print_r');