Compare commits

..

14 Commits

Author SHA1 Message Date
Alexander Schwenn
ad4511a8fd [Debug] Fixed ClassNotFoundFatalErrorHandlerTest 2015-05-08 15:17:44 +02:00
Fabien Potencier
572006675e Merge branch '2.3' into 2.6
* 2.3:
  link to https://symfony.com where possible
  [FrameworkBundle] Added missing log in server:run command
  [HttpFoundation] Allow curly braces in trusted host patterns
  [profiler][security] check authenticated user by tokenClass instead of username.
  Use https://symfony.com/search for searching

Conflicts:
	src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php
	src/Symfony/Component/Form/README.md
	src/Symfony/Component/Intl/README.md
	src/Symfony/Component/Routing/composer.json
	src/Symfony/Component/Security/README.md
	src/Symfony/Component/Translation/README.md
	src/Symfony/Component/Validator/README.md
2015-05-02 17:18:45 +02:00
Christian Flothmann
95a5aa2b72 link to https://symfony.com where possible 2015-05-01 16:06:45 +02:00
Nicolas Grekas
289e4e76fd [Debug] PHP7 compatibility with BaseException 2015-04-26 11:08:32 +02:00
Nicolas Grekas
c1dc68518c [Debug] Fix deprecated use of DebugClassLoader 2015-04-24 12:55:50 +02:00
Nicolas Grekas
cd19fabc2a [Debug] Fix ClassNotFoundFatalErrorHandler candidates lookups 2015-04-23 10:57:12 +02:00
Nicolas Grekas
eb7564c66d Merge branch '2.3' into 2.6
* 2.3:
  [Routing][DependencyInjection] Support .yaml extension in YAML loaders
  [DX] improve file loader error for router/other resources in bundle
  [FrameworkBundle] Fix Routing\DelegatingLoader resiliency to fatal errors
  [HttpKernel] Cleanup ExceptionListener
  CS fixes
  [DependencyInjection] Show better error when the Yaml component is not installed
  [2.3] SCA for Components - reference mismatches
  [2.3] Static Code Analysis for Components
  [Translation][fixed test] refresh cache when resources are no longer fresh.
  [Validator] Added missing Simplified Chinese (zh_CN) translations
  [FrameworkBundle] Workaround php -S ignoring auto_prepend_file

Conflicts:
	src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php
	src/Symfony/Component/Config/Exception/FileLoaderLoadException.php
	src/Symfony/Component/Console/Descriptor/TextDescriptor.php
	src/Symfony/Component/Console/Helper/TableHelper.php
	src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
	src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
	src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
	src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php
	src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php
	src/Symfony/Component/PropertyAccess/PropertyAccessor.php
	src/Symfony/Component/Yaml/Tests/InlineTest.php
2015-04-18 17:02:51 +02:00
Dariusz Ruminski
9cd1287f00 CS fixes 2015-04-16 09:01:03 +02:00
Nicolas Grekas
8f9d6bcc9b [Debug] Scream as LogLevel::DEBUG (but for fatal errors / uncaught exceptions) 2015-04-15 16:47:26 +02:00
Nicolas Grekas
c39932e3e4 [Debug] Skip unsilencing test on PHP7 2015-04-06 10:42:23 +02:00
Nicolas Grekas
2b8d1207a7 [Debug] Tweak docblocks 2015-04-03 09:48:36 +02:00
Grégoire Pineau
21e1aa2ed7 [Debug] Rework a bit the PHP doc 2015-04-03 09:46:34 +02:00
Grégoire Pineau
76df7e93ea [Debug] Renamed "context" key to "scope_vars" to avoid any ambiguity 2015-04-02 21:18:30 +02:00
Grégoire Pineau
4bd15a76de [Debug] Made code in ErrorHandler easier to read 2015-04-02 15:40:50 +02:00
10 changed files with 260 additions and 149 deletions

View File

