From dd6bb2c367cc84d678a5e72d80bdfcc258dbc10f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 21 Jul 2021 17:18:04 +0200 Subject: [PATCH] [ErrorHandler][Debug] Do not use the php80 polyfill --- .../Component/Debug/DebugClassLoader.php | 14 ++++---- src/Symfony/Component/Debug/ErrorHandler.php | 8 ++--- .../Debug/Exception/FatalThrowableError.php | 2 +- .../Debug/Exception/FlattenException.php | 6 ++-- .../Component/Debug/ExceptionHandler.php | 2 +- .../ClassNotFoundFatalErrorHandler.php | 2 +- .../UndefinedFunctionFatalErrorHandler.php | 2 +- .../UndefinedMethodFatalErrorHandler.php | 2 +- src/Symfony/Component/Debug/composer.json | 3 +- .../ErrorHandler/BufferingLogger.php | 2 +- .../ErrorHandler/DebugClassLoader.php | 36 +++++++++---------- .../ClassNotFoundErrorEnhancer.php | 2 +- .../UndefinedFunctionErrorEnhancer.php | 2 +- .../UndefinedMethodErrorEnhancer.php | 2 +- .../Component/ErrorHandler/ErrorHandler.php | 8 ++--- .../ErrorRenderer/HtmlErrorRenderer.php | 4 +-- .../Exception/FlattenException.php | 6 ++-- .../Component/ErrorHandler/composer.json | 1 - 18 files changed, 51 insertions(+), 53 deletions(-) diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index c4241714cc511..6081c525a6923 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -61,7 +61,7 @@ public function __construct(callable $classLoader) if (false === $test || false === $i) { // filesystem is case sensitive self::$caseCheck = 0; - } elseif (str_ends_with($test, $file)) { + } elseif (substr($test, -\strlen($file)) === $file) { // filesystem is case insensitive and realpath() normalizes the case of characters self::$caseCheck = 1; } elseif (false !== stripos(\PHP_OS, 'darwin')) { @@ -210,7 +210,7 @@ private function checkClass(string $class, string $file = null) } if (!$exists) { - if (str_contains($class, '/')) { + if (false !== strpos($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)); } @@ -237,17 +237,17 @@ public function checkAnnotations(\ReflectionClass $refl, $class) // Detect annotations on the class if (false !== $doc = $refl->getDocComment()) { foreach (['final', 'deprecated', 'internal'] as $annotation) { - if (str_contains($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : ''; } } - if ($refl->isInterface() && str_contains($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+(?:[\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, \PREG_SET_ORDER)) { + if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+(?:[\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, \PREG_SET_ORDER)) { foreach ($notice as $method) { $static = '' !== $method[1]; $name = $method[2]; $description = $method[3] ?? null; - if (!str_contains($name, '(')) { + if (false === strpos($name, '(')) { $name .= '()'; } if (null !== $description) { @@ -369,14 +369,14 @@ public function checkAnnotations(\ReflectionClass $refl, $class) $finalOrInternal = false; foreach (['final', 'internal'] as $annotation) { - if (str_contains($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { $message = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : ''; self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message]; $finalOrInternal = true; } } - if ($finalOrInternal || $method->isConstructor() || !str_contains($doc, '@param') || StatelessInvocation::class === $class) { + if ($finalOrInternal || $method->isConstructor() || false === strpos($doc, '@param') || StatelessInvocation::class === $class) { continue; } if (!preg_match_all('#\n\s+\* @param +((?(?!callable *\().*?|callable *\(.*\).*?))(?<= )\$([a-zA-Z0-9_\x7f-\xff]++)#', $doc, $matches, \PREG_SET_ORDER)) { diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 4a1c21fa97fbd..fd22f201adef6 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -385,7 +385,7 @@ private function reRegister(int $prev) */ public function handleError($type, $message, $file, $line) { - if (\PHP_VERSION_ID >= 70300 && \E_WARNING === $type && '"' === $message[0] && str_contains($message, '" targeting switch is equivalent to "break')) { + if (\PHP_VERSION_ID >= 70300 && \E_WARNING === $type && '"' === $message[0] && false !== strpos($message, '" targeting switch is equivalent to "break')) { $type = \E_DEPRECATED; } @@ -403,7 +403,7 @@ public function handleError($type, $message, $file, $line) } $scope = $this->scopedErrors & $type; - if (str_contains($message, "@anonymous\0")) { + if (false !== strpos($message, "@anonymous\0")) { $logMessage = $this->levels[$type].': '.(new FlattenException())->setMessage($message)->getMessage(); } else { $logMessage = $this->levels[$type].': '.$message; @@ -530,7 +530,7 @@ public function handleException($exception, array $error = null) $handlerException = null; if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) { - if (str_contains($message = $exception->getMessage(), "@anonymous\0")) { + if (false !== strpos($message = $exception->getMessage(), "@anonymous\0")) { $message = (new FlattenException())->setMessage($message)->getMessage(); } if ($exception instanceof FatalErrorException) { @@ -638,7 +638,7 @@ public static function handleFatalError(array $error = null) $handler->throwAt(0, true); $trace = $error['backtrace'] ?? null; - if (str_starts_with($error['message'], 'Allowed memory') || str_starts_with($error['message'], 'Out of memory')) { + 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, $trace); } else { $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace); diff --git a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php index 65634f51ee0f9..6c9ecb85301c1 100644 --- a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php +++ b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php @@ -26,7 +26,7 @@ class FatalThrowableError extends FatalErrorException public function __construct(\Throwable $e) { - $this->originalClassName = get_debug_type($e); + $this->originalClassName = \get_class($e); if ($e instanceof \ParseError) { $severity = \E_PARSE; diff --git a/src/Symfony/Component/Debug/Exception/FlattenException.php b/src/Symfony/Component/Debug/Exception/FlattenException.php index 8d6e2391a0a58..dbf0ed8ff62e3 100644 --- a/src/Symfony/Component/Debug/Exception/FlattenException.php +++ b/src/Symfony/Component/Debug/Exception/FlattenException.php @@ -67,7 +67,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod $e->setStatusCode($statusCode); $e->setHeaders($headers); $e->setTraceFromThrowable($exception); - $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : get_debug_type($exception)); + $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception)); $e->setFile($exception->getFile()); $e->setLine($exception->getLine()); @@ -134,7 +134,7 @@ public function getClass() */ public function setClass($class) { - $this->class = str_contains($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; + $this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; return $this; } @@ -179,7 +179,7 @@ public function getMessage() */ public function setMessage($message) { - if (str_contains($message, "@anonymous\0")) { + if (false !== strpos($message, "@anonymous\0")) { $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $message); diff --git a/src/Symfony/Component/Debug/ExceptionHandler.php b/src/Symfony/Component/Debug/ExceptionHandler.php index e8c9092d4a538..21be2827cd864 100644 --- a/src/Symfony/Component/Debug/ExceptionHandler.php +++ b/src/Symfony/Component/Debug/ExceptionHandler.php @@ -401,7 +401,7 @@ private function formatPath(string $path, int $line): string $fmt = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, \PREG_SPLIT_DELIM_CAPTURE); for ($i = 1; isset($fmt[$i]); ++$i) { - if (str_starts_with($path, $k = $fmt[$i++])) { + if (0 === strpos($path, $k = $fmt[$i++])) { $path = substr_replace($path, $fmt[$i], 0, \strlen($k)); break; } diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php index 189ac2f8e9f53..64d7551343e7a 100644 --- a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php +++ b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php @@ -149,7 +149,7 @@ private function convertFileToClass(string $path, string $file, string $prefix): ]; if ($prefix) { - $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return str_starts_with($candidate, $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 diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php index b74bfca47ab07..95096a9cd1a94 100644 --- a/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php +++ b/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php @@ -43,7 +43,7 @@ public function handleError(array $error, FatalErrorException $exception) $prefix = 'Call to undefined function '; $prefixLen = \strlen($prefix); - if (!str_starts_with($error['message'], $prefix)) { + if (0 !== strpos($error['message'], $prefix)) { return null; } diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php index ef72121e86138..4f622deeca53d 100644 --- a/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php +++ b/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php @@ -48,7 +48,7 @@ public function handleError(array $error, FatalErrorException $exception) $candidates = []; foreach ($methods as $definedMethodName) { $lev = levenshtein($methodName, $definedMethodName); - if ($lev <= \strlen($methodName) / 3 || str_contains($definedMethodName, $methodName)) { + if ($lev <= \strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) { $candidates[] = $definedMethodName; } } diff --git a/src/Symfony/Component/Debug/composer.json b/src/Symfony/Component/Debug/composer.json index cb2f4e895482d..01e8f78323fdf 100644 --- a/src/Symfony/Component/Debug/composer.json +++ b/src/Symfony/Component/Debug/composer.json @@ -17,8 +17,7 @@ ], "require": { "php": ">=7.1.3", - "psr/log": "^1|^2|^3", - "symfony/polyfill-php80": "^1.16" + "psr/log": "^1|^2|^3" }, "conflict": { "symfony/http-kernel": "<3.4" diff --git a/src/Symfony/Component/ErrorHandler/BufferingLogger.php b/src/Symfony/Component/ErrorHandler/BufferingLogger.php index 4c27685a845fb..72be64d1278a4 100644 --- a/src/Symfony/Component/ErrorHandler/BufferingLogger.php +++ b/src/Symfony/Component/ErrorHandler/BufferingLogger.php @@ -48,7 +48,7 @@ public function __wakeup() public function __destruct() { foreach ($this->logs as [$level, $message, $context]) { - if (str_contains($message, '{')) { + if (false !== strpos($message, '{')) { foreach ($context as $key => $val) { if (null === $val || is_scalar($val) || (\is_object($val) && \is_callable([$val, '__toString']))) { $message = str_replace("{{$key}}", $val, $message); diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php index cab601c23c707..342e6e83b06f0 100644 --- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php +++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php @@ -205,7 +205,7 @@ public function __construct(callable $classLoader) if (false === $test || false === $i) { // filesystem is case sensitive self::$caseCheck = 0; - } elseif (str_ends_with($test, $file)) { + } elseif (substr($test, -\strlen($file)) === $file) { // filesystem is case insensitive and realpath() normalizes the case of characters self::$caseCheck = 1; } elseif (false !== stripos(\PHP_OS, 'darwin')) { @@ -396,7 +396,7 @@ private function checkClass(string $class, string $file = null): void } if (!$exists) { - if (str_contains($class, '/')) { + if (false !== strpos($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)); } @@ -419,7 +419,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } $deprecations = []; - $className = str_contains($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; + $className = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; // Don't trigger deprecations for classes in the same vendor if ($class !== $className) { @@ -435,17 +435,17 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array // Detect annotations on the class if (false !== $doc = $refl->getDocComment()) { foreach (['final', 'deprecated', 'internal'] as $annotation) { - if (str_contains($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : ''; } } - if ($refl->isInterface() && str_contains($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+([\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, \PREG_SET_ORDER)) { + if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+([\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, \PREG_SET_ORDER)) { foreach ($notice as $method) { $static = '' !== $method[1] && !empty($method[2]); $name = $method[3]; $description = $method[4] ?? null; - if (!str_contains($name, '(')) { + if (false === strpos($name, '(')) { $name .= '()'; } if (null !== $description) { @@ -496,7 +496,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } } elseif (!$refl->isInterface()) { if (!strncmp($vendor, str_replace('_', '\\', $use), $vendorLen) - && str_starts_with($className, 'Symfony\\') + && 0 === strpos($className, 'Symfony\\') && (!class_exists(InstalledVersions::class) || 'symfony/symfony' !== InstalledVersions::getRootPackage()['name']) ) { @@ -597,12 +597,12 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array $forcePatchTypes = $this->patchTypes['force']; - if ($canAddReturnType = null !== $forcePatchTypes && !str_contains($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { + if ($canAddReturnType = null !== $forcePatchTypes && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { if ('void' !== (self::MAGIC_METHODS[$method->name] ?? 'void')) { $this->patchTypes['force'] = $forcePatchTypes ?: 'docblock'; } - $canAddReturnType = str_contains($refl->getFileName(), \DIRECTORY_SEPARATOR.'Tests'.\DIRECTORY_SEPARATOR) + $canAddReturnType = false !== strpos($refl->getFileName(), \DIRECTORY_SEPARATOR.'Tests'.\DIRECTORY_SEPARATOR) || $refl->isFinal() || $method->isFinal() || $method->isPrivate() @@ -623,8 +623,8 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array $this->patchMethod($method, $returnType, $declaringFile, $normalizedType); } - if (!str_contains($doc, '* @deprecated') && strncmp($ns, $declaringClass, $len)) { - if ($canAddReturnType && 'docblock' === $this->patchTypes['force'] && !str_contains($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { + if (false === strpos($doc, '* @deprecated') && strncmp($ns, $declaringClass, $len)) { + if ($canAddReturnType && 'docblock' === $this->patchTypes['force'] && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { $this->patchMethod($method, $returnType, $declaringFile, $normalizedType); } elseif ('' !== $declaringClass && $this->patchTypes['deprecations']) { $deprecations[] = sprintf('Method "%s::%s()" will return "%s" as of its next major version. Doing the same in %s "%s" will be required when upgrading.', $declaringClass, $method->name, $normalizedType, interface_exists($declaringClass) ? 'implementation' : 'child class', $className); @@ -640,7 +640,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array $matches = []; - if (!$method->hasReturnType() && ((str_contains($doc, '@return') && preg_match('/\n\s+\* @return +([^\s<(]+)/', $doc, $matches)) || 'void' !== (self::MAGIC_METHODS[$method->name] ?? 'void'))) { + if (!$method->hasReturnType() && ((false !== strpos($doc, '@return') && preg_match('/\n\s+\* @return +([^\s<(]+)/', $doc, $matches)) || 'void' !== (self::MAGIC_METHODS[$method->name] ?? 'void'))) { $matches = $matches ?: [1 => self::MAGIC_METHODS[$method->name]]; $this->setReturnType($matches[1], $method, $parent); @@ -662,14 +662,14 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array $finalOrInternal = false; foreach (['final', 'internal'] as $annotation) { - if (str_contains($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { $message = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : ''; self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message]; $finalOrInternal = true; } } - if ($finalOrInternal || $method->isConstructor() || !str_contains($doc, '@param') || StatelessInvocation::class === $class) { + if ($finalOrInternal || $method->isConstructor() || false === strpos($doc, '@param') || StatelessInvocation::class === $class) { continue; } if (!preg_match_all('#\n\s+\* @param +((?(?!callable *\().*?|callable *\(.*\).*?))(?<= )\$([a-zA-Z0-9_\x7f-\xff]++)#', $doc, $matches, \PREG_SET_ORDER)) { @@ -850,7 +850,7 @@ private function setReturnType(string $types, \ReflectionMethod $method, ?string $iterable = $object = true; foreach ($typesMap as $n => $t) { if ('null' !== $n) { - $iterable = $iterable && (\in_array($n, ['array', 'iterable']) || str_contains($n, 'Iterator')); + $iterable = $iterable && (\in_array($n, ['array', 'iterable']) || false !== strpos($n, 'Iterator')); $object = $object && (\in_array($n, ['callable', 'object', '$this', 'static']) || !isset(self::SPECIAL_RETURN_TYPES[$n])); } } @@ -1034,15 +1034,15 @@ private static function getUseStatements(string $file): array break; } - if (str_starts_with($file[$i], 'namespace ')) { + if (0 === strpos($file[$i], 'namespace ')) { $namespace = substr($file[$i], \strlen('namespace '), -2).'\\'; $useOffset = $i + 2; } - if (str_starts_with($file[$i], 'use ')) { + if (0 === strpos($file[$i], 'use ')) { $useOffset = $i; - for (; str_starts_with($file[$i], 'use '); ++$i) { + for (; 0 === strpos($file[$i], 'use '); ++$i) { $u = explode(' as ', substr($file[$i], 4, -2), 2); if (1 === \count($u)) { diff --git a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php index 25a622820b7d9..96a58be800e4b 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php @@ -145,7 +145,7 @@ private function convertFileToClass(string $path, string $file, string $prefix): ]; if ($prefix) { - $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return str_starts_with($candidate, $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 diff --git a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php index 2e3838a84d382..f4c49c2856c22 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php @@ -42,7 +42,7 @@ public function enhance(\Throwable $error): ?\Throwable $prefix = 'Call to undefined function '; $prefixLen = \strlen($prefix); - if (!str_starts_with($message, $prefix)) { + if (0 !== strpos($message, $prefix)) { return null; } diff --git a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedMethodErrorEnhancer.php b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedMethodErrorEnhancer.php index d5eb6d6b1e4a6..c4355f92ce089 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedMethodErrorEnhancer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedMethodErrorEnhancer.php @@ -47,7 +47,7 @@ public function enhance(\Throwable $error): ?\Throwable $candidates = []; foreach ($methods as $definedMethodName) { $lev = levenshtein($methodName, $definedMethodName); - if ($lev <= \strlen($methodName) / 3 || str_contains($definedMethodName, $methodName)) { + if ($lev <= \strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) { $candidates[] = $definedMethodName; } } diff --git a/src/Symfony/Component/ErrorHandler/ErrorHandler.php b/src/Symfony/Component/ErrorHandler/ErrorHandler.php index 3851eea72a8be..e6e21d601700e 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorHandler.php +++ b/src/Symfony/Component/ErrorHandler/ErrorHandler.php @@ -400,7 +400,7 @@ private function reRegister(int $prev): void */ public function handleError(int $type, string $message, string $file, int $line): bool { - if (\PHP_VERSION_ID >= 70300 && \E_WARNING === $type && '"' === $message[0] && str_contains($message, '" targeting switch is equivalent to "break')) { + if (\PHP_VERSION_ID >= 70300 && \E_WARNING === $type && '"' === $message[0] && false !== strpos($message, '" targeting switch is equivalent to "break')) { $type = \E_DEPRECATED; } @@ -451,7 +451,7 @@ public function handleError(int $type, string $message, string $file, int $line) return true; } } else { - if (str_contains($message, '@anonymous')) { + if (false !== strpos($message, '@anonymous')) { $backtrace = debug_backtrace(false, 5); for ($i = 1; isset($backtrace[$i]); ++$i) { @@ -560,7 +560,7 @@ public function handleException(\Throwable $exception) } if ($this->loggedErrors & $type) { - if (str_contains($message = $exception->getMessage(), "@anonymous\0")) { + if (false !== strpos($message = $exception->getMessage(), "@anonymous\0")) { $message = $this->parseAnonymousClass($message); } @@ -674,7 +674,7 @@ public static function handleFatalError(array $error = null): void $handler->throwAt(0, true); $trace = $error['backtrace'] ?? null; - if (str_starts_with($error['message'], 'Allowed memory') || str_starts_with($error['message'], 'Out of memory')) { + if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) { $fatalError = new OutOfMemoryError($handler->levels[$error['type']].': '.$error['message'], 0, $error, 2, false, $trace); } else { $fatalError = new FatalError($handler->levels[$error['type']].': '.$error['message'], 0, $error, 2, true, $trace); diff --git a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php index 95df271cc7112..69e1b9ce74555 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php @@ -199,7 +199,7 @@ private function getFileRelative(string $file): ?string { $file = str_replace('\\', '/', $file); - if (null !== $this->projectDir && str_starts_with($file, $this->projectDir)) { + if (null !== $this->projectDir && 0 === strpos($file, $this->projectDir)) { return ltrim(substr($file, \strlen($this->projectDir)), '/'); } @@ -316,7 +316,7 @@ private function formatFileFromText(string $text) private function formatLogMessage(string $message, array $context) { - if ($context && str_contains($message, '{')) { + if ($context && false !== strpos($message, '{')) { $replacements = []; foreach ($context as $key => $val) { if (is_scalar($val)) { diff --git a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php index 9b0949d718319..dc4733853738f 100644 --- a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php +++ b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php @@ -100,7 +100,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod $e->setStatusCode($statusCode); $e->setHeaders($headers); $e->setTraceFromThrowable($exception); - $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : get_debug_type($exception)); + $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception)); $e->setFile($exception->getFile()); $e->setLine($exception->getLine()); @@ -171,7 +171,7 @@ public function getClass(): string */ public function setClass($class): self { - $this->class = str_contains($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; + $this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; return $this; } @@ -234,7 +234,7 @@ public function getMessage(): string */ public function setMessage($message): self { - if (str_contains($message, "@anonymous\0")) { + if (false !== strpos($message, "@anonymous\0")) { $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $message); diff --git a/src/Symfony/Component/ErrorHandler/composer.json b/src/Symfony/Component/ErrorHandler/composer.json index 57c7bcaf1c06d..ef829f6d05605 100644 --- a/src/Symfony/Component/ErrorHandler/composer.json +++ b/src/Symfony/Component/ErrorHandler/composer.json @@ -19,7 +19,6 @@ "php": ">=7.1.3", "psr/log": "^1|^2|^3", "symfony/debug": "^4.4.5", - "symfony/polyfill-php80": "^1.16", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": {