From e9f653ae3f9ba422a357544a4bcbdedddd252453 Mon Sep 17 00:00:00 2001 From: Benjamin Pick Date: Fri, 4 Jul 2025 21:54:13 +0200 Subject: [PATCH 1/3] Fix php.net links --- Tests/ErrorRenderer/HtmlErrorRendererTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/ErrorRenderer/HtmlErrorRendererTest.php b/Tests/ErrorRenderer/HtmlErrorRendererTest.php index 2a33cee..3885307 100644 --- a/Tests/ErrorRenderer/HtmlErrorRendererTest.php +++ b/Tests/ErrorRenderer/HtmlErrorRendererTest.php @@ -100,7 +100,7 @@ public static function provideFileLinkFormats(): iterable public function testRendersStackWithoutBinaryStrings() { - // make sure method arguments are available in stack traces (see https://www.php.net/manual/en/ini.core.php) + // make sure method arguments are available in stack traces (see https://php.net/ini.core) ini_set('zend.exception_ignore_args', false); $binaryData = file_get_contents(__DIR__.'/../Fixtures/pixel.png'); From f011fa80dab8db15e480974af13ae5b8eec93d53 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 Jul 2025 09:12:18 +0200 Subject: [PATCH 2/3] CS fixes --- BufferingLogger.php | 2 +- DebugClassLoader.php | 38 +++++++++---------- ErrorEnhancer/ClassNotFoundErrorEnhancer.php | 4 +- .../UndefinedFunctionErrorEnhancer.php | 4 +- .../UndefinedMethodErrorEnhancer.php | 2 +- ErrorHandler.php | 6 +-- ErrorRenderer/CliErrorRenderer.php | 2 +- ErrorRenderer/HtmlErrorRenderer.php | 12 +++--- Tests/ErrorHandlerTest.php | 4 +- Tests/Exception/FlattenExceptionTest.php | 4 +- 10 files changed, 39 insertions(+), 39 deletions(-) diff --git a/BufferingLogger.php b/BufferingLogger.php index b33e079..3fc741e 100644 --- a/BufferingLogger.php +++ b/BufferingLogger.php @@ -65,7 +65,7 @@ public function __destruct() } } - error_log(sprintf('%s [%s] %s', date(\DateTimeInterface::RFC3339), $level, $message)); + error_log(\sprintf('%s [%s] %s', date(\DateTimeInterface::RFC3339), $level, $message)); } } } diff --git a/DebugClassLoader.php b/DebugClassLoader.php index 3f2a136..9773345 100644 --- a/DebugClassLoader.php +++ b/DebugClassLoader.php @@ -182,7 +182,7 @@ public function getClassLoader(): callable public static function enable(): void { // Ensures we don't hit https://bugs.php.net/42098 - class_exists(\Symfony\Component\ErrorHandler\ErrorHandler::class); + class_exists(ErrorHandler::class); class_exists(\Psr\Log\LogLevel::class); if (!\is_array($functions = spl_autoload_functions())) { @@ -332,7 +332,7 @@ private function checkClass(string $class, ?string $file = null): void $name = $refl->getName(); if ($name !== $class && 0 === strcasecmp($name, $class)) { - throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name)); + throw new \RuntimeException(\sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name)); } $deprecations = $this->checkAnnotations($refl, $name); @@ -348,14 +348,14 @@ private function checkClass(string $class, ?string $file = null): void if (!$exists) { if (str_contains($class, '/')) { - throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class)); + throw new \RuntimeException(\sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class)); } - throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); + throw new \RuntimeException(\sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); } if (self::$caseCheck && $message = $this->checkCase($refl, $file, $class)) { - throw new \RuntimeException(sprintf('Case mismatch between class and real file names: "%s" vs "%s" in "%s".', $message[0], $message[1], $message[2])); + throw new \RuntimeException(\sprintf('Case mismatch between class and real file names: "%s" vs "%s" in "%s".', $message[0], $message[1], $message[2])); } } @@ -416,7 +416,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } if (isset(self::$final[$parent])) { - $deprecations[] = sprintf('The "%s" class is considered final%s It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $className); + $deprecations[] = \sprintf('The "%s" class is considered final%s It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $className); } } @@ -429,10 +429,10 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array $type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait'); $verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses'); - $deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s', $className, $type, $verb, $use, self::$deprecated[$use]); + $deprecations[] = \sprintf('The "%s" %s %s "%s" that is deprecated%s', $className, $type, $verb, $use, self::$deprecated[$use]); } if (isset(self::$internal[$use]) && strncmp($vendor, str_replace('_', '\\', $use), $vendorLen)) { - $deprecations[] = sprintf('The "%s" %s is considered internal%s It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $className); + $deprecations[] = \sprintf('The "%s" %s is considered internal%s It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $className); } if (isset(self::$method[$use])) { if ($refl->isAbstract()) { @@ -458,7 +458,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } $realName = substr($name, 0, strpos($name, '(')); if (!$refl->hasMethod($realName) || !($methodRefl = $refl->getMethod($realName))->isPublic() || ($static && !$methodRefl->isStatic()) || (!$static && $methodRefl->isStatic())) { - $deprecations[] = sprintf('Class "%s" should implement method "%s::%s%s"%s', $className, ($static ? 'static ' : '').$interface, $name, $returnType ? ': '.$returnType : '', null === $description ? '.' : ': '.$description); + $deprecations[] = \sprintf('Class "%s" should implement method "%s::%s%s"%s', $className, ($static ? 'static ' : '').$interface, $name, $returnType ? ': '.$returnType : '', null === $description ? '.' : ': '.$description); } } } @@ -522,13 +522,13 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array if ($parent && isset(self::$finalMethods[$parent][$method->name])) { [$declaringClass, $message] = self::$finalMethods[$parent][$method->name]; - $deprecations[] = sprintf('The "%s::%s()" method is considered final%s It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className); + $deprecations[] = \sprintf('The "%s::%s()" method is considered final%s It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className); } if (isset(self::$internalMethods[$class][$method->name])) { [$declaringClass, $message] = self::$internalMethods[$class][$method->name]; if (strncmp($ns, $declaringClass, $len)) { - $deprecations[] = sprintf('The "%s::%s()" method is considered internal%s It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className); + $deprecations[] = \sprintf('The "%s::%s()" method is considered internal%s It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className); } } @@ -547,7 +547,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array foreach (self::$annotatedParameters[$class][$method->name] as $parameterName => $deprecation) { if (!isset($definedParameters[$parameterName]) && !isset($doc['param'][$parameterName])) { - $deprecations[] = sprintf($deprecation, $className); + $deprecations[] = \sprintf($deprecation, $className); } } } @@ -585,7 +585,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array if ('docblock' === $this->patchTypes['force']) { $this->patchMethod($method, $returnType, $declaringFile, $normalizedType); } elseif ('' !== $declaringClass && $this->patchTypes['deprecations']) { - $deprecations[] = sprintf('Method "%s::%s()" might add "%s" as a native return type declaration in the future. Do the same in %s "%s" now to avoid errors or add an explicit @return annotation to suppress this message.', $declaringClass, $method->name, $normalizedType, interface_exists($declaringClass) ? 'implementation' : 'child class', $className); + $deprecations[] = \sprintf('Method "%s::%s()" might add "%s" as a native return type declaration in the future. Do the same in %s "%s" now to avoid errors or add an explicit @return annotation to suppress this message.', $declaringClass, $method->name, $normalizedType, interface_exists($declaringClass) ? 'implementation' : 'child class', $className); } } } @@ -634,7 +634,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } foreach ($doc['param'] as $parameterName => $parameterType) { if (!isset($definedParameters[$parameterName])) { - self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($className) ? 'interface' : 'parent class', $className); + self::$annotatedParameters[$class][$method->name][$parameterName] = \sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($className) ? 'interface' : 'parent class', $className); } } } @@ -654,7 +654,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array foreach ($parentAndOwnInterfaces as $use) { if (isset(self::${$type}[$use][$r->name]) && !isset($doc['deprecated']) && ('finalConstants' === $type || substr($use, 0, strrpos($use, '\\')) !== substr($use, 0, strrpos($class, '\\')))) { $msg = 'finalConstants' === $type ? '%s" constant' : '$%s" property'; - $deprecations[] = sprintf('The "%s::'.$msg.' is considered final. You should not override it in "%s".', self::${$type}[$use][$r->name], $r->name, $class); + $deprecations[] = \sprintf('The "%s::'.$msg.' is considered final. You should not override it in "%s".', self::${$type}[$use][$r->name], $r->name, $class); } } @@ -895,8 +895,8 @@ private function setReturnType(string $types, string $class, string $method, str } } - $phpType = sprintf($nullable ? (1 < \count($phpTypes) ? '%s|null' : '?%s') : '%s', implode($glue, $phpTypes)); - $docType = sprintf($nullable ? '%s|null' : '%s', implode($glue, $docTypes)); + $phpType = \sprintf($nullable ? (1 < \count($phpTypes) ? '%s|null' : '?%s') : '%s', implode($glue, $phpTypes)); + $docType = \sprintf($nullable ? '%s|null' : '%s', implode($glue, $docTypes)); self::$returnTypes[$class][$method] = [$phpType, $docType, $class, $filename]; } @@ -1028,7 +1028,7 @@ private function patchMethod(\ReflectionMethod $method, string $returnType, stri ++$fileOffset; } - $returnType[$i] = null !== $format ? sprintf($format, $alias) : $alias; + $returnType[$i] = null !== $format ? \sprintf($format, $alias) : $alias; } if ('docblock' === $this->patchTypes['force'] || ('object' === $normalizedType && '7.1' === $this->patchTypes['php'])) { @@ -1137,7 +1137,7 @@ private function fixReturnStatements(\ReflectionMethod $method, string $returnTy $braces = 0; for (; $i < $end; ++$i) { if (!$inClosure) { - $inClosure = false !== strpos($code[$i], 'function ('); + $inClosure = str_contains($code[$i], 'function ('); } if ($inClosure) { diff --git a/ErrorEnhancer/ClassNotFoundErrorEnhancer.php b/ErrorEnhancer/ClassNotFoundErrorEnhancer.php index b4623cf..fc243a6 100644 --- a/ErrorEnhancer/ClassNotFoundErrorEnhancer.php +++ b/ErrorEnhancer/ClassNotFoundErrorEnhancer.php @@ -34,11 +34,11 @@ public function enhance(\Throwable $error): ?\Throwable if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) { $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1); $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex); - $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix); + $message = \sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix); $tail = ' for another namespace?'; } else { $className = $fullyQualifiedClassName; - $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className); + $message = \sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className); $tail = '?'; } diff --git a/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php b/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php index 0458c26..e1d54ab 100644 --- a/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php +++ b/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php @@ -47,10 +47,10 @@ public function enhance(\Throwable $error): ?\Throwable if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\')) { $functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1); $namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex); - $message = sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix); + $message = \sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix); } else { $functionName = $fullyQualifiedFunctionName; - $message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName); + $message = \sprintf('Attempted to call function "%s" from the global namespace.', $functionName); } $candidates = []; diff --git a/ErrorEnhancer/UndefinedMethodErrorEnhancer.php b/ErrorEnhancer/UndefinedMethodErrorEnhancer.php index 80eaec9..e331c17 100644 --- a/ErrorEnhancer/UndefinedMethodErrorEnhancer.php +++ b/ErrorEnhancer/UndefinedMethodErrorEnhancer.php @@ -34,7 +34,7 @@ public function enhance(\Throwable $error): ?\Throwable $className = $matches[1]; $methodName = $matches[2]; - $message = sprintf('Attempted to call an undefined method named "%s" of class "%s".', $methodName, $className); + $message = \sprintf('Attempted to call an undefined method named "%s" of class "%s".', $methodName, $className); if ('' === $methodName || !class_exists($className) || null === $methods = get_class_methods($className)) { // failed to get the class or its methods on which an unknown method was called (for example on an anonymous class) diff --git a/ErrorHandler.php b/ErrorHandler.php index 052baf2..142199e 100644 --- a/ErrorHandler.php +++ b/ErrorHandler.php @@ -193,7 +193,7 @@ public function __construct(?BufferingLogger $bootstrappingLogger = null, bool $ $traceReflector->setValue($e, $trace); $e->file = $file ?? $e->file; $e->line = $line ?? $e->line; - }, null, new class() extends \Exception { + }, null, new class extends \Exception { }); $this->debug = $debug; } @@ -435,7 +435,7 @@ public function handleError(int $type, string $message, string $file, int $line) return true; } } else { - if (PHP_VERSION_ID < 80303 && str_contains($message, '@anonymous')) { + if (\PHP_VERSION_ID < 80303 && str_contains($message, '@anonymous')) { $backtrace = debug_backtrace(false, 5); for ($i = 1; isset($backtrace[$i]); ++$i) { @@ -451,7 +451,7 @@ public function handleError(int $type, string $message, string $file, int $line) } } - if (false !== strpos($message, "@anonymous\0")) { + if (str_contains($message, "@anonymous\0")) { $message = $this->parseAnonymousClass($message); $logMessage = $this->levels[$type].': '.$message; } diff --git a/ErrorRenderer/CliErrorRenderer.php b/ErrorRenderer/CliErrorRenderer.php index 04b3edb..c414c83 100644 --- a/ErrorRenderer/CliErrorRenderer.php +++ b/ErrorRenderer/CliErrorRenderer.php @@ -26,7 +26,7 @@ class CliErrorRenderer implements ErrorRendererInterface public function render(\Throwable $exception): FlattenException { $cloner = new VarCloner(); - $dumper = new class() extends CliDumper { + $dumper = new class extends CliDumper { protected function supportsColors(): bool { $outputStream = $this->outputStream; diff --git a/ErrorRenderer/HtmlErrorRenderer.php b/ErrorRenderer/HtmlErrorRenderer.php index 2572a8a..12d7084 100644 --- a/ErrorRenderer/HtmlErrorRenderer.php +++ b/ErrorRenderer/HtmlErrorRenderer.php @@ -158,9 +158,9 @@ private function formatArgs(array $args): string $result = []; foreach ($args as $key => $item) { if ('object' === $item[0]) { - $formattedValue = sprintf('object(%s)', $this->abbrClass($item[1])); + $formattedValue = \sprintf('object(%s)', $this->abbrClass($item[1])); } elseif ('array' === $item[0]) { - $formattedValue = sprintf('array(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); + $formattedValue = \sprintf('array(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); } elseif ('null' === $item[0]) { $formattedValue = 'null'; } elseif ('boolean' === $item[0]) { @@ -173,7 +173,7 @@ private function formatArgs(array $args): string $formattedValue = str_replace("\n", '', $this->escape(var_export($item[1], true))); } - $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $this->escape($key), $formattedValue); + $result[] = \is_int($key) ? $formattedValue : \sprintf("'%s' => %s", $this->escape($key), $formattedValue); } return implode(', ', $result); @@ -194,7 +194,7 @@ private function abbrClass(string $class): string $parts = explode('\\', $class); $short = array_pop($parts); - return sprintf('%s', $class, $short); + return \sprintf('%s', $class, $short); } private function getFileRelative(string $file): ?string @@ -223,7 +223,7 @@ private function formatFile(string $file, int $line, ?string $text = null): stri $text = $file; if (null !== $rel = $this->getFileRelative($text)) { $rel = explode('/', $rel, 2); - $text = sprintf('%s%s', $this->projectDir, $rel[0], '/'.($rel[1] ?? '')); + $text = \sprintf('%s%s', $this->projectDir, $rel[0], '/'.($rel[1] ?? '')); } } @@ -237,7 +237,7 @@ private function formatFile(string $file, int $line, ?string $text = null): stri $link = $this->fileLinkFormat->format($file, $line); - return sprintf('%s', $this->escape($link), $text); + return \sprintf('%s', $this->escape($link), $text); } /** diff --git a/Tests/ErrorHandlerTest.php b/Tests/ErrorHandlerTest.php index 55a2a6b..c4cc5b7 100644 --- a/Tests/ErrorHandlerTest.php +++ b/Tests/ErrorHandlerTest.php @@ -333,7 +333,7 @@ public function testHandleError() public function testHandleErrorWithAnonymousClass() { - $anonymousObject = new class() extends \stdClass { + $anonymousObject = new class extends \stdClass { }; $handler = ErrorHandler::register(); @@ -422,7 +422,7 @@ public static function handleExceptionProvider(): array ['Uncaught Exception: foo', new \Exception('foo')], ['Uncaught Exception: foo', new class('foo') extends \RuntimeException { }], - ['Uncaught Exception: foo stdClass@anonymous bar', new \RuntimeException('foo '.(new class() extends \stdClass { + ['Uncaught Exception: foo stdClass@anonymous bar', new \RuntimeException('foo '.(new class extends \stdClass { })::class.' bar')], ['Uncaught Error: bar', new \Error('bar')], ['Uncaught ccc', new \ErrorException('ccc')], diff --git a/Tests/Exception/FlattenExceptionTest.php b/Tests/Exception/FlattenExceptionTest.php index a3ff2f6..c6efb3c 100644 --- a/Tests/Exception/FlattenExceptionTest.php +++ b/Tests/Exception/FlattenExceptionTest.php @@ -245,7 +245,7 @@ public static function stringAndIntDataProvider(): array public function testAnonymousClass() { - $flattened = FlattenException::createFromThrowable(new class() extends \RuntimeException { + $flattened = FlattenException::createFromThrowable(new class extends \RuntimeException { }); $this->assertSame('RuntimeException@anonymous', $flattened->getClass()); @@ -255,7 +255,7 @@ public function testAnonymousClass() $this->assertSame('Symfony\Component\HttpKernel\Exception\NotFoundHttpException@anonymous', $flattened->getClass()); - $flattened = FlattenException::createFromThrowable(new \Exception(sprintf('Class "%s" blah.', (new class() extends \RuntimeException { + $flattened = FlattenException::createFromThrowable(new \Exception(\sprintf('Class "%s" blah.', (new class extends \RuntimeException { })::class))); $this->assertSame('Class "RuntimeException@anonymous" blah.', $flattened->getMessage()); From 30fd0b3cf0e972e82636038ce4db0e4fe777112c Mon Sep 17 00:00:00 2001 From: NickSdot Date: Wed, 23 Jul 2025 01:48:30 +0700 Subject: [PATCH 3/3] [Form][PhpUnitBridge] Remove usage of noop `ReflectionProperty::setAccessible()` --- Tests/ErrorHandlerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/ErrorHandlerTest.php b/Tests/ErrorHandlerTest.php index c4cc5b7..48ddefa 100644 --- a/Tests/ErrorHandlerTest.php +++ b/Tests/ErrorHandlerTest.php @@ -34,7 +34,6 @@ class ErrorHandlerTest extends TestCase protected function tearDown(): void { $r = new \ReflectionProperty(ErrorHandler::class, 'exitCode'); - $r->setAccessible(true); $r->setValue(null, 0); }