@@ -14,6 +14,7 @@ namespace Symfony\Component\Debug;
use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
use Symfony\Component\Debug\Exception\ContextErrorException;
use Symfony\Component\Debug\Exception\FatalBaseException;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\Exception\OutOfMemoryException;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
@@ -101,7 +102,7 @@ class ErrorHandler
private static $stackedErrorLevels = array();
/**
* Same init value as thrownErrors
* Same init value as thrownErrors.
*
* @deprecated since 2.6, to be removed in 3.0.
*/
@@ -240,7 +241,7 @@ class ErrorHandler
}
/**
* Sets the error levels that are to be thrown.
* Sets the PHP error levels that throw an exception when a PHP error occurs.
*
* @param int $levels A bit field of E_* constants for thrown errors
* @param bool $replace Replace or amend the previous value
@@ -263,7 +264,7 @@ class ErrorHandler
}
/**
* Sets the error levels that are logged or thrown with their local scope.
* Sets the PHP error levels for which local variables are preserved.
*
* @param int $levels A bit field of E_* constants for scoped errors
* @param bool $replace Replace or amend the previous value
@@ -282,7 +283,7 @@ class ErrorHandler
}
/**
* Sets the error levels that are logged with their stack trace.
* Sets the PHP error levels for which the stack trace is preserved.
*
* @param int $levels A bit field of E_* constants for traced errors
* @param bool $replace Replace or amend the previous value
@@ -356,69 +357,71 @@ class ErrorHandler
$throw = $this->thrownErrors & $type & $level;
$type &= $level | $this->screamedErrors;
if ($type && ($log || $throw)) {
if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) {
$e = $context; // Whatever the signature of the method,
unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
$context = $e;
}
if (!$type || (!$log && !$throw)) {
return $type && $log;
}
if ($throw) {
if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
// Checking for class existence is a work around for https://bugs.php.net/42098
$throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
} else {
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
}
if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) {
$e = $context; // Whatever the signature of the method,
unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
$context = $e;
}
if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) {
// Exceptions thrown from error handlers are sometimes not caught by the exception
// handler and shutdown handlers are bypassed before 5.4.8/5.3.18.
// We temporarily re-enable display_errors to prevent any blank page related to this bug.
$throw->errorHandlerCanary = new ErrorHandlerCanary();
}
throw $throw;
}
// For duplicated errors, log the trace only once
$e = md5("{$type}/{$line}/{$file}\x00{$message}", true);
$trace = true;
if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) {
$trace = false;
if ($throw) {
if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
// Checking for class existence is a work around for https://bugs.php.net/42098
$throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
} else {
$this->loggedTraces[$e] = 1;
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
}
$e = compact('type', 'file', 'line', 'level');
if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) {
// Exceptions thrown from error handlers are sometimes not caught by the exception
// handler and shutdown handlers are bypassed before 5.4.8/5.3.18.
// We temporarily re-enable display_errors to prevent any blank page related to this bug.
if ($type & $level) {
if ($this->scopedErrors & $type) {
$e['context'] = $context;
if ($trace) {
$e['stack'] = debug_backtrace(true); // Provide object
}
} elseif ($trace) {
$e['stack'] = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false);
}
$throw->errorHandlerCanary = new ErrorHandlerCanary();
}
if ($this->isRecursive) {
$log = 0;
} elseif (self::$stackedErrorLevels) {
self::$stackedErrors[] = array($this->loggers[$type], $message, $e);
} else {
try {
$this->isRecursive = true;
$this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e);
$this->isRecursive = false;
} catch (\Exception $e) {
$this->isRecursive = false;
throw $throw;
}
throw $e;
// For duplicated errors, log the trace only once
$e = md5("{$type}/{$line}/{$file}\x00{$message}", true);
$trace = true;
if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) {
$trace = false;
} else {
$this->loggedTraces[$e] = 1;
}
$e = compact('type', 'file', 'line', 'level');
if ($type & $level) {
if ($this->scopedErrors & $type) {
$e['scope_vars'] = $context;
if ($trace) {
$e['stack'] = debug_backtrace(true); // Provide object
}
} elseif ($trace) {
$e['stack'] = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false);
}
}
if ($this->isRecursive) {
$log = 0;
} elseif (self::$stackedErrorLevels) {
self::$stackedErrors[] = array($this->loggers[$type], $message, $e);
} else {
try {
$this->isRecursive = true;
$this->loggers[$type][0]->log(($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e);
$this->isRecursive = false;
} catch (\Exception $e) {
$this->isRecursive = false;
throw $e;
}
}
@@ -428,23 +431,34 @@ class ErrorHandler
/**
* Handles an exception by logging then forwarding it to an other handler.
*
* @param \Exception $exception An exception to handle
* @param array $error An array as returned by error_get_last()
* @param \Exception|\BaseException $exception An exception to handle
* @param array $error An array as returned by error_get_last()
*
* @internal
*/
public function handleException(\Exception $exception, array $error = null)
public function handleException($exception, array $error = null)
{
$level = error_reporting();
if ($this->loggedErrors & E_ERROR & ($level | $this->screamedErrors)) {
if (!$exception instanceof \Exception) {
$exception = new FatalBaseException($exception);
}
$type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
if ($this->loggedErrors & $type) {
$e = array(
'type' => E_ERROR,
'type' => $type,
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'level' => $level,
'level' => error_reporting(),
'stack' => $exception->getTrace(),
);
if ($exception instanceof FatalErrorException) {
if ($exception instanceof FatalBaseException) {
$error = array(
'type' => $type,
'message' => $message = $exception->getMessage(),
'file' => $e['file'],
'line' => $e['line'],
);
} elseif ($exception instanceof FatalErrorException) {
$message = 'Fatal '.$exception->getMessage();
} elseif ($exception instanceof \ErrorException) {
$message = 'Uncaught '.$exception->getMessage();
@@ -474,6 +488,9 @@ class ErrorHandler
} catch (\Exception $handlerException) {
$this->exceptionHandler = null;
$this->handleException($handlerException);
} catch (\BaseException $handlerException) {
$this->exceptionHandler = null;
$this->handleException($handlerException);
}
}
@@ -487,40 +504,44 @@ class ErrorHandler
public static function handleFatalError(array $error = null)
{
self::$reservedMemory = '';
$handler = set_error_handler('var_dump', 0);
$handler = is_array($handler) ? $handler[0] : null;
restore_error_handler();
if ($handler instanceof self) {
if (null === $error) {
$error = error_get_last();
}
try {
while (self::$stackedErrorLevels) {
static::unstackErrors();
}
} catch (\Exception $exception) {
// Handled below
}
if (!$handler instanceof self) {
return;
}
if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) {
// Let's not throw anymore but keep logging
$handler->throwAt(0, true);
if (null === $error) {
$error = error_get_last();
}
if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
$exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false);
} else {
$exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true);
}
} elseif (!isset($exception)) {
return;
try {
while (self::$stackedErrorLevels) {
static::unstackErrors();
}
} catch (\Exception $exception) {
// Handled below
}
try {
$handler->handleException($exception, $error);
} catch (FatalErrorException $e) {
// Ignore this re-throw
if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) {
// Let's not throw anymore but keep logging
$handler->throwAt(0, true);
if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
$exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false);
} else {
$exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true);
}
} elseif (!isset($exception)) {
return;
}
try {
$handler->handleException($exception, $error);
} catch (FatalErrorException $e) {
// Ignore this re-throw
}
}
@@ -541,7 +562,7 @@ class ErrorHandler
}
/**
* Unstacks stacked errors and forwards to the logger
* Unstacks stacked errors and forwards to the logger.
*/
public static function unstackErrors()
{
@@ -660,7 +681,7 @@ class ErrorHandler
}
/**
* Private class used to work around https://bugs.php.net/54275
* Private class used to work around https://bugs.php.net/54275.
*
* @author Nicolas Grekas <p@tchwork.com>
*

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Debug\Exception;
/**
* Base Fatal Error Exception.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class FatalBaseException extends FatalErrorException
{
public function __construct(\BaseException $e)
{
if ($e instanceof \ParseException) {
$message = 'Parse error: '.$e->getMessage();
$severity = E_PARSE;
} elseif ($e instanceof \TypeException) {
$message = 'Type error: '.$e->getMessage();
$severity = E_RECOVERABLE_ERROR;
} else {
$message = 'Fatal error: '.$e->getMessage();
$severity = E_ERROR;
}
\ErrorException::__construct(
$message,
$e->getCode(),
$severity,
$e->getFile(),
$e->getLine()
);
$this->setTrace($e->getTrace());
}
}

View File

@@ -371,7 +371,7 @@ EOF;
{
$parts = explode('\\', $class);
return sprintf("<abbr title=\"%s\">%s</abbr>", $class, array_pop($parts));
return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts));
}
private function formatPath($path, $line)

View File

@@ -77,7 +77,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
/**
* Tries to guess the full namespace for a given class name.
*
* By default, it looks for PSR-0 classes registered via a Symfony or a Composer
* By default, it looks for PSR-0 and PSR-4 classes registered via a Symfony or a Composer
* autoloader (that should cover all common cases).
*
* @param string $class A class name (without its namespace)
@@ -101,7 +101,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
if ($function[0] instanceof DebugClassLoader) {
$function = $function[0]->getClassLoader();
// Since 2.5, returning an object from DebugClassLoader::getClassLoader() is @deprecated
// @deprecated since version 2.5. Returning an object from DebugClassLoader::getClassLoader() is deprecated.
if (is_object($function)) {
$function = array($function);
}
@@ -118,6 +118,13 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
}
}
}
if ($function[0] instanceof ComposerClassLoader) {
foreach ($function[0]->getPrefixesPsr4() as $prefix => $paths) {
foreach ($paths as $path) {
$classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
}
}
}
}
return array_unique($classes);
@@ -132,13 +139,13 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
*/
private function findClassInPath($path, $class, $prefix)
{
if (!$path = realpath($path)) {
if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
return array();
}
$classes = array();
$filename = $class.'.php';
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
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)) {
$classes[] = $class;
}
@@ -160,13 +167,21 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
// namespaced class
$namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
// namespaced class (with target dir)
$namespacedClassTargetDir = $prefix.str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
$prefix.$namespacedClass,
// namespaced class (with target dir and separator)
$prefix.'\\'.$namespacedClass,
// PEAR class
str_replace('\\', '_', $namespacedClass),
// PEAR class (with target dir)
str_replace('\\', '_', $namespacedClassTargetDir),
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);});
}
// We cannot use the autoloader here as most of them use require; but if the class
// is not found, the new autoloader call will require the file again leading to a
// "cannot redeclare class" error.

View File

@@ -61,6 +61,10 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase
public function testUnsilencing()
{
if (PHP_VERSION_ID >= 70000) {
$this->markTestSkipped('PHP7 throws exceptions, unsilencing is not required anymore.');
}
ob_start();
$this->iniSet('log_errors', 0);
@@ -100,9 +104,14 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase
// if an exception is thrown, the test passed
restore_error_handler();
restore_exception_handler();
$this->assertEquals(E_STRICT, $exception->getSeverity());
$this->assertStringStartsWith(__FILE__, $exception->getFile());
$this->assertRegexp('/^Runtime Notice: Declaration/', $exception->getMessage());
if (PHP_VERSION_ID < 70000) {
$this->assertRegexp('/^Runtime Notice: Declaration/', $exception->getMessage());
$this->assertEquals(E_STRICT, $exception->getSeverity());
} else {
$this->assertRegexp('/^Warning: Declaration/', $exception->getMessage());
$this->assertEquals(E_WARNING, $exception->getSeverity());
}
} catch (\Exception $exception) {
restore_error_handler();
restore_exception_handler();

View File

@@ -336,7 +336,7 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
$logArgCheck = function ($level, $message, $context) use ($that) {
$that->assertEquals('Fatal Parse Error: foo', $message);
$that->assertArrayHasKey('type', $context);
$that->assertEquals($context['type'], E_ERROR);
$that->assertEquals($context['type'], E_PARSE);
};
$logger
@@ -345,7 +345,7 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
->will($this->returnCallback($logArgCheck))
;
$handler->setDefaultLogger($logger, E_ERROR);
$handler->setDefaultLogger($logger, E_PARSE);
$handler->handleFatalError($error);

View File

@@ -15,18 +15,52 @@ use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
use Symfony\Component\Debug\DebugClassLoader;
use Composer\Autoload\ClassLoader as ComposerClassLoader;
class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
{
public static function setUpBeforeClass()
{
foreach (spl_autoload_functions() as $function) {
if (!is_array($function)) {
continue;
}
// get class loaders wrapped by DebugClassLoader
if ($function[0] instanceof DebugClassLoader) {
$function = $function[0]->getClassLoader();
}
if ($function[0] instanceof ComposerClassLoader) {
$function[0]->add('Symfony_Component_Debug_Tests_Fixtures', dirname(dirname(dirname(dirname(dirname(__DIR__))))));
break;
}
}
}
/**
* @dataProvider provideClassNotFoundData
*/
public function testHandleClassNotFound($error, $translatedMessage)
public function testHandleClassNotFound($error, $translatedMessage, $autoloader = null)
{
if ($autoloader) {
// Unregister all autoloaders to ensure the custom provided
// autoloader is the only one to be used during the test run.
$autoloaders = spl_autoload_functions();
array_map('spl_autoload_unregister', $autoloaders);
spl_autoload_register($autoloader);
}
$handler = new ClassNotFoundFatalErrorHandler();
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));
if ($autoloader) {
spl_autoload_unregister($autoloader);
array_map('spl_autoload_register', $autoloaders);
}
$this->assertInstanceof('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
$this->assertSame($translatedMessage, $exception->getMessage());
$this->assertSame($error['type'], $exception->getSeverity());
@@ -35,35 +69,37 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
}
/**
* @dataProvider provideLegacyClassNotFoundData
* @group legacy
*/
public function testLegacyHandleClassNotFound($error, $translatedMessage, $autoloader)
public function testLegacyHandleClassNotFound()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
// Unregister all autoloaders to ensure the custom provided
// autoloader is the only one to be used during the test run.
$autoloaders = spl_autoload_functions();
array_map('spl_autoload_unregister', $autoloaders);
spl_autoload_register($autoloader);
$prefixes = array('Symfony\Component\Debug\Exception\\' => realpath(__DIR__.'/../../Exception'));
$symfonyUniversalClassLoader = new SymfonyUniversalClassLoader();
$symfonyUniversalClassLoader->registerPrefixes($prefixes);
$handler = new ClassNotFoundFatalErrorHandler();
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));
spl_autoload_unregister($autoloader);
array_map('spl_autoload_register', $autoloaders);
$this->assertInstanceof('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
$this->assertSame($translatedMessage, $exception->getMessage());
$this->assertSame($error['type'], $exception->getSeverity());
$this->assertSame($error['file'], $exception->getFile());
$this->assertSame($error['line'], $exception->getLine());
$this->testHandleClassNotFound(
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($symfonyUniversalClassLoader, 'loadClass')
);
}
public function provideClassNotFoundData()
{
$prefixes = array('Symfony\Component\Debug\Exception\\' => realpath(__DIR__.'/../../Exception'));
$symfonyAutoloader = new SymfonyClassLoader();
$symfonyAutoloader->addPrefixes($prefixes);
$debugClassLoader = new DebugClassLoader(array($symfonyAutoloader, 'loadClass'));
return array(
array(
array(
@@ -110,20 +146,6 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
),
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
),
);
}
public function provideLegacyClassNotFoundData()
{
$prefixes = array('Symfony\Component\Debug\Exception\\' => realpath(__DIR__.'/../../Exception'));
$symfonyAutoloader = new SymfonyClassLoader();
$symfonyAutoloader->addPrefixes($prefixes);
$symfonyUniversalClassLoader = new SymfonyUniversalClassLoader();
$symfonyUniversalClassLoader->registerPrefixes($prefixes);
return array(
array(
array(
'type' => 1,
@@ -142,7 +164,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
'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($symfonyUniversalClassLoader, 'loadClass'),
array($debugClassLoader, 'loadClass'),
),
array(
array(
@@ -159,11 +181,11 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
public function testCannotRedeclareClass()
{
if (!file_exists(__DIR__.'/../FIXTURES/REQUIREDTWICE.PHP')) {
if (!file_exists(__DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP')) {
$this->markTestSkipped('Can only be run on case insensitive filesystems');
}
require_once __DIR__.'/../FIXTURES/REQUIREDTWICE.PHP';
require_once __DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP';
$error = array(
'type' => 1,

View File

@@ -1,7 +0,0 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
class RequiredTwice
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures2;
class RequiredTwice
{
}

View File

@@ -3,7 +3,7 @@
"type": "library",
"description": "Symfony Debug Component",
"keywords": [],
"homepage": "http://symfony.com",
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [
{
@@ -12,7 +12,7 @@
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
"homepage": "https://symfony.com/contributors"
}
],
"require": {