diff --git a/composer.json b/composer.json index cfbdd532a8..2018b3015d 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.11", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/polyfill-php81": "^1.22", "symfony/polyfill-uuid": "^1.15" }, diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index 34aba14e9f..868042bc31 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -221,7 +221,7 @@ abstract class AbstractDoctrineExtension extends Extension ]); } $mappingDriverDef->setPublic(false); - if (false !== strpos($mappingDriverDef->getClass(), 'yml') || false !== strpos($mappingDriverDef->getClass(), 'xml')) { + if (str_contains($mappingDriverDef->getClass(), 'yml') || str_contains($mappingDriverDef->getClass(), 'xml')) { $mappingDriverDef->setArguments([array_flip($driverPaths)]); $mappingDriverDef->addMethodCall('setGlobalBasename', ['mapping']); } diff --git a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php index f031eeb172..1f7f6afe4c 100644 --- a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php +++ b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php @@ -50,7 +50,7 @@ class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeE if ($metadata instanceof ClassMetadataInfo && class_exists(\Doctrine\ORM\Mapping\Embedded::class) && $metadata->embeddedClasses) { $properties = array_filter($properties, function ($property) { - return false === strpos($property, '.'); + return !str_contains($property, '.'); }); $properties = array_merge($properties, array_keys($metadata->embeddedClasses)); diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index 1763631d61..683dcec5ee 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -144,7 +144,7 @@ class EntityUserProvider implements UserProviderInterface, PasswordUpgraderInter if (null === $this->class) { $class = $this->classOrAlias; - if (false !== strpos($class, ':')) { + if (str_contains($class, ':')) { $class = $this->getClassMetadata()->getName(); } diff --git a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php index ca9eb4fab1..f0f9a95652 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php +++ b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php @@ -104,7 +104,7 @@ final class DoctrineLoader implements LoaderInterface } if (null === $lengthConstraint) { - if (isset($mapping['originalClass']) && false === strpos($mapping['declaredField'], '.')) { + if (isset($mapping['originalClass']) && !str_contains($mapping['declaredField'], '.')) { $metadata->addPropertyConstraint($mapping['declaredField'], new Valid()); $loaded = true; } elseif (property_exists($className, $mapping['fieldName'])) { diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 8e1ea65fbc..b07a4ae76c 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -22,7 +22,7 @@ "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2" }, "require-dev": { diff --git a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php index 977be786e5..0e5fddc222 100644 --- a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php +++ b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php @@ -96,7 +96,7 @@ EOF 'multiline' => OutputInterface::VERBOSITY_DEBUG <= $output->getVerbosity(), ])); - if (false === strpos($host = $input->getOption('host'), '://')) { + if (!str_contains($host = $input->getOption('host'), '://')) { $host = 'tcp://'.$host; } diff --git a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php index d232d68cd9..4b87c264e4 100644 --- a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php +++ b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php @@ -163,7 +163,7 @@ class ConsoleFormatter implements FormatterInterface { $message = $record['message']; - if (false === strpos($message, '{')) { + if (!str_contains($message, '{')) { return $record; } diff --git a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php index 056b4ab9a9..53491e9df5 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php @@ -61,7 +61,7 @@ trait ServerLogHandlerTrait { parent::__construct($level, $bubble); - if (false === strpos($host, '://')) { + if (!str_contains($host, '://')) { $host = 'tcp://'.$host; } diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index ee48ea0330..b7215fc40f 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -20,7 +20,8 @@ "monolog/monolog": "^1.25.1|^2", "symfony/service-contracts": "^1.1|^2", "symfony/http-kernel": "^4.4|^5.0", - "symfony/deprecation-contracts": "^2.1" + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "symfony/console": "^4.4|^5.0", diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php index 141147a64c..d665070f02 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php @@ -28,12 +28,12 @@ class LazyLoadingValueHolderGenerator extends BaseGenerator parent::generate($originalClass, $classGenerator, $proxyOptions); foreach ($classGenerator->getMethods() as $method) { - if (0 === strpos($originalClass->getFilename(), __FILE__)) { + if (str_starts_with($originalClass->getFilename(), __FILE__)) { $method->setBody(str_replace(var_export($originalClass->name, true), '__CLASS__', $method->getBody())); } } - if (0 === strpos($originalClass->getFilename(), __FILE__)) { + if (str_starts_with($originalClass->getFilename(), __FILE__)) { $interfaces = $classGenerator->getImplementedInterfaces(); array_pop($interfaces); $classGenerator->setImplementedInterfaces(array_merge($interfaces, $originalClass->getInterfaceNames())); diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json index 145ac6880f..91d93ba7cf 100644 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ b/src/Symfony/Bridge/ProxyManager/composer.json @@ -19,7 +19,8 @@ "php": ">=7.2.5", "composer/package-versions-deprecated": "^1.8", "friendsofphp/proxy-manager-lts": "^1.0.2", - "symfony/dependency-injection": "^5.0" + "symfony/dependency-injection": "^5.0", + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "symfony/config": "^4.4|^5.0" diff --git a/src/Symfony/Bridge/Twig/Command/DebugCommand.php b/src/Symfony/Bridge/Twig/Command/DebugCommand.php index 1b1bf7a7c3..570bb3285e 100644 --- a/src/Symfony/Bridge/Twig/Command/DebugCommand.php +++ b/src/Symfony/Bridge/Twig/Command/DebugCommand.php @@ -211,7 +211,7 @@ EOF foreach ($types as $index => $type) { $items = []; foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) { - if (!$filter || false !== strpos($name, $filter)) { + if (!$filter || str_contains($name, $filter)) { $items[$name] = $name.$this->getPrettyMetadata($type, $entity, $decorated); } } @@ -245,7 +245,7 @@ EOF $data = []; foreach ($types as $type) { foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) { - if (!$filter || false !== strpos($name, $filter)) { + if (!$filter || str_contains($name, $filter)) { $data[$type][$name] = $this->getMetadata($type, $entity); } } @@ -395,7 +395,7 @@ EOF $folders = glob($this->twigDefaultPath.'/bundles/*', \GLOB_ONLYDIR); $relativePath = ltrim(substr($this->twigDefaultPath.'/bundles/', \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); $bundleNames = array_reduce($folders, function ($carry, $absolutePath) use ($relativePath) { - if (0 === strpos($absolutePath, $this->projectDir)) { + if (str_starts_with($absolutePath, $this->projectDir)) { $name = basename($absolutePath); $path = ltrim($relativePath.$name, \DIRECTORY_SEPARATOR); $carry[$name] = $path; @@ -525,7 +525,7 @@ EOF $alternatives = []; foreach ($collection as $item) { $lev = levenshtein($name, $item); - if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) { + if ($lev <= \strlen($name) / 3 || str_contains($item, $name)) { $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; } } @@ -539,7 +539,7 @@ EOF private function getRelativePath(string $path): string { - if (null !== $this->projectDir && 0 === strpos($path, $this->projectDir)) { + if (null !== $this->projectDir && str_starts_with($path, $this->projectDir)) { return ltrim(substr($path, \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); } diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php index 7acf75fb9c..a769b872b1 100644 --- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php @@ -65,7 +65,7 @@ final class CodeExtension extends AbstractExtension public function abbrMethod(string $method): string { - if (false !== strpos($method, '::')) { + if (str_contains($method, '::')) { [$class, $method] = explode('::', $method, 2); $result = sprintf('%s::%s()', $this->abbrClass($class), $method); } elseif ('Closure' === $method) { @@ -190,7 +190,7 @@ final class CodeExtension extends AbstractExtension { $file = str_replace('\\', '/', $file); - if (null !== $this->projectDir && 0 === strpos($file, $this->projectDir)) { + if (null !== $this->projectDir && str_starts_with($file, $this->projectDir)) { return ltrim(substr($file, \strlen($this->projectDir)), '/'); } @@ -209,7 +209,7 @@ final class CodeExtension extends AbstractExtension */ public function formatLogMessage(string $message, array $context): string { - if ($context && false !== strpos($message, '{')) { + if ($context && str_contains($message, '{')) { $replacements = []; foreach ($context as $key => $val) { if (is_scalar($val)) { diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 8012df7ae6..bc90ee6738 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/translation-contracts": "^1.1|^2", "twig/twig": "^2.13|^3.0.4" }, diff --git a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php index b607a4314b..bce977e9b1 100644 --- a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php +++ b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php @@ -59,7 +59,7 @@ class DebugExtension extends Extension $container->getDefinition('var_dumper.command.server_dump') ->setClass(ServerDumpPlaceholderCommand::class) ; - } elseif (0 === strpos($config['dump_destination'], 'tcp://')) { + } elseif (str_starts_with($config['dump_destination'], 'tcp://')) { $container->getDefinition('debug.dump_listener') ->replaceArgument(2, new Reference('var_dumper.server_connection')) ; diff --git a/src/Symfony/Bundle/DebugBundle/composer.json b/src/Symfony/Bundle/DebugBundle/composer.json index b69ec5c768..7c59e89ab3 100644 --- a/src/Symfony/Bundle/DebugBundle/composer.json +++ b/src/Symfony/Bundle/DebugBundle/composer.json @@ -19,6 +19,7 @@ "php": ">=7.2.5", "ext-xml": "*", "symfony/http-kernel": "^4.4|^5.0", + "symfony/polyfill-php80": "^1.16", "symfony/twig-bridge": "^4.4|^5.0", "symfony/var-dumper": "^4.4|^5.0" }, diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AbstractConfigCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AbstractConfigCommand.php index bda4956df7..1085c5bef8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AbstractConfigCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AbstractConfigCommand.php @@ -113,7 +113,7 @@ abstract class AbstractConfigCommand extends ContainerDebugCommand } } - if ('Bundle' !== substr($name, -6)) { + if (!str_ends_with($name, 'Bundle')) { $message = sprintf('No extensions with configuration available for "%s".', $name); } else { $message = sprintf('No extension with alias "%s" is enabled.', $name); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index 3bb5480571..ac6b994bfa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -83,7 +83,7 @@ EOF $realBuildDir = $kernel->getContainer()->hasParameter('kernel.build_dir') ? $kernel->getContainer()->getParameter('kernel.build_dir') : $realCacheDir; // the old cache dir name must not be longer than the real one to avoid exceeding // the maximum length of a directory or file path within it (esp. Windows MAX_PATH) - $oldCacheDir = substr($realCacheDir, 0, -1).('~' === substr($realCacheDir, -1) ? '+' : '~'); + $oldCacheDir = substr($realCacheDir, 0, -1).(str_ends_with($realCacheDir, '~') ? '+' : '~'); $fs->remove($oldCacheDir); if (!is_writable($realCacheDir)) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php index e5532df079..69d847fce1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php @@ -237,7 +237,7 @@ EOF $serviceIds = $builder->getServiceIds(); $foundServiceIds = $foundServiceIdsIgnoringBackslashes = []; foreach ($serviceIds as $serviceId) { - if (!$showHidden && 0 === strpos($serviceId, '.')) { + if (!$showHidden && str_starts_with($serviceId, '.')) { continue; } if (false !== stripos(str_replace('\\', '', $serviceId), $name)) { @@ -262,7 +262,7 @@ EOF } // if the id has a \, assume it is a class - if (false !== strpos($serviceId, '\\')) { + if (str_contains($serviceId, '\\')) { return true; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php index 18930c1655..04b580b2da 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php @@ -113,7 +113,7 @@ final class ContainerLintCommand extends Command $skippedIds = []; foreach ($container->getServiceIds() as $serviceId) { - if (0 === strpos($serviceId, '.errored.')) { + if (str_starts_with($serviceId, '.errored.')) { $skippedIds[$serviceId] = true; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php index 79ac2dd8f8..b5023749a3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php @@ -80,7 +80,7 @@ EOF if ($search = $input->getArgument('search')) { $serviceIds = array_filter($serviceIds, function ($serviceId) use ($search) { - return false !== stripos(str_replace('\\', '', $serviceId), $search) && 0 !== strpos($serviceId, '.'); + return false !== stripos(str_replace('\\', '', $serviceId), $search) && !str_starts_with($serviceId, '.'); }); if (empty($serviceIds)) { @@ -104,7 +104,7 @@ EOF foreach ($serviceIds as $serviceId) { $text = []; $resolvedServiceId = $serviceId; - if (0 !== strpos($serviceId, $previousId)) { + if (!str_starts_with($serviceId, $previousId)) { $text[] = ''; if ('' !== $description = Descriptor::getClassDescription($serviceId, $resolvedServiceId)) { if (isset($hasAlias[$serviceId])) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php index 0b5bb061d6..a52177acc0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php @@ -37,7 +37,7 @@ class XliffLintCommand extends BaseLintCommand }; $isReadableProvider = function ($fileOrDirectory, $default) { - return 0 === strpos($fileOrDirectory, '@') || $default($fileOrDirectory); + return str_starts_with($fileOrDirectory, '@') || $default($fileOrDirectory); }; parent::__construct(null, $directoryIteratorProvider, $isReadableProvider); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php index 1163ff1c28..86787361aa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php @@ -36,7 +36,7 @@ class YamlLintCommand extends BaseLintCommand }; $isReadableProvider = function ($fileOrDirectory, $default) { - return 0 === strpos($fileOrDirectory, '@') || $default($fileOrDirectory); + return str_starts_with($fileOrDirectory, '@') || $default($fileOrDirectory); }; parent::__construct(null, $directoryIteratorProvider, $isReadableProvider); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php index 65b94fb21a..e04e32c221 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php @@ -312,7 +312,7 @@ class JsonDescriptor extends Descriptor $data['name'] = $callable[1]; $data['class'] = \get_class($callable[0]); } else { - if (0 !== strpos($callable[1], 'parent::')) { + if (!str_starts_with($callable[1], 'parent::')) { $data['name'] = $callable[1]; $data['class'] = $callable[0]; $data['static'] = true; @@ -330,7 +330,7 @@ class JsonDescriptor extends Descriptor if (\is_string($callable)) { $data['type'] = 'function'; - if (false === strpos($callable, '::')) { + if (!str_contains($callable, '::')) { $data['name'] = $callable; } else { $callableParts = explode('::', $callable); @@ -347,7 +347,7 @@ class JsonDescriptor extends Descriptor $data['type'] = 'closure'; $r = new \ReflectionFunction($callable); - if (false !== strpos($r->name, '{closure}')) { + if (str_contains($r->name, '{closure}')) { return $data; } $data['name'] = $r->name; diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php index 4c1fe44087..048aeb7f22 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php @@ -328,7 +328,7 @@ class MarkdownDescriptor extends Descriptor $string .= "\n".sprintf('- Name: `%s`', $callable[1]); $string .= "\n".sprintf('- Class: `%s`', \get_class($callable[0])); } else { - if (0 !== strpos($callable[1], 'parent::')) { + if (!str_starts_with($callable[1], 'parent::')) { $string .= "\n".sprintf('- Name: `%s`', $callable[1]); $string .= "\n".sprintf('- Class: `%s`', $callable[0]); $string .= "\n- Static: yes"; @@ -346,7 +346,7 @@ class MarkdownDescriptor extends Descriptor if (\is_string($callable)) { $string .= "\n- Type: `function`"; - if (false === strpos($callable, '::')) { + if (!str_contains($callable, '::')) { $string .= "\n".sprintf('- Name: `%s`', $callable); } else { $callableParts = explode('::', $callable); @@ -363,7 +363,7 @@ class MarkdownDescriptor extends Descriptor $string .= "\n- Type: `closure`"; $r = new \ReflectionFunction($callable); - if (false !== strpos($r->name, '{closure}')) { + if (str_contains($r->name, '{closure}')) { return $this->write($string."\n"); } $string .= "\n".sprintf('- Name: `%s`', $r->name); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index 6b9db5c698..b157892c0f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -548,7 +548,7 @@ class TextDescriptor extends Descriptor $r = new \ReflectionMethod($controller, '__invoke'); } elseif (!\is_string($controller)) { return $anchorText; - } elseif (false !== strpos($controller, '::')) { + } elseif (str_contains($controller, '::')) { $r = new \ReflectionMethod($controller); } else { $r = new \ReflectionFunction($controller); @@ -601,7 +601,7 @@ class TextDescriptor extends Descriptor if ($callable instanceof \Closure) { $r = new \ReflectionFunction($callable); - if (false !== strpos($r->name, '{closure}')) { + if (str_contains($r->name, '{closure}')) { return 'Closure()'; } if ($class = $r->getClosureScopeClass()) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php index a3688b19a0..a435c20c6d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php @@ -502,7 +502,7 @@ class XmlDescriptor extends Descriptor $callableXML->setAttribute('name', $callable[1]); $callableXML->setAttribute('class', \get_class($callable[0])); } else { - if (0 !== strpos($callable[1], 'parent::')) { + if (!str_starts_with($callable[1], 'parent::')) { $callableXML->setAttribute('name', $callable[1]); $callableXML->setAttribute('class', $callable[0]); $callableXML->setAttribute('static', 'true'); @@ -520,7 +520,7 @@ class XmlDescriptor extends Descriptor if (\is_string($callable)) { $callableXML->setAttribute('type', 'function'); - if (false === strpos($callable, '::')) { + if (!str_contains($callable, '::')) { $callableXML->setAttribute('name', $callable); } else { $callableParts = explode('::', $callable); @@ -537,7 +537,7 @@ class XmlDescriptor extends Descriptor $callableXML->setAttribute('type', 'closure'); $r = new \ReflectionFunction($callable); - if (false !== strpos($r->name, '{closure}')) { + if (str_contains($r->name, '{closure}')) { return $dom; } $callableXML->setAttribute('name', $r->name); diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php index 7ab276128f..6a0fed64f6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php @@ -129,7 +129,7 @@ class RedirectController } if ($qs = $request->server->get('QUERY_STRING') ?: $request->getQueryString()) { - if (false === strpos($path, '?')) { + if (!str_contains($path, '?')) { $qs = '?'.$qs; } else { $qs = '&'.$qs; diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php index 37f545468d..2ce3ba6f8d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php @@ -107,7 +107,7 @@ class UnusedTagsPass implements CompilerPassInterface continue; } - if (false !== strpos($definedTag, $tag) || levenshtein($tag, $definedTag) <= \strlen($tag) / 3) { + if (str_contains($definedTag, $tag) || levenshtein($tag, $definedTag) <= \strlen($tag) / 3) { $candidates[] = $definedTag; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index c3382839f9..b61ce6744b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1253,7 +1253,7 @@ class FrameworkExtension extends Extension 'scanned_directories' => $scannedDirectories = array_merge($dirs, $nonExistingDirs), 'cache_vary' => [ 'scanned_directories' => array_map(static function (string $dir) use ($projectDir): string { - return 0 === strpos($dir, $projectDir.'/') ? substr($dir, 1 + \strlen($projectDir)) : $dir; + return str_starts_with($dir, $projectDir.'/') ? substr($dir, 1 + \strlen($projectDir)) : $dir; }, $scannedDirectories), ], ] diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php index 5bdf54565d..438ee578ef 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php @@ -82,7 +82,7 @@ class DelegatingLoader extends BaseDelegatingLoader continue; } - if (false !== strpos($controller, '::')) { + if (str_contains($controller, '::')) { continue; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Secrets/DotenvVault.php b/src/Symfony/Bundle/FrameworkBundle/Secrets/DotenvVault.php index 933091d19c..7c6f6987e2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Secrets/DotenvVault.php +++ b/src/Symfony/Bundle/FrameworkBundle/Secrets/DotenvVault.php @@ -54,7 +54,7 @@ class DotenvVault extends AbstractVault { $this->lastMessage = null; $this->validateName($name); - $v = \is_string($_SERVER[$name] ?? null) && 0 !== strpos($name, 'HTTP_') ? $_SERVER[$name] : ($_ENV[$name] ?? null); + $v = \is_string($_SERVER[$name] ?? null) && !str_starts_with($name, 'HTTP_') ? $_SERVER[$name] : ($_ENV[$name] ?? null); if (null === $v) { $this->lastMessage = sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath($this->dotenvFile)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php index 2a93a6f9f3..0bb2d0e17f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php @@ -35,12 +35,12 @@ class CachePoolsTest extends AbstractWebTestCase try { $this->doTestCachePools(['root_config' => 'redis_config.yml', 'environment' => 'redis_cache'], RedisAdapter::class); } catch (\PHPUnit\Framework\Error\Warning $e) { - if (0 !== strpos($e->getMessage(), 'unable to connect to')) { + if (!str_starts_with($e->getMessage(), 'unable to connect to')) { throw $e; } $this->markTestSkipped($e->getMessage()); } catch (InvalidArgumentException $e) { - if (0 !== strpos($e->getMessage(), 'Redis connection ')) { + if (!str_starts_with($e->getMessage(), 'Redis connection ')) { throw $e; } $this->markTestSkipped($e->getMessage()); @@ -58,7 +58,7 @@ class CachePoolsTest extends AbstractWebTestCase try { $this->doTestCachePools(['root_config' => 'redis_custom_config.yml', 'environment' => 'custom_redis_cache'], RedisAdapter::class); } catch (\PHPUnit\Framework\Error\Warning $e) { - if (0 !== strpos($e->getMessage(), 'unable to connect to')) { + if (!str_starts_with($e->getMessage(), 'unable to connect to')) { throw $e; } $this->markTestSkipped($e->getMessage()); diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 6a97c9082e..93d66e7515 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -27,7 +27,7 @@ "symfony/http-foundation": "^5.2.1", "symfony/http-kernel": "^5.2.1", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/filesystem": "^4.4|^5.0", "symfony/finder": "^4.4|^5.0", "symfony/routing": "^5.2" diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index 3d3000d8cd..ed385922bd 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -279,7 +279,7 @@ class MainConfiguration implements ConfigurationInterface continue; } - if (false !== strpos($firewall[$k]['check_path'], '/') && !preg_match('#'.$firewall['pattern'].'#', $firewall[$k]['check_path'])) { + if (str_contains($firewall[$k]['check_path'], '/') && !preg_match('#'.$firewall['pattern'].'#', $firewall[$k]['check_path'])) { throw new \LogicException(sprintf('The check_path "%s" for login method "%s" is not matched by the firewall pattern "%s".', $firewall[$k]['check_path'], $k, $firewall['pattern'])); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index 47d3033a25..0c65d5a5f6 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -75,7 +75,7 @@ abstract class CompleteConfigurationTest extends TestCase { $container = $this->getContainer('container1'); - $providers = array_values(array_filter($container->getServiceIds(), function ($key) { return 0 === strpos($key, 'security.user.provider.concrete'); })); + $providers = array_values(array_filter($container->getServiceIds(), function ($key) { return str_starts_with($key, 'security.user.provider.concrete'); })); $expectedProviders = [ 'security.user.provider.concrete.default', diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 3e9bc6591d..33482f8eb6 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -23,7 +23,7 @@ "symfony/deprecation-contracts": "^2.1", "symfony/event-dispatcher": "^5.1", "symfony/http-kernel": "^5.0", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/security-core": "^5.2", "symfony/security-csrf": "^4.4|^5.0", "symfony/security-guard": "^5.2", diff --git a/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php b/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php index f6e6b054fa..19a60737c1 100644 --- a/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php +++ b/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php @@ -44,7 +44,7 @@ EOF protected function findFiles(string $filename): iterable { - if (0 === strpos($filename, '@')) { + if (str_starts_with($filename, '@')) { $dir = $this->getApplication()->getKernel()->locateResource($filename); return Finder::create()->files()->in($dir)->name('*.twig'); diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php index a17d3facb6..45413dc932 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php @@ -43,7 +43,7 @@ class TwigEnvironmentPass implements CompilerPassInterface $methodCall = ['addExtension', [$extension]]; $extensionClass = $container->getDefinition((string) $extension)->getClass(); - if (\is_string($extensionClass) && 0 === strpos($extensionClass, 'Symfony\Bridge\Twig\Extension')) { + if (\is_string($extensionClass) && str_starts_with($extensionClass, 'Symfony\Bridge\Twig\Extension')) { $twigBridgeExtensionsMethodCalls[] = $methodCall; } else { $othersExtensionsMethodCalls[] = $methodCall; diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php index e9268e41b2..c7826cd5ff 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php @@ -86,9 +86,9 @@ class Configuration implements ConfigurationInterface ->prototype('array') ->normalizeKeys(false) ->beforeNormalization() - ->ifTrue(function ($v) { return \is_string($v) && 0 === strpos($v, '@'); }) + ->ifTrue(function ($v) { return \is_string($v) && str_starts_with($v, '@'); }) ->then(function ($v) { - if (0 === strpos($v, '@@')) { + if (str_starts_with($v, '@@')) { return substr($v, 1); } diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php index 5ccc9a1a04..4b7d90c854 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php @@ -172,7 +172,7 @@ class TwigExtension extends Extension private function normalizeBundleName(string $name): string { - if ('Bundle' === substr($name, -6)) { + if (str_ends_with($name, 'Bundle')) { $name = substr($name, 0, -6); } diff --git a/src/Symfony/Bundle/TwigBundle/TemplateIterator.php b/src/Symfony/Bundle/TwigBundle/TemplateIterator.php index 42f33804bf..5871600d54 100644 --- a/src/Symfony/Bundle/TwigBundle/TemplateIterator.php +++ b/src/Symfony/Bundle/TwigBundle/TemplateIterator.php @@ -49,7 +49,7 @@ class TemplateIterator implements \IteratorAggregate foreach ($this->kernel->getBundles() as $bundle) { $name = $bundle->getName(); - if ('Bundle' === substr($name, -6)) { + if (str_ends_with($name, 'Bundle')) { $name = substr($name, 0, -6); } diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php index 12eaa4ba4c..1cc9c0ebf3 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php @@ -181,7 +181,7 @@ class TwigExtensionTest extends TestCase $def = $container->getDefinition('twig.loader.native_filesystem'); $paths = []; foreach ($def->getMethodCalls() as $call) { - if ('addPath' === $call[0] && false === strpos($call[1][0], 'Form')) { + if ('addPath' === $call[0] && !str_contains($call[1][0], 'Form')) { $paths[] = $call[1]; } } diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index cecbadb50c..cb7ea41883 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -22,6 +22,7 @@ "symfony/http-foundation": "^4.4|^5.0", "symfony/http-kernel": "^5.0", "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.16", "twig/twig": "^2.13|^3.0.4" }, "require-dev": { diff --git a/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php b/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php index c2af599cff..ce24136926 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php @@ -221,7 +221,7 @@ class ContentSecurityPolicyHandler private function hasHashOrNonce(array $directives): bool { foreach ($directives as $directive) { - if ('\'' !== substr($directive, -1)) { + if (!str_ends_with($directive, '\'')) { continue; } if ('\'nonce-' === substr($directive, 0, 7)) { diff --git a/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php b/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php index 2fdc42bdf6..89441d15db 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php +++ b/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php @@ -101,7 +101,7 @@ class WebDebugToolbarListener implements EventSubscriberInterface if (self::DISABLED === $this->mode || !$response->headers->has('X-Debug-Token') || $response->isRedirection() - || ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html')) + || ($response->headers->has('Content-Type') && !str_contains($response->headers->get('Content-Type'), 'html')) || 'html' !== $request->getRequestFormat() || false !== stripos($response->headers->get('Content-Disposition', ''), 'attachment;') ) { diff --git a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php index bb9daab006..794c118837 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php @@ -78,7 +78,7 @@ class TemplateManager continue; } - if ('.html.twig' === substr($template, -10)) { + if (str_ends_with($template, '.html.twig')) { $template = substr($template, 0, -10); } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php b/src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php index 1f9d54bf71..8a8721a3a1 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php @@ -90,7 +90,7 @@ class WebProfilerExtension extends ProfilerExtension $message = twig_escape_filter($env, $message); $message = preg_replace('/"(.*?)"/', '"$1"', $message); - if (null === $context || false === strpos($message, '{')) { + if (null === $context || !str_contains($message, '{')) { return ''.$message.''; } diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index 46b7e78567..641d4cc6f1 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -20,6 +20,7 @@ "symfony/config": "^4.4|^5.0", "symfony/framework-bundle": "^5.1", "symfony/http-kernel": "^5.2", + "symfony/polyfill-php80": "^1.16", "symfony/routing": "^4.4|^5.0", "symfony/twig-bundle": "^4.4|^5.0", "twig/twig": "^2.13|^3.0.4" diff --git a/src/Symfony/Component/Asset/Package.php b/src/Symfony/Component/Asset/Package.php index ad6044bd3e..a74e33449f 100644 --- a/src/Symfony/Component/Asset/Package.php +++ b/src/Symfony/Component/Asset/Package.php @@ -73,6 +73,6 @@ class Package implements PackageInterface */ protected function isAbsoluteUrl(string $url) { - return false !== strpos($url, '://') || '//' === substr($url, 0, 2); + return str_contains($url, '://') || '//' === substr($url, 0, 2); } } diff --git a/src/Symfony/Component/Asset/composer.json b/src/Symfony/Component/Asset/composer.json index 60ebe4a8e6..974fcdf4e0 100644 --- a/src/Symfony/Component/Asset/composer.json +++ b/src/Symfony/Component/Asset/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "suggest": { "symfony/http-foundation": "" diff --git a/src/Symfony/Component/BrowserKit/Cookie.php b/src/Symfony/Component/BrowserKit/Cookie.php index e09846bfa1..2166652a66 100644 --- a/src/Symfony/Component/BrowserKit/Cookie.php +++ b/src/Symfony/Component/BrowserKit/Cookie.php @@ -129,7 +129,7 @@ class Cookie { $parts = explode(';', $cookie); - if (false === strpos($parts[0], '=')) { + if (!str_contains($parts[0], '=')) { throw new \InvalidArgumentException(sprintf('The cookie string "%s" is not valid.', $parts[0])); } diff --git a/src/Symfony/Component/BrowserKit/CookieJar.php b/src/Symfony/Component/BrowserKit/CookieJar.php index 3a585bed66..b12cc5203e 100644 --- a/src/Symfony/Component/BrowserKit/CookieJar.php +++ b/src/Symfony/Component/BrowserKit/CookieJar.php @@ -42,13 +42,13 @@ class CookieJar foreach ($this->cookieJar as $cookieDomain => $pathCookies) { if ($cookieDomain && $domain) { $cookieDomain = '.'.ltrim($cookieDomain, '.'); - if ($cookieDomain !== substr('.'.$domain, -\strlen($cookieDomain))) { + if (!str_ends_with('.'.$domain, $cookieDomain)) { continue; } } foreach ($pathCookies as $cookiePath => $namedCookies) { - if (0 !== strpos($path, $cookiePath)) { + if (!str_starts_with($path, $cookiePath)) { continue; } if (isset($namedCookies[$name])) { diff --git a/src/Symfony/Component/BrowserKit/HttpBrowser.php b/src/Symfony/Component/BrowserKit/HttpBrowser.php index e7ccde4fa4..a3532161a3 100644 --- a/src/Symfony/Component/BrowserKit/HttpBrowser.php +++ b/src/Symfony/Component/BrowserKit/HttpBrowser.php @@ -100,7 +100,7 @@ class HttpBrowser extends AbstractBrowser foreach ($request->getServer() as $key => $value) { $key = strtolower(str_replace('_', '-', $key)); $contentHeaders = ['content-length' => true, 'content-md5' => true, 'content-type' => true]; - if (0 === strpos($key, 'http-')) { + if (str_starts_with($key, 'http-')) { $headers[substr($key, 5)] = $value; } elseif (isset($contentHeaders[$key])) { // CONTENT_* are not prefixed with HTTP_ diff --git a/src/Symfony/Component/BrowserKit/composer.json b/src/Symfony/Component/BrowserKit/composer.json index 239b8faa1b..b41f7d65b9 100644 --- a/src/Symfony/Component/BrowserKit/composer.json +++ b/src/Symfony/Component/BrowserKit/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=7.2.5", - "symfony/dom-crawler": "^4.4|^5.0" + "symfony/dom-crawler": "^4.4|^5.0", + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "symfony/css-selector": "^4.4|^5.0", diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index d32d627324..a42a039a3d 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -126,10 +126,10 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg public static function createConnection(string $dsn, array $options = []) { - if (0 === strpos($dsn, 'redis:') || 0 === strpos($dsn, 'rediss:')) { + if (str_starts_with($dsn, 'redis:') || str_starts_with($dsn, 'rediss:')) { return RedisAdapter::createConnection($dsn, $options); } - if (0 === strpos($dsn, 'memcached:')) { + if (str_starts_with($dsn, 'memcached:')) { return MemcachedAdapter::createConnection($dsn, $options); } if (0 === strpos($dsn, 'couchbase:')) { diff --git a/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php index 34b1044e2b..304d173737 100644 --- a/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php @@ -88,7 +88,7 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter protected function doSave(array $values, int $lifetime, array $addTagData = [], array $delTagData = []): array { $eviction = $this->getRedisEvictionPolicy(); - if ('noeviction' !== $eviction && 0 !== strpos($eviction, 'volatile-')) { + if ('noeviction' !== $eviction && !str_starts_with($eviction, 'volatile-')) { throw new LogicException(sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction)); } diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index c0bdafd3c2..f5d0b73fe0 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -233,7 +233,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac { if ('' !== $prefix) { foreach ($this->deferred as $key => $item) { - if (0 === strpos($key, $prefix)) { + if (str_starts_with($key, $prefix)) { unset($this->deferred[$key]); } } diff --git a/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php b/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php index 07433bd00b..8e45081aef 100644 --- a/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php +++ b/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php @@ -58,7 +58,7 @@ trait FilesystemCommonTrait $ok = true; foreach ($this->scanHashDir($this->directory) as $file) { - if ('' !== $namespace && 0 !== strpos($this->getFileKey($file), $namespace)) { + if ('' !== $namespace && !str_starts_with($this->getFileKey($file), $namespace)) { continue; } @@ -98,7 +98,7 @@ trait FilesystemCommonTrait try { $h = fopen($this->tmp, 'x'); } catch (\ErrorException $e) { - if (false === strpos($e->getMessage(), 'File exists')) { + if (!str_contains($e->getMessage(), 'File exists')) { throw $e; } diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index 77fe0b8b25..550ae92dc4 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -90,9 +90,9 @@ trait RedisTrait */ public static function createConnection(string $dsn, array $options = []) { - if (0 === strpos($dsn, 'redis:')) { + if (str_starts_with($dsn, 'redis:')) { $scheme = 'redis'; - } elseif (0 === strpos($dsn, 'rediss:')) { + } elseif (str_starts_with($dsn, 'rediss:')) { $scheme = 'rediss'; } else { throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s" does not start with "redis:" or "rediss".', $dsn)); diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index 3671872571..6f26bdcfaa 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -25,7 +25,7 @@ "psr/cache": "^1.0|^2.0", "psr/log": "^1.1|^2|^3", "symfony/cache-contracts": "^1.1.7|^2", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2", "symfony/var-exporter": "^4.4|^5.0" }, diff --git a/src/Symfony/Component/Config/Definition/ArrayNode.php b/src/Symfony/Component/Config/Definition/ArrayNode.php index d2df4575c4..601d2da9a8 100644 --- a/src/Symfony/Component/Config/Definition/ArrayNode.php +++ b/src/Symfony/Component/Config/Definition/ArrayNode.php @@ -55,7 +55,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface $normalized = []; foreach ($value as $k => $v) { - if (false !== strpos($k, '-') && false === strpos($k, '_') && !\array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) { + if (str_contains($k, '-') && !str_contains($k, '_') && !\array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) { $normalized[$normalizedKey] = $v; } else { $normalized[$k] = $v; diff --git a/src/Symfony/Component/Config/Definition/BaseNode.php b/src/Symfony/Component/Config/Definition/BaseNode.php index 5526697b0a..e945ea3bf6 100644 --- a/src/Symfony/Component/Config/Definition/BaseNode.php +++ b/src/Symfony/Component/Config/Definition/BaseNode.php @@ -47,7 +47,7 @@ abstract class BaseNode implements NodeInterface */ public function __construct(?string $name, NodeInterface $parent = null, string $pathSeparator = self::DEFAULT_PATH_SEPARATOR) { - if (false !== strpos($name = (string) $name, $pathSeparator)) { + if (str_contains($name = (string) $name, $pathSeparator)) { throw new \InvalidArgumentException('The name must not contain ".'.$pathSeparator.'".'); } @@ -542,7 +542,7 @@ abstract class BaseNode implements NodeInterface } foreach (self::$placeholderUniquePrefixes as $placeholderUniquePrefix) { - if (0 === strpos($value, $placeholderUniquePrefix)) { + if (str_starts_with($value, $placeholderUniquePrefix)) { return []; } } diff --git a/src/Symfony/Component/Config/Loader/FileLoader.php b/src/Symfony/Component/Config/Loader/FileLoader.php index 16a50220f0..a2dfc83033 100644 --- a/src/Symfony/Component/Config/Loader/FileLoader.php +++ b/src/Symfony/Component/Config/Loader/FileLoader.php @@ -71,7 +71,7 @@ abstract class FileLoader extends Loader */ public function import($resource, string $type = null, bool $ignoreErrors = false, string $sourceResource = null, $exclude = null) { - if (\is_string($resource) && \strlen($resource) !== ($i = strcspn($resource, '*?{[')) && false === strpos($resource, "\n")) { + if (\is_string($resource) && \strlen($resource) !== ($i = strcspn($resource, '*?{[')) && !str_contains($resource, "\n")) { $excluded = []; foreach ((array) $exclude as $pattern) { foreach ($this->glob($pattern, true, $_, false, true) as $path => $info) { @@ -81,7 +81,7 @@ abstract class FileLoader extends Loader } $ret = []; - $isSubpath = 0 !== $i && false !== strpos(substr($resource, 0, $i), '/'); + $isSubpath = 0 !== $i && str_contains(substr($resource, 0, $i), '/'); foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath, false, $excluded) as $path => $info) { if (null !== $res = $this->doImport($path, 'glob' === $type ? null : $type, $ignoreErrors, $sourceResource)) { $ret[] = $res; @@ -105,7 +105,7 @@ abstract class FileLoader extends Loader if (\strlen($pattern) === $i = strcspn($pattern, '*?{[')) { $prefix = $pattern; $pattern = ''; - } elseif (0 === $i || false === strpos(substr($pattern, 0, $i), '/')) { + } elseif (0 === $i || !str_contains(substr($pattern, 0, $i), '/')) { $prefix = '.'; $pattern = '/'.$pattern; } else { diff --git a/src/Symfony/Component/Config/Resource/ComposerResource.php b/src/Symfony/Component/Config/Resource/ComposerResource.php index cb7370b95b..f552f80ac5 100644 --- a/src/Symfony/Component/Config/Resource/ComposerResource.php +++ b/src/Symfony/Component/Config/Resource/ComposerResource.php @@ -55,7 +55,7 @@ class ComposerResource implements SelfCheckingResourceInterface self::$runtimeVendors = []; foreach (get_declared_classes() as $class) { - if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { + if ('C' === $class[0] && str_starts_with($class, 'ComposerAutoloaderInit')) { $r = new \ReflectionClass($class); $v = \dirname($r->getFileName(), 2); if (is_file($v.'/composer/installed.json')) { diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 07cccd21c5..a7501095a4 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -81,7 +81,7 @@ class DirectoryResource implements SelfCheckingResourceInterface // always monitor directories for changes, except the .. entries // (otherwise deleted files wouldn't get detected) - if ($file->isDir() && '/..' === substr($file, -3)) { + if ($file->isDir() && str_ends_with($file, '/..')) { continue; } diff --git a/src/Symfony/Component/Config/Resource/GlobResource.php b/src/Symfony/Component/Config/Resource/GlobResource.php index 54cace4847..2ac06986d5 100644 --- a/src/Symfony/Component/Config/Resource/GlobResource.php +++ b/src/Symfony/Component/Config/Resource/GlobResource.php @@ -107,10 +107,10 @@ class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface $prefix = str_replace('\\', '/', $this->prefix); $paths = null; - if (0 !== strpos($this->prefix, 'phar://') && false === strpos($this->pattern, '/**/')) { - if ($this->globBrace || false === strpos($this->pattern, '{')) { + if (!str_starts_with($this->prefix, 'phar://') && !str_contains($this->pattern, '/**/')) { + if ($this->globBrace || !str_contains($this->pattern, '{')) { $paths = glob($this->prefix.$this->pattern, \GLOB_NOSORT | $this->globBrace); - } elseif (false === strpos($this->pattern, '\\') || !preg_match('/\\\\[,{}]/', $this->pattern)) { + } elseif (!str_contains($this->pattern, '\\') || !preg_match('/\\\\[,{}]/', $this->pattern)) { foreach ($this->expandGlob($this->pattern) as $p) { $paths[] = glob($this->prefix.$p, \GLOB_NOSORT); } @@ -223,7 +223,7 @@ class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface $j = 0; foreach ($patterns as $i => $p) { - if (false !== strpos($p, '{')) { + if (str_contains($p, '{')) { $p = $this->expandGlob($p); array_splice($paths, $i + $j, 1, $p); $j += \count($p) - 1; diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index 4bc6903cdf..61e8d71d05 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -85,7 +85,7 @@ class ReflectionClassResource implements SelfCheckingResourceInterface $file = $class->getFileName(); if (false !== $file && is_file($file)) { foreach ($this->excludedVendors as $vendor) { - if (0 === strpos($file, $vendor) && false !== strpbrk(substr($file, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { + if (str_starts_with($file, $vendor) && false !== strpbrk(substr($file, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { $file = false; break; } diff --git a/src/Symfony/Component/Config/Tests/Resource/ComposerResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ComposerResourceTest.php index 6857c766d1..10139f53a8 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ComposerResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ComposerResourceTest.php @@ -25,7 +25,7 @@ class ComposerResourceTest extends TestCase $found = false; foreach ($res->getVendors() as $vendor) { - if ($vendor && 0 === strpos($r->getFileName(), $vendor)) { + if ($vendor && str_starts_with($r->getFileName(), $vendor)) { $found = true; break; } diff --git a/src/Symfony/Component/Config/composer.json b/src/Symfony/Component/Config/composer.json index b99d04c7d8..a014fd2726 100644 --- a/src/Symfony/Component/Config/composer.json +++ b/src/Symfony/Component/Config/composer.json @@ -20,7 +20,7 @@ "symfony/deprecation-contracts": "^2.1", "symfony/filesystem": "^4.4|^5.0", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/polyfill-php81": "^1.22" }, "require-dev": { diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 2a4966b463..416ab222bc 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -812,7 +812,7 @@ class Application implements ResetInterface $len = 0; } - if (false !== strpos($message, "@anonymous\0")) { + if (str_contains($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); @@ -1113,7 +1113,7 @@ class Application implements ResetInterface } $lev = levenshtein($subname, $parts[$i]); - if ($lev <= \strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) { + if ($lev <= \strlen($subname) / 3 || '' !== $subname && str_contains($parts[$i], $subname)) { $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; } elseif ($exists) { $alternatives[$collectionName] += $threshold; @@ -1123,7 +1123,7 @@ class Application implements ResetInterface foreach ($collection as $item) { $lev = levenshtein($name, $item); - if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) { + if ($lev <= \strlen($name) / 3 || str_contains($item, $name)) { $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; } } diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index 84facf7d63..c6add43d6f 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -604,7 +604,7 @@ class Command */ public function addUsage(string $usage) { - if (0 !== strpos($usage, $this->name)) { + if (!str_starts_with($usage, $this->name)) { $usage = sprintf('%s %s', $this->name, $usage); } diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php index 52ca232730..80d59b3b4d 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php @@ -52,7 +52,7 @@ class OutputFormatter implements WrappableOutputFormatterInterface */ public static function escapeTrailingBackslash(string $text): string { - if ('\\' === substr($text, -1)) { + if (str_ends_with($text, '\\')) { $len = \strlen($text); $text = rtrim($text, '\\'); $text = str_replace("\0", '', $text); @@ -178,7 +178,7 @@ class OutputFormatter implements WrappableOutputFormatterInterface $output .= $this->applyCurrentStyle(substr($message, $offset), $output, $width, $currentLineLength); - if (false !== strpos($output, "\0")) { + if (str_contains($output, "\0")) { return strtr($output, ["\0" => '\\', '\\<' => '<']); } diff --git a/src/Symfony/Component/Console/Helper/QuestionHelper.php b/src/Symfony/Component/Console/Helper/QuestionHelper.php index 7b99783629..2f1be71b54 100644 --- a/src/Symfony/Component/Console/Helper/QuestionHelper.php +++ b/src/Symfony/Component/Console/Helper/QuestionHelper.php @@ -311,7 +311,7 @@ class QuestionHelper extends Helper $matches = array_filter( $autocomplete($ret), function ($match) use ($ret) { - return '' === $ret || 0 === strpos($match, $ret); + return '' === $ret || str_starts_with($match, $ret); } ); $numMatches = \count($matches); @@ -348,7 +348,7 @@ class QuestionHelper extends Helper foreach ($autocomplete($ret) as $value) { // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) - if (0 === strpos($value, $tempRet)) { + if (str_starts_with($value, $tempRet)) { $matches[$numMatches++] = $value; } } @@ -374,7 +374,7 @@ class QuestionHelper extends Helper private function mostRecentlyEnteredValue(string $entered): string { // Determine the most recent value that the user entered - if (false === strpos($entered, ',')) { + if (!str_contains($entered, ',')) { return $entered; } diff --git a/src/Symfony/Component/Console/Input/ArgvInput.php b/src/Symfony/Component/Console/Input/ArgvInput.php index 2171bdc968..c10bbf47a9 100644 --- a/src/Symfony/Component/Console/Input/ArgvInput.php +++ b/src/Symfony/Component/Console/Input/ArgvInput.php @@ -72,7 +72,7 @@ class ArgvInput extends Input $this->parseArgument($token); } elseif ($parseOptions && '--' == $token) { $parseOptions = false; - } elseif ($parseOptions && 0 === strpos($token, '--')) { + } elseif ($parseOptions && str_starts_with($token, '--')) { $this->parseLongOption($token); } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { $this->parseShortOption($token); @@ -254,7 +254,7 @@ class ArgvInput extends Input $isOption = false; foreach ($this->tokens as $i => $token) { if ($token && '-' === $token[0]) { - if (false !== strpos($token, '=') || !isset($this->tokens[$i + 1])) { + if (str_contains($token, '=') || !isset($this->tokens[$i + 1])) { continue; } @@ -296,8 +296,8 @@ class ArgvInput extends Input // Options with values: // For long options, test for '--option=' at beginning // For short options, test for '-o' at beginning - $leading = 0 === strpos($value, '--') ? $value.'=' : $value; - if ($token === $value || '' !== $leading && 0 === strpos($token, $leading)) { + $leading = str_starts_with($value, '--') ? $value.'=' : $value; + if ($token === $value || '' !== $leading && str_starts_with($token, $leading)) { return true; } } @@ -327,8 +327,8 @@ class ArgvInput extends Input // Options with values: // For long options, test for '--option=' at beginning // For short options, test for '-o' at beginning - $leading = 0 === strpos($value, '--') ? $value.'=' : $value; - if ('' !== $leading && 0 === strpos($token, $leading)) { + $leading = str_starts_with($value, '--') ? $value.'=' : $value; + if ('' !== $leading && str_starts_with($token, $leading)) { return substr($token, \strlen($leading)); } } diff --git a/src/Symfony/Component/Console/Input/ArrayInput.php b/src/Symfony/Component/Console/Input/ArrayInput.php index 5c1e2f63ae..6f7d5d8244 100644 --- a/src/Symfony/Component/Console/Input/ArrayInput.php +++ b/src/Symfony/Component/Console/Input/ArrayInput.php @@ -133,9 +133,9 @@ class ArrayInput extends Input if ('--' === $key) { return; } - if (0 === strpos($key, '--')) { + if (str_starts_with($key, '--')) { $this->addLongOption(substr($key, 2), $value); - } elseif (0 === strpos($key, '-')) { + } elseif (str_starts_with($key, '-')) { $this->addShortOption(substr($key, 1), $value); } else { $this->addArgument($key, $value); diff --git a/src/Symfony/Component/Console/Input/InputOption.php b/src/Symfony/Component/Console/Input/InputOption.php index 710e9a8095..c40e0da344 100644 --- a/src/Symfony/Component/Console/Input/InputOption.php +++ b/src/Symfony/Component/Console/Input/InputOption.php @@ -56,7 +56,7 @@ class InputOption */ public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null) { - if (0 === strpos($name, '--')) { + if (str_starts_with($name, '--')) { $name = substr($name, 2); } diff --git a/src/Symfony/Component/Console/Logger/ConsoleLogger.php b/src/Symfony/Component/Console/Logger/ConsoleLogger.php index 4a03156565..c9ee03561b 100644 --- a/src/Symfony/Component/Console/Logger/ConsoleLogger.php +++ b/src/Symfony/Component/Console/Logger/ConsoleLogger.php @@ -104,7 +104,7 @@ class ConsoleLogger extends AbstractLogger */ private function interpolate(string $message, array $context): string { - if (false === strpos($message, '{')) { + if (!str_contains($message, '{')) { return $message; } diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php index 7fd74aa679..2246b1f453 100644 --- a/src/Symfony/Component/Console/Style/SymfonyStyle.php +++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php @@ -447,7 +447,7 @@ class SymfonyStyle extends OutputStyle { $fetched = $this->bufferedOutput->fetch(); //Prepend new line if last char isn't EOL: - if ("\n" !== substr($fetched, -1)) { + if (!str_ends_with($fetched, "\n")) { $this->newLine(); } } diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index 7fdba052fc..35cbaf6250 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -19,7 +19,7 @@ "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2", "symfony/string": "^5.1" }, diff --git a/src/Symfony/Component/CssSelector/Parser/Parser.php b/src/Symfony/Component/CssSelector/Parser/Parser.php index 963efb013e..d73489edfb 100644 --- a/src/Symfony/Component/CssSelector/Parser/Parser.php +++ b/src/Symfony/Component/CssSelector/Parser/Parser.php @@ -79,7 +79,7 @@ class Parser implements ParserInterface return [2, 0]; case 'n' === $joined: return [1, 0]; - case false === strpos($joined, 'n'): + case !str_contains($joined, 'n'): return [0, $int($joined)]; } diff --git a/src/Symfony/Component/CssSelector/XPath/Translator.php b/src/Symfony/Component/CssSelector/XPath/Translator.php index 3fab76ad69..8ce4730360 100644 --- a/src/Symfony/Component/CssSelector/XPath/Translator.php +++ b/src/Symfony/Component/CssSelector/XPath/Translator.php @@ -63,11 +63,11 @@ class Translator implements TranslatorInterface public static function getXpathLiteral(string $element): string { - if (false === strpos($element, "'")) { + if (!str_contains($element, "'")) { return "'".$element."'"; } - if (false === strpos($element, '"')) { + if (!str_contains($element, '"')) { return '"'.$element.'"'; } diff --git a/src/Symfony/Component/CssSelector/composer.json b/src/Symfony/Component/CssSelector/composer.json index eb63cf59c6..f0b712495a 100644 --- a/src/Symfony/Component/CssSelector/composer.json +++ b/src/Symfony/Component/CssSelector/composer.json @@ -20,7 +20,8 @@ } ], "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "autoload": { "psr-4": { "Symfony\\Component\\CssSelector\\": "" }, diff --git a/src/Symfony/Component/DependencyInjection/Alias.php b/src/Symfony/Component/DependencyInjection/Alias.php index 799229c147..d1c9989ec1 100644 --- a/src/Symfony/Component/DependencyInjection/Alias.php +++ b/src/Symfony/Component/DependencyInjection/Alias.php @@ -112,7 +112,7 @@ class Alias throw new InvalidArgumentException('Invalid characters found in deprecation template.'); } - if (false === strpos($message, '%alias_id%')) { + if (!str_contains($message, '%alias_id%')) { throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.'); } } diff --git a/src/Symfony/Component/DependencyInjection/ChildDefinition.php b/src/Symfony/Component/DependencyInjection/ChildDefinition.php index d51fdd2ef6..868cd14136 100644 --- a/src/Symfony/Component/DependencyInjection/ChildDefinition.php +++ b/src/Symfony/Component/DependencyInjection/ChildDefinition.php @@ -93,7 +93,7 @@ class ChildDefinition extends Definition { if (\is_int($index)) { $this->arguments['index_'.$index] = $value; - } elseif (0 === strpos($index, '$')) { + } elseif (str_starts_with($index, '$')) { $this->arguments[$index] = $value; } else { throw new InvalidArgumentException('The argument must be an existing index or the name of a constructor\'s parameter.'); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index 97db011367..052cfc49a9 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -297,7 +297,7 @@ class AutowirePass extends AbstractRecursivePass if ($this->container->has($name) && !$this->container->findDefinition($name)->isAbstract()) { foreach ($this->container->getAliases() as $id => $alias) { - if ($name === (string) $alias && 0 === strpos($id, $type.' $')) { + if ($name === (string) $alias && str_starts_with($id, $type.' $')) { return new TypedReference($name, $type, $reference->getInvalidBehavior()); } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php index bb87f47cdd..7abac908f5 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php @@ -49,7 +49,7 @@ class CheckDefinitionValidityPass implements CompilerPassInterface throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id)); } if (class_exists($id) || interface_exists($id, false)) { - if (0 === strpos($id, '\\') && 1 < substr_count($id, '\\')) { + if (str_starts_with($id, '\\') && 1 < substr_count($id, '\\')) { throw new RuntimeException(sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface. Please specify the class attribute explicitly or remove the leading backslash by renaming the service to "%s" to get rid of this error.', $id, substr($id, 1))); } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php index c9c9b8b194..f8ec9214de 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php @@ -231,7 +231,7 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass $value = $this->container->getParameter(substr($value, 1, -1)); } - if ($envPlaceholderUniquePrefix && \is_string($value) && false !== strpos($value, 'env_')) { + if ($envPlaceholderUniquePrefix && \is_string($value) && str_contains($value, 'env_')) { // If the value is an env placeholder that is either mixed with a string or with another env placeholder, then its resolved value will always be a string, so we don't need to resolve it. // We don't need to change the value because it is already a string. if ('' === preg_replace('/'.$envPlaceholderUniquePrefix.'_\w+_[a-f0-9]{32}/U', '', $value, -1, $c) && 1 === $c) { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php b/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php index 04ae8d51cb..f6566072f5 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php @@ -64,7 +64,7 @@ class Compiler */ public function log(CompilerPassInterface $pass, string $message) { - if (false !== strpos($message, "\n")) { + if (str_contains($message, "\n")) { $message = str_replace("\n", "\n".\get_class($pass).': ', trim($message)); } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index 57505f96da..feaad77e59 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -209,7 +209,7 @@ class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder } foreach ($bag->getEnvPlaceholders() as $env => $placeholders) { - if (false === strpos($env, ':')) { + if (!str_contains($env, ':')) { continue; } foreach ($placeholders as $placeholder) { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php index f6301f1dd6..c292c23b11 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php @@ -91,7 +91,7 @@ class RegisterServiceSubscribersPass extends AbstractRecursivePass if ($name) { if (false !== $i = strpos($name, '::get')) { $name = lcfirst(substr($name, 5 + $i)); - } elseif (false !== strpos($name, '::')) { + } elseif (str_contains($name, '::')) { $name = null; } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php index b7f55e0429..91cba0029f 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php @@ -44,7 +44,7 @@ class ResolveBindingsPass extends AbstractRecursivePass foreach ($this->unusedBindings as [$key, $serviceId, $bindingType, $file]) { $argumentType = $argumentName = $message = null; - if (false !== strpos($key, ' ')) { + if (str_contains($key, ' ')) { [$argumentType, $argumentName] = explode(' ', $key, 2); } elseif ('$' === $key[0]) { $argumentName = $key; diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php index bb11c2f909..a1b2c86e3d 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php @@ -164,7 +164,7 @@ class ResolveChildDefinitionsPass extends AbstractRecursivePass foreach ($definition->getArguments() as $k => $v) { if (is_numeric($k)) { $def->addArgument($v); - } elseif (0 === strpos($k, 'index_')) { + } elseif (str_starts_with($k, 'index_')) { $def->replaceArgument((int) substr($k, \strlen('index_')), $v); } else { $def->setArgument($k, $v); diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 030c7f9868..d2793f1c91 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -263,7 +263,7 @@ class Container implements ContainerInterface, ResetInterface continue; } $lev = levenshtein($id, $knownId); - if ($lev <= \strlen($id) / 3 || false !== strpos($knownId, $id)) { + if ($lev <= \strlen($id) / 3 || str_contains($knownId, $id)) { $alternatives[] = $knownId; } } diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 628f44c43f..266c3bfd18 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1588,7 +1588,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface $path = realpath($path) ?: $path; foreach ($this->vendors as $vendor) { - if (0 === strpos($path, $vendor) && false !== strpbrk(substr($path, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { + if (str_starts_with($path, $vendor) && false !== strpbrk(substr($path, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { $this->addResource(new FileResource($vendor.'/composer/installed.json')); return true; diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index a8c76c10ed..90f8f886cd 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -104,7 +104,7 @@ class Definition { $this->changes['factory'] = true; - if (\is_string($factory) && false !== strpos($factory, '::')) { + if (\is_string($factory) && str_contains($factory, '::')) { $factory = explode('::', $factory, 2); } elseif ($factory instanceof Reference) { $factory = [$factory, '__invoke']; @@ -737,7 +737,7 @@ class Definition throw new InvalidArgumentException('Invalid characters found in deprecation template.'); } - if (false === strpos($message, '%service_id%')) { + if (!str_contains($message, '%service_id%')) { throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.'); } } @@ -798,7 +798,7 @@ class Definition { $this->changes['configurator'] = true; - if (\is_string($configurator) && false !== strpos($configurator, '::')) { + if (\is_string($configurator) && str_contains($configurator, '::')) { $configurator = explode('::', $configurator, 2); } elseif ($configurator instanceof Reference) { $configurator = [$configurator, '__invoke']; diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 82e167cde0..da745850d5 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -160,7 +160,7 @@ class PhpDumper extends Dumper $this->inlineRequires = $options['inline_class_loader_parameter'] && ($this->container->hasParameter($options['inline_class_loader_parameter']) ? $this->container->getParameter($options['inline_class_loader_parameter']) : (\PHP_VERSION_ID < 70400 || $options['debug'])); $this->serviceLocatorTag = $options['service_locator_tag']; - if (0 !== strpos($baseClass = $options['base_class'], '\\') && 'Container' !== $baseClass) { + if (!str_starts_with($baseClass = $options['base_class'], '\\') && 'Container' !== $baseClass) { $baseClass = sprintf('%s\%s', $options['namespace'] ? '\\'.$options['namespace'] : '', $baseClass); $this->baseClass = $baseClass; } elseif ('Container' === $baseClass) { @@ -332,7 +332,7 @@ require __DIR__.'/$preloadedFiles'; EOF; foreach ($this->preload as $class) { - if (!$class || false !== strpos($class, '$') || \in_array($class, ['int', 'float', 'string', 'bool', 'resource', 'object', 'array', 'null', 'callable', 'iterable', 'mixed', 'void'], true)) { + if (!$class || str_contains($class, '$') || \in_array($class, ['int', 'float', 'string', 'bool', 'resource', 'object', 'array', 'null', 'callable', 'iterable', 'mixed', 'void'], true)) { continue; } if (!(class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) || (new \ReflectionClass($class))->isUserDefined()) { @@ -523,7 +523,7 @@ EOF; return; } $file = $r->getFileName(); - if (') : eval()\'d code' === substr($file, -17)) { + if (str_ends_with($file, ') : eval()\'d code')) { $file = substr($file, 0, strrpos($file, '(', -17)); } if (!$file || $this->doExport($file) === $exportedFile = $this->export($file)) { @@ -656,7 +656,7 @@ EOF; { $class = $this->dumpValue($definition->getClass()); - if (0 === strpos($class, "'") && false === strpos($class, '$') && !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + if (str_starts_with($class, "'") && !str_contains($class, '$') && !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); } @@ -783,11 +783,11 @@ EOF; $class = $this->dumpValue($callable[0]); // If the class is a string we can optimize away - if (0 === strpos($class, "'") && false === strpos($class, '$')) { + if (str_starts_with($class, "'") && !str_contains($class, '$')) { return sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName); } - if (0 === strpos($class, 'new ')) { + if (str_starts_with($class, 'new ')) { return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); } @@ -808,7 +808,7 @@ EOF; if ($class = $definition->getClass()) { $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); - $return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\')); + $return[] = sprintf(str_starts_with($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\')); } elseif ($definition->getFactory()) { $factory = $definition->getFactory(); if (\is_string($factory)) { @@ -821,7 +821,7 @@ EOF; } if ($definition->isDeprecated()) { - if ($return && 0 === strpos($return[\count($return) - 1], '@return')) { + if ($return && str_starts_with($return[\count($return) - 1], '@return')) { $return[] = ''; } @@ -1151,7 +1151,7 @@ EOTXT $class = $this->dumpValue($callable[0]); // If the class is a string we can optimize away - if (0 === strpos($class, "'") && false === strpos($class, '$')) { + if (str_starts_with($class, "'") && !str_contains($class, '$')) { if ("''" === $class) { throw new RuntimeException(sprintf('Cannot dump definition: "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id ? 'The "'.$id.'"' : 'inline')); } @@ -1159,7 +1159,7 @@ EOTXT return $return.sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '').$tail; } - if (0 === strpos($class, 'new ')) { + if (str_starts_with($class, 'new ')) { return $return.sprintf('(%s)->%s(%s)', $class, $callable[1], $arguments ? implode(', ', $arguments) : '').$tail; } @@ -1889,16 +1889,16 @@ EOF; */ private function dumpLiteralClass(string $class): string { - if (false !== strpos($class, '$')) { + if (str_contains($class, '$')) { return sprintf('${($_ = %s) && false ?: "_"}', $class); } - if (0 !== strpos($class, "'") || !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + if (!str_starts_with($class, "'") || !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { throw new RuntimeException(sprintf('Cannot dump definition because of invalid class name (%s).', $class ?: 'n/a')); } $class = substr(str_replace('\\\\', '\\', $class), 1, -1); - return 0 === strpos($class, '\\') ? $class : '\\'.$class; + return str_starts_with($class, '\\') ? $class : '\\'.$class; } private function dumpParameter(string $name): string @@ -2146,7 +2146,7 @@ EOF; if ($shouldCacheValue && isset($this->exportedVariables[$value])) { return $this->exportedVariables[$value]; } - if (\is_string($value) && false !== strpos($value, "\n")) { + if (\is_string($value) && str_contains($value, "\n")) { $cleanParts = explode("\n", $value); $cleanParts = array_map(function ($part) { return var_export($part, true); }, $cleanParts); $export = implode('."\n".', $cleanParts); @@ -2164,7 +2164,7 @@ EOF; if ($resolveEnv && "'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'")) { $export = $resolvedExport; - if (".''" === substr($export, -3)) { + if (str_ends_with($export, ".''")) { $export = substr($export, 0, -3); if ("'" === $export[1]) { $export = substr_replace($export, '', 18, 7); @@ -2200,7 +2200,7 @@ EOF; } foreach (get_declared_classes() as $class) { - if (0 === strpos($class, 'ComposerAutoloaderInit') && $class::getLoader() === $autoloader[0]) { + if (str_starts_with($class, 'ComposerAutoloaderInit') && $class::getLoader() === $autoloader[0]) { $file = \dirname((new \ReflectionClass($class))->getFileName(), 2).'/autoload.php'; if (null !== $this->targetDirRegex && preg_match($this->targetDirRegex.'A', $file)) { diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index 98617a66da..4c9bb7572c 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -347,7 +347,7 @@ class YamlDumper extends Dumper foreach ($parameters as $key => $value) { if (\is_array($value)) { $value = $this->prepareParameters($value, $escape); - } elseif ($value instanceof Reference || \is_string($value) && 0 === strpos($value, '@')) { + } elseif ($value instanceof Reference || \is_string($value) && str_starts_with($value, '@')) { $value = '@'.$value; } diff --git a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php index 39eb3d9967..02d7adbb71 100644 --- a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php +++ b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php @@ -129,7 +129,7 @@ class EnvVarProcessor implements EnvVarProcessorInterface $env = $getEnv($name); } elseif (isset($_ENV[$name])) { $env = $_ENV[$name]; - } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + } elseif (isset($_SERVER[$name]) && !str_starts_with($name, 'HTTP_')) { $env = $_SERVER[$name]; } elseif (false === ($env = getenv($name)) || null === $env) { // null is a possible value because of thread safety issues foreach ($this->loadedVars as $vars) { diff --git a/src/Symfony/Component/DependencyInjection/Extension/Extension.php b/src/Symfony/Component/DependencyInjection/Extension/Extension.php index 81070c911f..8fcf6789b1 100644 --- a/src/Symfony/Component/DependencyInjection/Extension/Extension.php +++ b/src/Symfony/Component/DependencyInjection/Extension/Extension.php @@ -67,7 +67,7 @@ abstract class Extension implements ExtensionInterface, ConfigurationExtensionIn public function getAlias() { $className = static::class; - if ('Extension' != substr($className, -9)) { + if (!str_ends_with($className, 'Extension')) { throw new BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.'); } $classBaseName = substr(strrchr($className, '\\'), 1, -9); @@ -82,7 +82,7 @@ abstract class Extension implements ExtensionInterface, ConfigurationExtensionIn { $class = static::class; - if (false !== strpos($class, "\0")) { + if (str_contains($class, "\0")) { return null; // ignore anonymous classes } diff --git a/src/Symfony/Component/DependencyInjection/Loader/DirectoryLoader.php b/src/Symfony/Component/DependencyInjection/Loader/DirectoryLoader.php index 943986982e..d4b454a1e8 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/DirectoryLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/DirectoryLoader.php @@ -49,6 +49,6 @@ class DirectoryLoader extends FileLoader return true; } - return null === $type && \is_string($resource) && '/' === substr($resource, -1); + return null === $type && \is_string($resource) && str_ends_with($resource, '/'); } } diff --git a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php index 3bd4c6a358..bdb9c9a8a0 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php @@ -89,7 +89,7 @@ abstract class FileLoader extends BaseFileLoader */ public function registerClasses(Definition $prototype, $namespace, $resource, $exclude = null) { - if ('\\' !== substr($namespace, -1)) { + if (!str_ends_with($namespace, '\\')) { throw new InvalidArgumentException(sprintf('Namespace prefix must end with a "\\": "%s".', $namespace)); } if (!preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\\)++$/', $namespace)) { @@ -177,7 +177,7 @@ abstract class FileLoader extends BaseFileLoader if (null === $prefixLen) { $prefixLen = \strlen($resource->getPrefix()); - if ($excludePrefix && 0 !== strpos($excludePrefix, $resource->getPrefix())) { + if ($excludePrefix && !str_starts_with($excludePrefix, $resource->getPrefix())) { throw new InvalidArgumentException(sprintf('Invalid "exclude" pattern when importing classes for "%s": make sure your "exclude" pattern (%s) is a subset of the "resource" pattern (%s).', $namespace, $excludePattern, $pattern)); } } diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 5dfe97355f..970818fdf7 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -323,7 +323,7 @@ class XmlFileLoader extends FileLoader continue; } - if (false !== strpos($name, '-') && false === strpos($name, '_') && !\array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) { + if (str_contains($name, '-') && !str_contains($name, '_') && !\array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) { $parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue); } // keep not normalized key @@ -612,7 +612,7 @@ class XmlFileLoader extends FileLoader array_shift($parts); $locationstart = 'phar:///'; } - } elseif ('\\' === \DIRECTORY_SEPARATOR && 0 === strpos($location, '\\\\')) { + } elseif ('\\' === \DIRECTORY_SEPARATOR && str_starts_with($location, '\\\\')) { $locationstart = ''; } $drive = '\\' === \DIRECTORY_SEPARATOR ? array_shift($parts).'/' : ''; diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index a874715f9d..b644bd0ae6 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -222,7 +222,7 @@ class YamlFileLoader extends FileLoader if (!$service || !\is_array($service)) { throw new InvalidArgumentException(sprintf('Type definition "%s" must be a non-empty array within "_instanceof" in "%s". Check your YAML syntax.', $id, $file)); } - if (\is_string($service) && 0 === strpos($service, '@')) { + if (\is_string($service) && str_starts_with($service, '@')) { throw new InvalidArgumentException(sprintf('Type definition "%s" cannot be an alias within "_instanceof" in "%s". Check your YAML syntax.', $id, $file)); } $this->parseDefinition($id, $service, $file, []); @@ -306,7 +306,7 @@ class YamlFileLoader extends FileLoader private function isUsingShortSyntax(array $service): bool { foreach ($service as $key => $value) { - if (\is_string($key) && ('' === $key || ('$' !== $key[0] && false === strpos($key, '\\')))) { + if (\is_string($key) && ('' === $key || ('$' !== $key[0] && !str_contains($key, '\\')))) { return false; } } @@ -327,7 +327,7 @@ class YamlFileLoader extends FileLoader throw new InvalidArgumentException(sprintf('Service names that start with an underscore are reserved. Rename the "%s" service or define it in XML instead.', $id)); } - if (\is_string($service) && 0 === strpos($service, '@')) { + if (\is_string($service) && str_starts_with($service, '@')) { $alias = new Alias(substr($service, 1)); if (isset($defaults['public'])) { @@ -688,7 +688,7 @@ class YamlFileLoader extends FileLoader { if (\is_string($callable)) { if ('' !== $callable && '@' === $callable[0]) { - if (false === strpos($callable, ':')) { + if (!str_contains($callable, ':')) { return [$this->resolveServices($callable, $file), '__invoke']; } @@ -874,20 +874,20 @@ class YamlFileLoader extends FileLoader foreach ($value as $k => $v) { $value[$k] = $this->resolveServices($v, $file, $isParameter); } - } elseif (\is_string($value) && 0 === strpos($value, '@=')) { + } elseif (\is_string($value) && str_starts_with($value, '@=')) { if (!class_exists(Expression::class)) { throw new \LogicException('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'); } return new Expression(substr($value, 2)); - } elseif (\is_string($value) && 0 === strpos($value, '@')) { - if (0 === strpos($value, '@@')) { + } elseif (\is_string($value) && str_starts_with($value, '@')) { + if (str_starts_with($value, '@@')) { $value = substr($value, 1); $invalidBehavior = null; - } elseif (0 === strpos($value, '@!')) { + } elseif (str_starts_with($value, '@!')) { $value = substr($value, 2); $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; - } elseif (0 === strpos($value, '@?')) { + } elseif (str_starts_with($value, '@?')) { $value = substr($value, 2); $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; } else { diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php index ed128fa5ea..67b8aeeb13 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php @@ -31,7 +31,7 @@ class EnvPlaceholderParameterBag extends ParameterBag */ public function get(string $name) { - if (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) { + if (str_starts_with($name, 'env(') && str_ends_with($name, ')') && 'env()' !== $name) { $env = substr($name, 4, -1); if (isset($this->envPlaceholders[$env])) { diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php index 2292ab6cb1..fad04fc6df 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php @@ -69,13 +69,13 @@ class ParameterBag implements ParameterBagInterface $alternatives = []; foreach ($this->parameters as $key => $parameterValue) { $lev = levenshtein($name, $key); - if ($lev <= \strlen($name) / 3 || false !== strpos($key, $name)) { + if ($lev <= \strlen($name) / 3 || str_contains($key, $name)) { $alternatives[] = $key; } } $nonNestedAlternative = null; - if (!\count($alternatives) && false !== strpos($name, '.')) { + if (!\count($alternatives) && str_contains($name, '.')) { $namePartsLength = array_map('strlen', explode('.', $name)); $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength))); while (\count($namePartsLength)) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 2d0f5f1e3a..a8e4d781d5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1031,7 +1031,7 @@ class ContainerBuilderTest extends TestCase $container->addResource($b = new FileResource(__DIR__.'/Fixtures/xml/services2.xml')); $resources = []; foreach ($container->getResources() as $resource) { - if (false === strpos($resource, '.php')) { + if (!str_contains($resource, '.php')) { $resources[] = $resource; } } @@ -1051,7 +1051,7 @@ class ContainerBuilderTest extends TestCase $resources = []; foreach ($container->getResources() as $resource) { - if (false === strpos($resource, '.php')) { + if (!str_contains($resource, '.php')) { $resources[] = $resource; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 06bb53bb3b..2fb43c35b9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -572,7 +572,7 @@ class XmlFileLoaderTest extends TestCase public function testExtensionInPhar() { - if (\extension_loaded('suhosin') && false === strpos(ini_get('suhosin.executor.include.whitelist'), 'phar')) { + if (\extension_loaded('suhosin') && !str_contains(ini_get('suhosin.executor.include.whitelist'), 'phar')) { $this->markTestSkipped('To run this test, add "phar" to the "suhosin.executor.include.whitelist" settings in your php.ini file.'); } diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index c5752e46d0..9a80c47035 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -19,7 +19,7 @@ "php": ">=7.2.5", "psr/container": "^1.0", "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1.6|^2" }, "require-dev": { diff --git a/src/Symfony/Component/DomCrawler/AbstractUriElement.php b/src/Symfony/Component/DomCrawler/AbstractUriElement.php index 8bc6be300f..76cc8362ef 100644 --- a/src/Symfony/Component/DomCrawler/AbstractUriElement.php +++ b/src/Symfony/Component/DomCrawler/AbstractUriElement.php @@ -103,7 +103,7 @@ abstract class AbstractUriElement return $path; } - if ('.' === substr($path, -1)) { + if (str_ends_with($path, '.')) { $path .= '/'; } diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index 63b35fad74..244d2e1a64 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -145,7 +145,7 @@ class Crawler implements \Countable, \IteratorAggregate public function addContent(string $content, string $type = null) { if (empty($type)) { - $type = 0 === strpos($content, '=7.2.5", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "symfony/css-selector": "^4.4|^5.0", diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index ade7fa5978..6c30803b21 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -190,7 +190,7 @@ final class Dotenv $loadedVars = array_flip(explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? $_ENV['SYMFONY_DOTENV_VARS'] ?? '')); foreach ($values as $name => $value) { - $notHttpName = 0 !== strpos($name, 'HTTP_'); + $notHttpName = !str_starts_with($name, 'HTTP_'); // don't check existence with getenv() because of thread safety issues if (!isset($loadedVars[$name]) && (!$overrideExistingVars && (isset($_ENV[$name]) || (isset($_SERVER[$name]) && $notHttpName)))) { continue; @@ -427,7 +427,7 @@ final class Dotenv private function resolveCommands(string $value, array $loadedVars): string { - if (false === strpos($value, '$')) { + if (!str_contains($value, '$')) { return $value; } @@ -463,7 +463,7 @@ final class Dotenv $env = []; foreach ($this->values as $name => $value) { - if (isset($loadedVars[$name]) || (!isset($_ENV[$name]) && !(isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')))) { + if (isset($loadedVars[$name]) || (!isset($_ENV[$name]) && !(isset($_SERVER[$name]) && !str_starts_with($name, 'HTTP_')))) { $env[$name] = $value; } } @@ -481,7 +481,7 @@ final class Dotenv private function resolveVariables(string $value, array $loadedVars): string { - if (false === strpos($value, '$')) { + if (!str_contains($value, '$')) { return $value; } @@ -516,7 +516,7 @@ final class Dotenv $value = $this->values[$name]; } elseif (isset($_ENV[$name])) { $value = $_ENV[$name]; - } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + } elseif (isset($_SERVER[$name]) && !str_starts_with($name, 'HTTP_')) { $value = $_SERVER[$name]; } elseif (isset($this->values[$name])) { $value = $this->values[$name]; diff --git a/src/Symfony/Component/Dotenv/composer.json b/src/Symfony/Component/Dotenv/composer.json index de8ec15974..6e85c9fded 100644 --- a/src/Symfony/Component/Dotenv/composer.json +++ b/src/Symfony/Component/Dotenv/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1" + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "symfony/process": "^4.4|^5.0" diff --git a/src/Symfony/Component/ErrorHandler/BufferingLogger.php b/src/Symfony/Component/ErrorHandler/BufferingLogger.php index 72be64d127..4c27685a84 100644 --- a/src/Symfony/Component/ErrorHandler/BufferingLogger.php +++ b/src/Symfony/Component/ErrorHandler/BufferingLogger.php @@ -48,7 +48,7 @@ class BufferingLogger extends AbstractLogger public function __destruct() { foreach ($this->logs as [$level, $message, $context]) { - if (false !== strpos($message, '{')) { + if (str_contains($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 c47794936e..356b32e8cb 100644 --- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php +++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php @@ -205,7 +205,7 @@ class DebugClassLoader if (false === $test || false === $i) { // filesystem is case sensitive self::$caseCheck = 0; - } elseif (substr($test, -\strlen($file)) === $file) { + } elseif (str_ends_with($test, $file)) { // filesystem is case insensitive and realpath() normalizes the case of characters self::$caseCheck = 1; } elseif ('Darwin' === \PHP_OS_FAMILY) { @@ -396,7 +396,7 @@ class DebugClassLoader } if (!$exists) { - if (false !== strpos($class, '/')) { + 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)); } @@ -418,7 +418,7 @@ class DebugClassLoader } $deprecations = []; - $className = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; + $className = str_contains($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) { @@ -434,17 +434,17 @@ class DebugClassLoader // Detect annotations on the class if (false !== $doc = $refl->getDocComment()) { foreach (['final', 'deprecated', 'internal'] as $annotation) { - if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (str_contains($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() && 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)) { + 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)) { foreach ($notice as $method) { $static = '' !== $method[1] && !empty($method[2]); $name = $method[3]; $description = $method[4] ?? null; - if (false === strpos($name, '(')) { + if (!str_contains($name, '(')) { $name .= '()'; } if (null !== $description) { @@ -495,7 +495,7 @@ class DebugClassLoader } } elseif (!$refl->isInterface()) { if (!strncmp($vendor, str_replace('_', '\\', $use), $vendorLen) - && 0 === strpos($className, 'Symfony\\') + && str_starts_with($className, 'Symfony\\') && (!class_exists(InstalledVersions::class) || 'symfony/symfony' !== InstalledVersions::getRootPackage()['name']) ) { @@ -596,12 +596,12 @@ class DebugClassLoader $forcePatchTypes = $this->patchTypes['force']; - if ($canAddReturnType = null !== $forcePatchTypes && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { + if ($canAddReturnType = null !== $forcePatchTypes && !str_contains($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { if ('void' !== (self::MAGIC_METHODS[$method->name] ?? 'void')) { $this->patchTypes['force'] = $forcePatchTypes ?: 'docblock'; } - $canAddReturnType = false !== strpos($refl->getFileName(), \DIRECTORY_SEPARATOR.'Tests'.\DIRECTORY_SEPARATOR) + $canAddReturnType = str_contains($refl->getFileName(), \DIRECTORY_SEPARATOR.'Tests'.\DIRECTORY_SEPARATOR) || $refl->isFinal() || $method->isFinal() || $method->isPrivate() @@ -622,8 +622,8 @@ class DebugClassLoader $this->patchMethod($method, $returnType, $declaringFile, $normalizedType); } - if (false === strpos($doc, '* @deprecated') && strncmp($ns, $declaringClass, $len)) { - if ($canAddReturnType && 'docblock' === $this->patchTypes['force'] && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { + if (!str_contains($doc, '* @deprecated') && strncmp($ns, $declaringClass, $len)) { + if ($canAddReturnType && 'docblock' === $this->patchTypes['force'] && !str_contains($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); @@ -639,7 +639,7 @@ class DebugClassLoader $matches = []; - if (!$method->hasReturnType() && ((false !== strpos($doc, '@return') && preg_match('/\n\s+\* @return +([^\s<(]+)/', $doc, $matches)) || 'void' !== (self::MAGIC_METHODS[$method->name] ?? 'void'))) { + if (!$method->hasReturnType() && ((str_contains($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); @@ -661,14 +661,14 @@ class DebugClassLoader $finalOrInternal = false; foreach (['final', 'internal'] as $annotation) { - if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (str_contains($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() || false === strpos($doc, '@param') || StatelessInvocation::class === $class) { + if ($finalOrInternal || $method->isConstructor() || !str_contains($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)) { @@ -849,7 +849,7 @@ class DebugClassLoader $iterable = $object = true; foreach ($typesMap as $n => $t) { if ('null' !== $n) { - $iterable = $iterable && (\in_array($n, ['array', 'iterable']) || false !== strpos($n, 'Iterator')); + $iterable = $iterable && (\in_array($n, ['array', 'iterable']) || str_contains($n, 'Iterator')); $object = $object && (\in_array($n, ['callable', 'object', '$this', 'static']) || !isset(self::SPECIAL_RETURN_TYPES[$n])); } } @@ -1033,15 +1033,15 @@ EOTXT; break; } - if (0 === strpos($file[$i], 'namespace ')) { + if (str_starts_with($file[$i], 'namespace ')) { $namespace = substr($file[$i], \strlen('namespace '), -2).'\\'; $useOffset = $i + 2; } - if (0 === strpos($file[$i], 'use ')) { + if (str_starts_with($file[$i], 'use ')) { $useOffset = $i; - for (; 0 === strpos($file[$i], 'use '); ++$i) { + for (; str_starts_with($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 3d9e8b092b..78f94a6f17 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php @@ -143,7 +143,7 @@ class ClassNotFoundErrorEnhancer implements ErrorEnhancerInterface ]; if ($prefix) { - $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); }); + $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return str_starts_with($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 f4c49c2856..2e3838a84d 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedFunctionErrorEnhancer.php @@ -42,7 +42,7 @@ class UndefinedFunctionErrorEnhancer implements ErrorEnhancerInterface $prefix = 'Call to undefined function '; $prefixLen = \strlen($prefix); - if (0 !== strpos($message, $prefix)) { + if (!str_starts_with($message, $prefix)) { return null; } diff --git a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedMethodErrorEnhancer.php b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedMethodErrorEnhancer.php index c4355f92ce..d5eb6d6b1e 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedMethodErrorEnhancer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/UndefinedMethodErrorEnhancer.php @@ -47,7 +47,7 @@ class UndefinedMethodErrorEnhancer implements ErrorEnhancerInterface $candidates = []; foreach ($methods as $definedMethodName) { $lev = levenshtein($methodName, $definedMethodName); - if ($lev <= \strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) { + if ($lev <= \strlen($methodName) / 3 || str_contains($definedMethodName, $methodName)) { $candidates[] = $definedMethodName; } } diff --git a/src/Symfony/Component/ErrorHandler/ErrorHandler.php b/src/Symfony/Component/ErrorHandler/ErrorHandler.php index 1abafc1528..e4d002bca2 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorHandler.php +++ b/src/Symfony/Component/ErrorHandler/ErrorHandler.php @@ -406,7 +406,7 @@ class ErrorHandler */ public function handleError(int $type, string $message, string $file, int $line): bool { - if (\PHP_VERSION_ID >= 70300 && \E_WARNING === $type && '"' === $message[0] && false !== strpos($message, '" targeting switch is equivalent to "break')) { + if (\PHP_VERSION_ID >= 70300 && \E_WARNING === $type && '"' === $message[0] && str_contains($message, '" targeting switch is equivalent to "break')) { $type = \E_DEPRECATED; } @@ -457,7 +457,7 @@ class ErrorHandler return true; } } else { - if (false !== strpos($message, '@anonymous')) { + if (str_contains($message, '@anonymous')) { $backtrace = debug_backtrace(false, 5); for ($i = 1; isset($backtrace[$i]); ++$i) { @@ -566,7 +566,7 @@ class ErrorHandler } if ($this->loggedErrors & $type) { - if (false !== strpos($message = $exception->getMessage(), "@anonymous\0")) { + if (str_contains($message = $exception->getMessage(), "@anonymous\0")) { $message = $this->parseAnonymousClass($message); } @@ -680,7 +680,7 @@ class ErrorHandler $handler->throwAt(0, true); $trace = $error['backtrace'] ?? null; - if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) { + if (str_starts_with($error['message'], 'Allowed memory') || str_starts_with($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 2850293096..53e06f5497 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php @@ -205,7 +205,7 @@ class HtmlErrorRenderer implements ErrorRendererInterface { $file = str_replace('\\', '/', $file); - if (null !== $this->projectDir && 0 === strpos($file, $this->projectDir)) { + if (null !== $this->projectDir && str_starts_with($file, $this->projectDir)) { return ltrim(substr($file, \strlen($this->projectDir)), '/'); } @@ -322,7 +322,7 @@ class HtmlErrorRenderer implements ErrorRendererInterface private function formatLogMessage(string $message, array $context) { - if ($context && false !== strpos($message, '{')) { + if ($context && str_contains($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 bcb31b0f6a..d55df7153c 100644 --- a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php +++ b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php @@ -165,7 +165,7 @@ class FlattenException */ public function setClass(string $class): self { - $this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; + $this->class = str_contains($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; return $this; } @@ -222,7 +222,7 @@ class FlattenException */ public function setMessage(string $message): self { - if (false !== strpos($message, "@anonymous\0")) { + if (str_contains($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 1c66062d6e..78021f2426 100644 --- a/src/Symfony/Component/ErrorHandler/composer.json +++ b/src/Symfony/Component/ErrorHandler/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=7.2.5", "psr/log": "^1|^2|^3", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": { diff --git a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php index 58a5ed9813..3916716ec0 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php +++ b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php @@ -47,7 +47,7 @@ final class WrappedListener $this->pretty = $this->name.'::'.$listener[1]; } elseif ($listener instanceof \Closure) { $r = new \ReflectionFunction($listener); - if (false !== strpos($r->name, '{closure}')) { + if (str_contains($r->name, '{closure}')) { $this->pretty = $this->name = 'closure'; } elseif ($class = $r->getClosureScopeClass()) { $this->name = $class->name; diff --git a/src/Symfony/Component/EventDispatcher/composer.json b/src/Symfony/Component/EventDispatcher/composer.json index a3f12aa43c..72a712aa07 100644 --- a/src/Symfony/Component/EventDispatcher/composer.json +++ b/src/Symfony/Component/EventDispatcher/composer.json @@ -19,7 +19,7 @@ "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", "symfony/event-dispatcher-contracts": "^2", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "symfony/dependency-injection": "^4.4|^5.0", diff --git a/src/Symfony/Component/ExpressionLanguage/Lexer.php b/src/Symfony/Component/ExpressionLanguage/Lexer.php index 6e3cc488b1..a8966f6fa5 100644 --- a/src/Symfony/Component/ExpressionLanguage/Lexer.php +++ b/src/Symfony/Component/ExpressionLanguage/Lexer.php @@ -48,13 +48,13 @@ class Lexer } $tokens[] = new Token(Token::NUMBER_TYPE, $number, $cursor + 1); $cursor += \strlen($match[0]); - } elseif (false !== strpos('([{', $expression[$cursor])) { + } elseif (str_contains('([{', $expression[$cursor])) { // opening bracket $brackets[] = [$expression[$cursor], $cursor]; $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); ++$cursor; - } elseif (false !== strpos(')]}', $expression[$cursor])) { + } elseif (str_contains(')]}', $expression[$cursor])) { // closing bracket if (empty($brackets)) { throw new SyntaxError(sprintf('Unexpected "%s".', $expression[$cursor]), $cursor, $expression); @@ -75,7 +75,7 @@ class Lexer // operators $tokens[] = new Token(Token::OPERATOR_TYPE, $match[0], $cursor + 1); $cursor += \strlen($match[0]); - } elseif (false !== strpos('.,?:', $expression[$cursor])) { + } elseif (str_contains('.,?:', $expression[$cursor])) { // punctuation $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); ++$cursor; diff --git a/src/Symfony/Component/ExpressionLanguage/composer.json b/src/Symfony/Component/ExpressionLanguage/composer.json index 2e75859183..6bc260e4b9 100644 --- a/src/Symfony/Component/ExpressionLanguage/composer.json +++ b/src/Symfony/Component/ExpressionLanguage/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=7.2.5", "symfony/cache": "^4.4|^5.0", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2" }, "autoload": { diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 0345c679bb..935205f54b 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -175,7 +175,7 @@ class Filesystem if (!self::box('rmdir', $file) && file_exists($file)) { throw new IOException(sprintf('Failed to remove directory "%s": ', $file).self::$lastError); } - } elseif (!self::box('unlink', $file) && (false !== strpos(self::$lastError, 'Permission denied') || file_exists($file))) { + } elseif (!self::box('unlink', $file) && (str_contains(self::$lastError, 'Permission denied') || file_exists($file))) { throw new IOException(sprintf('Failed to remove file "%s": ', $file).self::$lastError); } } @@ -368,7 +368,7 @@ class Filesystem private function linkException(string $origin, string $target, string $linkType) { if (self::$lastError) { - if ('\\' === \DIRECTORY_SEPARATOR && false !== strpos(self::$lastError, 'error code(1314)')) { + if ('\\' === \DIRECTORY_SEPARATOR && str_contains(self::$lastError, 'error code(1314)')) { throw new IOException(sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target); } } diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php index 76cfb9f9ff..725870c698 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php @@ -48,7 +48,7 @@ class FilesystemTestCase extends TestCase $targetFile = tempnam(sys_get_temp_dir(), 'li'); if (true !== @link($originFile, $targetFile)) { $report = error_get_last(); - if (\is_array($report) && false !== strpos($report['message'], 'error code(1314)')) { + if (\is_array($report) && str_contains($report['message'], 'error code(1314)')) { self::$linkOnWindows = false; } } else { @@ -60,7 +60,7 @@ class FilesystemTestCase extends TestCase $targetDir = tempnam(sys_get_temp_dir(), 'sl'); if (true !== @symlink($originDir, $targetDir)) { $report = error_get_last(); - if (\is_array($report) && false !== strpos($report['message'], 'error code(1314)')) { + if (\is_array($report) && str_contains($report['message'], 'error code(1314)')) { self::$symlinkOnWindows = false; } } else { diff --git a/src/Symfony/Component/Filesystem/composer.json b/src/Symfony/Component/Filesystem/composer.json index c61b78cc8a..a6c17a1e5f 100644 --- a/src/Symfony/Component/Filesystem/composer.json +++ b/src/Symfony/Component/Filesystem/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.16" }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" }, diff --git a/src/Symfony/Component/Finder/Gitignore.php b/src/Symfony/Component/Finder/Gitignore.php index 304aba9e5a..491f588ee2 100644 --- a/src/Symfony/Component/Finder/Gitignore.php +++ b/src/Symfony/Component/Finder/Gitignore.php @@ -78,6 +78,6 @@ class Gitignore return ($isAbsolute ? '' : '(?:[^/]+/)*') .$regex - .('/' !== substr($gitignoreLine, -1) ? '(?:$|/)' : ''); + .(!str_ends_with($gitignoreLine, '/') ? '(?:$|/)' : ''); } } diff --git a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php index 6a1b291ade..f37431433d 100644 --- a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php @@ -34,7 +34,7 @@ class ExcludeDirectoryFilterIterator extends \FilterIterator implements \Recursi $patterns = []; foreach ($directories as $directory) { $directory = rtrim($directory, '/'); - if (!$this->isRecursive || false !== strpos($directory, '/')) { + if (!$this->isRecursive || str_contains($directory, '/')) { $patterns[] = preg_quote($directory, '#'); } else { $this->excludedDirs[$directory] = true; diff --git a/src/Symfony/Component/Finder/Tests/FinderTest.php b/src/Symfony/Component/Finder/Tests/FinderTest.php index 83e3a01e31..f005433d94 100644 --- a/src/Symfony/Component/Finder/Tests/FinderTest.php +++ b/src/Symfony/Component/Finder/Tests/FinderTest.php @@ -869,7 +869,7 @@ class FinderTest extends Iterator\RealIteratorTestCase public function testFilter() { $finder = $this->buildFinder(); - $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return false !== strpos($f, 'test'); })); + $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return str_contains($f, 'test'); })); $this->assertIterator($this->toAbsolute(['test.php', 'test.py']), $finder->in(self::$tmpDir)->getIterator()); } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php index 4d55b112dc..7c3c65ce5e 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php @@ -37,7 +37,7 @@ class CustomFilterIteratorTest extends IteratorTestCase { return [ [[function (\SplFileInfo $fileinfo) { return false; }], []], - [[function (\SplFileInfo $fileinfo) { return 0 === strpos($fileinfo, 'test'); }], ['test.php', 'test.py']], + [[function (\SplFileInfo $fileinfo) { return str_starts_with($fileinfo, 'test'); }], ['test.php', 'test.py']], [['is_dir'], []], ]; } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php b/src/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php index bc80ed2e1e..028e358452 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php @@ -51,7 +51,7 @@ class MockSplFileInfo extends \SplFileInfo public function isFile(): bool { if (null === $this->type) { - return false !== strpos($this->getFilename(), 'file'); + return str_contains($this->getFilename(), 'file'); } return self::TYPE_FILE === $this->type; @@ -60,7 +60,7 @@ class MockSplFileInfo extends \SplFileInfo public function isDir(): bool { if (null === $this->type) { - return false !== strpos($this->getFilename(), 'directory'); + return str_contains($this->getFilename(), 'directory'); } return self::TYPE_DIRECTORY === $this->type; diff --git a/src/Symfony/Component/Finder/composer.json b/src/Symfony/Component/Finder/composer.json index dc097b3c3a..deccde83be 100644 --- a/src/Symfony/Component/Finder/composer.json +++ b/src/Symfony/Component/Finder/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" }, diff --git a/src/Symfony/Component/Form/Command/DebugCommand.php b/src/Symfony/Component/Form/Command/DebugCommand.php index 3ee7609725..04ed1c140f 100644 --- a/src/Symfony/Component/Form/Command/DebugCommand.php +++ b/src/Symfony/Component/Form/Command/DebugCommand.php @@ -167,7 +167,7 @@ EOF $classes[] = $fqcn; } elseif (class_exists($fqcn = $namespace.'\\'.ucfirst($shortClassName).'Type')) { $classes[] = $fqcn; - } elseif ('type' === substr($shortClassName, -4) && class_exists($fqcn = $namespace.'\\'.ucfirst(substr($shortClassName, 0, -4).'Type'))) { + } elseif (str_ends_with($shortClassName, 'type') && class_exists($fqcn = $namespace.'\\'.ucfirst(substr($shortClassName, 0, -4).'Type'))) { $classes[] = $fqcn; } } @@ -230,7 +230,7 @@ EOF $alternatives = []; foreach ($collection as $item) { $lev = levenshtein($name, $item); - if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) { + if ($lev <= \strlen($name) / 3 || str_contains($item, $name)) { $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; } } diff --git a/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php b/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php index 7dbc214ca6..504dbe45ed 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php +++ b/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php @@ -102,7 +102,7 @@ class PropertyPathMapper implements DataMapperInterface } catch (AccessException $e) { if (!$e instanceof UninitializedPropertyException // For versions without UninitializedPropertyException check the exception message - && (class_exists(UninitializedPropertyException::class) || false === strpos($e->getMessage(), 'You should initialize it')) + && (class_exists(UninitializedPropertyException::class) || !str_contains($e->getMessage(), 'You should initialize it')) ) { throw $e; } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php index a8f81bb8a8..52565f3879 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php @@ -62,7 +62,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer // where the time corresponds to the current server time. // With "|" and "Y-m-d", "2010-02-03" becomes "2010-02-03 00:00:00", // which is at least deterministic and thus used here. - if (false === strpos($this->parseFormat, '|')) { + if (!str_contains($this->parseFormat, '|')) { $this->parseFormat .= '|'; } } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php index 2439e676c7..1ba9140626 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php @@ -40,7 +40,7 @@ class IntegerToLocalizedStringTransformer extends NumberToLocalizedStringTransfo { $decimalSeparator = $this->getNumberFormatter()->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); - if (\is_string($value) && false !== strpos($value, $decimalSeparator)) { + if (\is_string($value) && str_contains($value, $decimalSeparator)) { throw new TransformationFailedException(sprintf('The value "%s" is not a valid integer.', $value)); } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php index 1f0426033e..f658dc2f93 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php @@ -143,7 +143,7 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface $value = str_replace(',', $decSep, $value); } - if (false !== strpos($value, $decSep)) { + if (str_contains($value, $decSep)) { $type = \NumberFormatter::TYPE_DOUBLE; } else { $type = \PHP_INT_SIZE === 8 diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php index 09861d6d06..40c4a3f78a 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php @@ -133,7 +133,7 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface $value = str_replace(',', $decSep, $value); } - if (false !== strpos($value, $decSep)) { + if (str_contains($value, $decSep)) { $type = \NumberFormatter::TYPE_DOUBLE; } else { $type = \PHP_INT_SIZE === 8 ? \NumberFormatter::TYPE_INT64 : \NumberFormatter::TYPE_INT32; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index b28a3f5e9d..1a46a8084d 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -58,7 +58,7 @@ class DateType extends AbstractType } if ('single_text' === $options['widget']) { - if ('' !== $pattern && false === strpos($pattern, 'y') && false === strpos($pattern, 'M') && false === strpos($pattern, 'd')) { + if ('' !== $pattern && !str_contains($pattern, 'y') && !str_contains($pattern, 'M') && !str_contains($pattern, 'd')) { throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M" or "d". Its current value is "%s".', $pattern)); } @@ -71,7 +71,7 @@ class DateType extends AbstractType $pattern )); } else { - if ('' !== $pattern && (false === strpos($pattern, 'y') || false === strpos($pattern, 'M') || false === strpos($pattern, 'd'))) { + if ('' !== $pattern && (!str_contains($pattern, 'y') || !str_contains($pattern, 'M') || !str_contains($pattern, 'd'))) { throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M" and "d". Its current value is "%s".', $pattern)); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index fc7091bad8..36e23ec2a6 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -188,9 +188,9 @@ class FileType extends AbstractType } $max = ltrim($iniMax, '+'); - if (0 === strpos($max, '0x')) { + if (str_starts_with($max, '0x')) { $max = \intval($max, 16); - } elseif (0 === strpos($max, '0')) { + } elseif (str_starts_with($max, '0')) { $max = \intval($max, 8); } else { $max = (int) $max; diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php index 1982e85d8b..88dbf9b2b4 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php +++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php @@ -267,7 +267,7 @@ class ViolationMapper implements ViolationMapperInterface if ($childPath === $chunk) { $target = $child; $foundAtIndex = $it->key(); - } elseif (0 === strpos($childPath, $chunk)) { + } elseif (str_starts_with($childPath, $chunk)) { continue; } diff --git a/src/Symfony/Component/Form/Util/ServerParams.php b/src/Symfony/Component/Form/Util/ServerParams.php index 08b9d690c7..b6ce9d1065 100644 --- a/src/Symfony/Component/Form/Util/ServerParams.php +++ b/src/Symfony/Component/Form/Util/ServerParams.php @@ -52,9 +52,9 @@ class ServerParams } $max = ltrim($iniMax, '+'); - if (0 === strpos($max, '0x')) { + if (str_starts_with($max, '0x')) { $max = \intval($max, 16); - } elseif (0 === strpos($max, '0')) { + } elseif (str_starts_with($max, '0')) { $max = \intval($max, 8); } else { $max = (int) $max; diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index b4ac5bb8bc..aa92b7f260 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -23,7 +23,7 @@ "symfony/options-resolver": "^5.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/property-access": "^5.0.8", "symfony/service-contracts": "^1.1|^2" }, diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 2e9bb23429..5e6094c378 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -272,7 +272,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, if ($options['bindto']) { if (file_exists($options['bindto'])) { $curlopts[\CURLOPT_UNIX_SOCKET_PATH] = $options['bindto']; - } elseif (0 !== strpos($options['bindto'], 'if!') && preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) { + } elseif (!str_starts_with($options['bindto'], 'if!') && preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) { $curlopts[\CURLOPT_INTERFACE] = $matches[1]; $curlopts[\CURLOPT_LOCALPORT] = $matches[2]; } else { @@ -404,7 +404,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, // curl before 7.65 doesn't validate the pushed ":authority" header, // but this is a MUST in the HTTP/2 RFC; let's restrict pushes to the original host, // ignoring domains mentioned as alt-name in the certificate for now (same as curl). - if (0 !== strpos($origin, $url.'/')) { + if (!str_starts_with($origin, $url.'/')) { $this->logger && $this->logger->debug(sprintf('Rejecting pushed response from "%s": server is not authoritative for "%s"', $origin, $url)); return \CURL_PUSH_DENY; @@ -515,7 +515,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, private function findConstantName(int $opt): ?string { $constants = array_filter(get_defined_constants(), static function ($v, $k) use ($opt) { - return $v === $opt && 'C' === $k[0] && (0 === strpos($k, 'CURLOPT_') || 0 === strpos($k, 'CURLINFO_')); + return $v === $opt && 'C' === $k[0] && (str_starts_with($k, 'CURLOPT_') || str_starts_with($k, 'CURLINFO_')); }, \ARRAY_FILTER_USE_BOTH); return key($constants); diff --git a/src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php b/src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php index 5b7b448307..7ab27524fa 100644 --- a/src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php +++ b/src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php @@ -32,7 +32,7 @@ trait HttpExceptionTrait $httpCodeFound = false; $isJson = false; foreach (array_reverse($response->getInfo('response_headers')) as $h) { - if (0 === strpos($h, 'HTTP/')) { + if (str_starts_with($h, 'HTTP/')) { if ($httpCodeFound) { break; } diff --git a/src/Symfony/Component/HttpClient/HttpClientTrait.php b/src/Symfony/Component/HttpClient/HttpClientTrait.php index 4db3a3ca8a..c67c1c1587 100644 --- a/src/Symfony/Component/HttpClient/HttpClientTrait.php +++ b/src/Symfony/Component/HttpClient/HttpClientTrait.php @@ -216,7 +216,7 @@ trait HttpClientTrait $alternatives = []; foreach ($defaultOptions as $key => $v) { - if (levenshtein($name, $key) <= \strlen($name) / 3 || false !== strpos($key, $name)) { + if (levenshtein($name, $key) <= \strlen($name) / 3 || str_contains($key, $name)) { $alternatives[] = $key; } } @@ -479,7 +479,7 @@ trait HttpClientTrait continue; } - if (false !== strpos($parts[$part], '%')) { + if (str_contains($parts[$part], '%')) { // https://tools.ietf.org/html/rfc3986#section-2.3 $parts[$part] = preg_replace_callback('/%(?:2[DE]|3[0-9]|[46][1-9A-F]|5F|[57][0-9A]|7E)++/i', function ($m) { return rawurldecode($m[0]); }, $parts[$part]); } @@ -507,11 +507,11 @@ trait HttpClientTrait $result = ''; while (!\in_array($path, ['', '.', '..'], true)) { - if ('.' === $path[0] && (0 === strpos($path, $p = '../') || 0 === strpos($path, $p = './'))) { + if ('.' === $path[0] && (str_starts_with($path, $p = '../') || str_starts_with($path, $p = './'))) { $path = substr($path, \strlen($p)); - } elseif ('/.' === $path || 0 === strpos($path, '/./')) { + } elseif ('/.' === $path || str_starts_with($path, '/./')) { $path = substr_replace($path, '/', 0, 3); - } elseif ('/..' === $path || 0 === strpos($path, '/../')) { + } elseif ('/..' === $path || str_starts_with($path, '/../')) { $i = strrpos($result, '/'); $result = $i ? substr($result, 0, $i) : ''; $path = substr_replace($path, '/', 0, 4); diff --git a/src/Symfony/Component/HttpClient/NativeHttpClient.php b/src/Symfony/Component/HttpClient/NativeHttpClient.php index 4f922ac8f6..b0910cf784 100644 --- a/src/Symfony/Component/HttpClient/NativeHttpClient.php +++ b/src/Symfony/Component/HttpClient/NativeHttpClient.php @@ -71,10 +71,10 @@ final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterfac if (file_exists($options['bindto'])) { throw new TransportException(__CLASS__.' cannot bind to local Unix sockets, use e.g. CurlHttpClient instead.'); } - if (0 === strpos($options['bindto'], 'if!')) { + if (str_starts_with($options['bindto'], 'if!')) { throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.'); } - if (0 === strpos($options['bindto'], 'host!')) { + if (str_starts_with($options['bindto'], 'host!')) { $options['bindto'] = substr($options['bindto'], 5); } } @@ -423,7 +423,7 @@ final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterfac foreach ($proxy['no_proxy'] as $rule) { $dotRule = '.'.ltrim($rule, '.'); - if ('*' === $rule || $host === $rule || substr($host, -\strlen($dotRule)) === $dotRule) { + if ('*' === $rule || $host === $rule || str_ends_with($host, $dotRule)) { stream_context_set_option($context, 'http', 'proxy', null); stream_context_set_option($context, 'http', 'request_fulluri', false); stream_context_set_option($context, 'http', 'header', $requestHeaders); diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 73760400dd..a645a5ff3e 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -381,7 +381,7 @@ final class CurlResponse implements ResponseInterface, StreamableInterface return \strlen($data); } - if (0 !== strpos($data, 'HTTP/')) { + if (!str_starts_with($data, 'HTTP/')) { if (0 === stripos($data, 'Location:')) { $location = trim(substr($data, 9)); } diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index 0227de9a17..7528d50496 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -18,14 +18,15 @@ "php-http/async-client-implementation": "*", "php-http/client-implementation": "*", "psr/http-client-implementation": "1.0", - "symfony/http-client-implementation": "2.2" + "symfony/http-client-implementation": "2.2", + "symfony/polyfill-php80": "^1.16" }, "require": { "php": ">=7.2.5", "psr/log": "^1|^2|^3", "symfony/http-client-contracts": "^2.2", "symfony/polyfill-php73": "^1.11", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.0|^2" }, "require-dev": { diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index b41d31eca3..9432b59964 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -160,7 +160,7 @@ class BinaryFileResponse extends Response $filename = $this->file->getFilename(); } - if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || false !== strpos($filename, '%'))) { + if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || str_contains($filename, '%'))) { $encoding = mb_detect_encoding($filename, null, true) ?: '8bit'; for ($i = 0, $filenameLength = mb_strlen($filename, $encoding); $i < $filenameLength; ++$i) { @@ -240,7 +240,7 @@ class BinaryFileResponse extends Response if (!$request->headers->has('If-Range') || $this->hasValidIfRangeHeader($request->headers->get('If-Range'))) { $range = $request->headers->get('Range'); - if (0 === strpos($range, 'bytes=')) { + if (str_starts_with($range, 'bytes=')) { [$start, $end] = explode('-', substr($range, 6), 2) + [0]; $end = ('' === $end) ? $fileSize - 1 : (int) $end; diff --git a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php index 8aa2f03a33..e07ef6c591 100644 --- a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php +++ b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php @@ -240,9 +240,9 @@ class UploadedFile extends File $size = strtolower($size); $max = ltrim($size, '+'); - if (0 === strpos($max, '0x')) { + if (str_starts_with($max, '0x')) { $max = \intval($max, 16); - } elseif (0 === strpos($max, '0')) { + } elseif (str_starts_with($max, '0')) { $max = \intval($max, 8); } else { $max = (int) $max; diff --git a/src/Symfony/Component/HttpFoundation/HeaderUtils.php b/src/Symfony/Component/HttpFoundation/HeaderUtils.php index 1824ac336d..8ef870284d 100644 --- a/src/Symfony/Component/HttpFoundation/HeaderUtils.php +++ b/src/Symfony/Component/HttpFoundation/HeaderUtils.php @@ -176,12 +176,12 @@ class HeaderUtils } // percent characters aren't safe in fallback. - if (false !== strpos($filenameFallback, '%')) { + if (str_contains($filenameFallback, '%')) { throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.'); } // path separators aren't allowed in either. - if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) { + if (str_contains($filename, '/') || str_contains($filename, '\\') || str_contains($filenameFallback, '/') || str_contains($filenameFallback, '\\')) { throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.'); } diff --git a/src/Symfony/Component/HttpFoundation/IpUtils.php b/src/Symfony/Component/HttpFoundation/IpUtils.php index 27fe725929..68426f5b0b 100644 --- a/src/Symfony/Component/HttpFoundation/IpUtils.php +++ b/src/Symfony/Component/HttpFoundation/IpUtils.php @@ -70,7 +70,7 @@ class IpUtils return self::$checkedIps[$cacheKey] = false; } - if (false !== strpos($ip, '/')) { + if (str_contains($ip, '/')) { [$address, $netmask] = explode('/', $ip, 2); if ('0' === $netmask) { @@ -117,7 +117,7 @@ class IpUtils throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".'); } - if (false !== strpos($ip, '/')) { + if (str_contains($ip, '/')) { [$address, $netmask] = explode('/', $ip, 2); if ('0' === $netmask) { diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 5d73c6faed..501a6387d9 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -157,7 +157,7 @@ class JsonResponse extends Response try { $data = json_encode($data, $this->encodingOptions); } catch (\Exception $e) { - if ('Exception' === \get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { + if ('Exception' === \get_class($e) && str_starts_with($e->getMessage(), 'Failed calling ')) { throw $e->getPrevious() ?: $e; } throw $e; diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 365c334506..8cd3d06629 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -306,7 +306,7 @@ class Request if ($_POST) { $request->request = new InputBag($_POST); - } elseif (0 === strpos($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded') + } elseif (str_starts_with($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded') && \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH']) ) { parse_str($request->getContent(), $data); @@ -1683,7 +1683,7 @@ class Request $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all(); $this->languages = []; foreach ($languages as $lang => $acceptHeaderItem) { - if (false !== strpos($lang, '-')) { + if (str_contains($lang, '-')) { $codes = explode('-', $lang); if ('i' === $codes[0]) { // Language not listed in ISO 639 that are not variants @@ -2008,7 +2008,7 @@ class Request */ private function getUrlencodedPrefix(string $string, string $prefix): ?string { - if (0 !== strpos(rawurldecode($string), $prefix)) { + if (!str_starts_with(rawurldecode($string), $prefix)) { return null; } @@ -2070,7 +2070,7 @@ class Request continue; } if (self::HEADER_X_FORWARDED_PORT === $type) { - if (']' === substr($v, -1) || false === $v = strrchr($v, ':')) { + if (str_ends_with($v, ']') || false === $v = strrchr($v, ':')) { $v = $this->isSecure() ? ':443' : ':80'; } $v = '0.0.0.0'.$v; @@ -2116,7 +2116,7 @@ class Request if ($i) { $clientIps[$key] = $clientIp = substr($clientIp, 0, $i); } - } elseif (0 === strpos($clientIp, '[')) { + } elseif (str_starts_with($clientIp, '[')) { // Strip brackets and :port from IPv6 addresses. $i = strpos($clientIp, ']', 1); $clientIps[$key] = $clientIp = substr($clientIp, 1, $i - 1); diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index ae1546a115..3ebc4378b5 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -324,7 +324,7 @@ class Response } // Check if we need to send extra expire info headers - if ('1.0' == $this->getProtocolVersion() && false !== strpos($headers->get('Cache-Control'), 'no-cache')) { + if ('1.0' == $this->getProtocolVersion() && str_contains($headers->get('Cache-Control'), 'no-cache')) { $headers->set('pragma', 'no-cache'); $headers->set('expires', -1); } @@ -926,7 +926,7 @@ class Response if (null === $etag) { $this->headers->remove('Etag'); } else { - if (0 !== strpos($etag, '"')) { + if (!str_starts_with($etag, '"')) { $etag = '"'.$etag.'"'; } diff --git a/src/Symfony/Component/HttpFoundation/ServerBag.php b/src/Symfony/Component/HttpFoundation/ServerBag.php index 5e1094d5fe..7af111c865 100644 --- a/src/Symfony/Component/HttpFoundation/ServerBag.php +++ b/src/Symfony/Component/HttpFoundation/ServerBag.php @@ -29,7 +29,7 @@ class ServerBag extends ParameterBag { $headers = []; foreach ($this->parameters as $key => $value) { - if (0 === strpos($key, 'HTTP_')) { + if (str_starts_with($key, 'HTTP_')) { $headers[substr($key, 5)] = $value; } elseif (\in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH', 'CONTENT_MD5'], true)) { $headers[$key] = $value; diff --git a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php index 7e752ddaa7..1092f98ba6 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php +++ b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php @@ -102,7 +102,7 @@ class NamespacedAttributeBag extends AttributeBag protected function &resolveAttributePath(string $name, bool $writeContext = false) { $array = &$this->attributes; - $name = (0 === strpos($name, $this->namespaceCharacter)) ? substr($name, 1) : $name; + $name = (str_starts_with($name, $this->namespaceCharacter)) ? substr($name, 1) : $name; // Check if there is anything to do, else return if (!$name) { diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index 0e6ae58225..31b208493d 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -179,7 +179,7 @@ class PdoSessionHandler extends AbstractSessionHandler $this->pdo = $pdoOrDsn; $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); - } elseif (\is_string($pdoOrDsn) && false !== strpos($pdoOrDsn, '://')) { + } elseif (\is_string($pdoOrDsn) && str_contains($pdoOrDsn, '://')) { $this->dsn = $this->buildDsnFromUrl($pdoOrDsn); } else { $this->dsn = $pdoOrDsn; @@ -353,7 +353,7 @@ class PdoSessionHandler extends AbstractSessionHandler $insertStmt->execute(); } catch (\PDOException $e) { // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys - if (0 === strpos($e->getCode(), '23')) { + if (str_starts_with($e->getCode(), '23')) { $updateStmt->execute(); } else { throw $e; @@ -487,7 +487,7 @@ class PdoSessionHandler extends AbstractSessionHandler $driver = $driverAliasMap[$params['scheme']] ?? $params['scheme']; // Doctrine DBAL supports passing its internal pdo_* driver names directly too (allowing both dashes and underscores). This allows supporting the same here. - if (0 === strpos($driver, 'pdo_') || 0 === strpos($driver, 'pdo-')) { + if (str_starts_with($driver, 'pdo_') || str_starts_with($driver, 'pdo-')) { $driver = substr($driver, 4); } @@ -659,7 +659,7 @@ class PdoSessionHandler extends AbstractSessionHandler } catch (\PDOException $e) { // Catch duplicate key error because other connection created the session already. // It would only not be the case when the other connection destroyed the session. - if (0 === strpos($e->getCode(), '23')) { + if (str_starts_with($e->getCode(), '23')) { // Retrieve finished session data written by concurrent connection by restarting the loop. // We have to start a new transaction as a failed query will mark the current transaction as // aborted in PostgreSQL and disallow further queries within it. diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php index 93e403777a..b032c136e5 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php @@ -47,38 +47,38 @@ class SessionHandlerFactory case !\is_string($connection): throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', get_debug_type($connection))); - case 0 === strpos($connection, 'file://'): + case str_starts_with($connection, 'file://'): $savePath = substr($connection, 7); return new StrictSessionHandler(new NativeFileSessionHandler('' === $savePath ? null : $savePath)); - case 0 === strpos($connection, 'redis:'): - case 0 === strpos($connection, 'rediss:'): - case 0 === strpos($connection, 'memcached:'): + case str_starts_with($connection, 'redis:'): + case str_starts_with($connection, 'rediss:'): + case str_starts_with($connection, 'memcached:'): if (!class_exists(AbstractAdapter::class)) { throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection)); } - $handlerClass = 0 === strpos($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class; + $handlerClass = str_starts_with($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class; $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); return new $handlerClass($connection); - case 0 === strpos($connection, 'pdo_oci://'): + case str_starts_with($connection, 'pdo_oci://'): if (!class_exists(DriverManager::class)) { throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require doctrine/dbal".', $connection)); } $connection = DriverManager::getConnection(['url' => $connection])->getWrappedConnection(); // no break; - case 0 === strpos($connection, 'mssql://'): - case 0 === strpos($connection, 'mysql://'): - case 0 === strpos($connection, 'mysql2://'): - case 0 === strpos($connection, 'pgsql://'): - case 0 === strpos($connection, 'postgres://'): - case 0 === strpos($connection, 'postgresql://'): - case 0 === strpos($connection, 'sqlsrv://'): - case 0 === strpos($connection, 'sqlite://'): - case 0 === strpos($connection, 'sqlite3://'): + case str_starts_with($connection, 'mssql://'): + case str_starts_with($connection, 'mysql://'): + case str_starts_with($connection, 'mysql2://'): + case str_starts_with($connection, 'pgsql://'): + case str_starts_with($connection, 'postgres://'): + case str_starts_with($connection, 'postgresql://'): + case str_starts_with($connection, 'sqlsrv://'): + case str_starts_with($connection, 'sqlite://'): + case str_starts_with($connection, 'sqlite3://'): return new PdoSessionHandler($connection); } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index b96521f754..16a7a3d167 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -256,7 +256,7 @@ class NativeSessionStorage implements SessionStorageInterface // Register error handler to add information about the current save handler $previousHandler = set_error_handler(function ($type, $msg, $file, $line) use (&$previousHandler) { - if (\E_WARNING === $type && 0 === strpos($msg, 'session_write_close():')) { + if (\E_WARNING === $type && str_starts_with($msg, 'session_write_close():')) { $handler = $this->saveHandler instanceof SessionHandlerProxy ? $this->saveHandler->getHandler() : $this->saveHandler; $msg = sprintf('session_write_close(): Failed to write session data with "%s" handler', \get_class($handler)); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index 79ab73c1a4..408ce32f33 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -156,7 +156,7 @@ class PdoSessionHandlerTest extends TestCase $insertStmt = $this->createMock(\PDOStatement::class); $pdo->prepareResult = function ($statement) use ($selectStmt, $insertStmt) { - return 0 === strpos($statement, 'INSERT') ? $insertStmt : $selectStmt; + return str_starts_with($statement, 'INSERT') ? $insertStmt : $selectStmt; }; $content = 'foobar'; diff --git a/src/Symfony/Component/HttpFoundation/UrlHelper.php b/src/Symfony/Component/HttpFoundation/UrlHelper.php index f114c0a9fb..3fe053ddbb 100644 --- a/src/Symfony/Component/HttpFoundation/UrlHelper.php +++ b/src/Symfony/Component/HttpFoundation/UrlHelper.php @@ -31,7 +31,7 @@ final class UrlHelper public function getAbsoluteUrl(string $path): string { - if (false !== strpos($path, '://') || '//' === substr($path, 0, 2)) { + if (str_contains($path, '://') || '//' === substr($path, 0, 2)) { return $path; } @@ -60,7 +60,7 @@ final class UrlHelper public function getRelativePath(string $path): string { - if (false !== strpos($path, '://') || '//' === substr($path, 0, 2)) { + if (str_contains($path, '://') || '//' === substr($path, 0, 2)) { return $path; } diff --git a/src/Symfony/Component/HttpFoundation/composer.json b/src/Symfony/Component/HttpFoundation/composer.json index 4137f21dd5..adac6e152c 100644 --- a/src/Symfony/Component/HttpFoundation/composer.json +++ b/src/Symfony/Component/HttpFoundation/composer.json @@ -19,7 +19,7 @@ "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "predis/predis": "~1.0", diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index 300ee020c2..b4211e27c9 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -104,7 +104,7 @@ class ControllerResolver implements ControllerResolverInterface */ protected function createController(string $controller) { - if (false === strpos($controller, '::')) { + if (!str_contains($controller, '::')) { $controller = $this->instantiateController($controller); if (!\is_callable($controller)) { @@ -150,7 +150,7 @@ class ControllerResolver implements ControllerResolverInterface private function getControllerError($callable): string { if (\is_string($callable)) { - if (false !== strpos($callable, '::')) { + if (str_contains($callable, '::')) { $callable = explode('::', $callable, 2); } else { return sprintf('Function "%s" does not exist.', $callable); @@ -191,7 +191,7 @@ class ControllerResolver implements ControllerResolverInterface foreach ($collection as $item) { $lev = levenshtein($method, $item); - if ($lev <= \strlen($method) / 3 || false !== strpos($item, $method)) { + if ($lev <= \strlen($method) / 3 || str_contains($item, $method)) { $alternatives[] = $item; } } diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php index ca81714771..a05e68319e 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -115,11 +115,11 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface if (!$this->requestStack || !$response->headers->has('X-Debug-Token') || $response->isRedirection() - || ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html')) + || ($response->headers->has('Content-Type') && !str_contains($response->headers->get('Content-Type'), 'html')) || 'html' !== $request->getRequestFormat() || false === strripos($response->getContent(), '') ) { - if ($response->headers->has('Content-Type') && false !== strpos($response->headers->get('Content-Type'), 'html')) { + if ($response->headers->has('Content-Type') && str_contains($response->headers->get('Content-Type'), 'html')) { $dumper = new HtmlDumper('php://output', $this->charset); $dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]); } else { diff --git a/src/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php index 37302128ad..7db4b807a6 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php @@ -102,9 +102,9 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte $memoryLimit = strtolower($memoryLimit); $max = strtolower(ltrim($memoryLimit, '+')); - if (0 === strpos($max, '0x')) { + if (str_starts_with($max, '0x')) { $max = \intval($max, 16); - } elseif (0 === strpos($max, '0')) { + } elseif (str_starts_with($max, '0')) { $max = \intval($max, 8); } else { $max = (int) $max; diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index 425715669e..a4fef9e55f 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -439,7 +439,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter */ protected function parseController($controller) { - if (\is_string($controller) && false !== strpos($controller, '::')) { + if (\is_string($controller) && str_contains($controller, '::')) { $controller = explode('::', $controller); } @@ -476,7 +476,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter 'line' => $r->getStartLine(), ]; - if (false !== strpos($r->name, '{closure}')) { + if (str_contains($r->name, '{closure}')) { return $controller; } $controller['method'] = $r->name; diff --git a/src/Symfony/Component/HttpKernel/Debug/FileLinkFormatter.php b/src/Symfony/Component/HttpKernel/Debug/FileLinkFormatter.php index 8ac5fd6d81..112985b318 100644 --- a/src/Symfony/Component/HttpKernel/Debug/FileLinkFormatter.php +++ b/src/Symfony/Component/HttpKernel/Debug/FileLinkFormatter.php @@ -50,7 +50,7 @@ class FileLinkFormatter { if ($fmt = $this->getFileLinkFormat()) { for ($i = 1; isset($fmt[$i]); ++$i) { - if (0 === strpos($file, $k = $fmt[$i++])) { + if (str_starts_with($file, $k = $fmt[$i++])) { $file = substr_replace($file, $fmt[$i], 0, \strlen($k)); break; } diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/AddAnnotatedClassesToCachePass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/AddAnnotatedClassesToCachePass.php index 5eb833b51d..9825151ab0 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/AddAnnotatedClassesToCachePass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/AddAnnotatedClassesToCachePass.php @@ -62,7 +62,7 @@ class AddAnnotatedClassesToCachePass implements CompilerPassInterface // Explicit classes declared in the patterns are returned directly foreach ($patterns as $key => $pattern) { - if ('\\' !== substr($pattern, -1) && false === strpos($pattern, '*')) { + if (!str_ends_with($pattern, '\\') && !str_contains($pattern, '*')) { unset($patterns[$key]); $expanded[] = ltrim($pattern, '\\'); } @@ -127,10 +127,10 @@ class AddAnnotatedClassesToCachePass implements CompilerPassInterface private function matchAnyRegexps(string $class, array $regexps): bool { - $isTest = false !== strpos($class, 'Test'); + $isTest = str_contains($class, 'Test'); foreach ($regexps as $regex) { - if ($isTest && false === strpos($regex, 'Test')) { + if ($isTest && !str_contains($regex, 'Test')) { continue; } diff --git a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php index 19d13b8c46..e39e7b3524 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php @@ -81,7 +81,7 @@ abstract class AbstractTestSessionListener implements EventSubscriberInterface if ($session instanceof Session ? !$session->isEmpty() || (null !== $this->sessionId && $session->getId() !== $this->sessionId) : $wasStarted) { $params = session_get_cookie_params() + ['samesite' => null]; foreach ($this->sessionOptions as $k => $v) { - if (0 === strpos($k, 'cookie_')) { + if (str_starts_with($k, 'cookie_')) { $params[substr($k, 7)] = $v; } } diff --git a/src/Symfony/Component/HttpKernel/Exception/ControllerDoesNotReturnResponseException.php b/src/Symfony/Component/HttpKernel/Exception/ControllerDoesNotReturnResponseException.php index 1e87690ff1..54c80be90f 100644 --- a/src/Symfony/Component/HttpKernel/Exception/ControllerDoesNotReturnResponseException.php +++ b/src/Symfony/Component/HttpKernel/Exception/ControllerDoesNotReturnResponseException.php @@ -38,7 +38,7 @@ class ControllerDoesNotReturnResponseException extends \LogicException private function parseControllerDefinition(callable $controller): ?array { - if (\is_string($controller) && false !== strpos($controller, '::')) { + if (\is_string($controller) && str_contains($controller, '::')) { $controller = explode('::', $controller); } diff --git a/src/Symfony/Component/HttpKernel/HttpCache/AbstractSurrogate.php b/src/Symfony/Component/HttpKernel/HttpCache/AbstractSurrogate.php index bcfa13446a..54d0dc9163 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/AbstractSurrogate.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/AbstractSurrogate.php @@ -57,7 +57,7 @@ abstract class AbstractSurrogate implements SurrogateInterface return false; } - return false !== strpos($value, sprintf('%s/1.0', strtoupper($this->getName()))); + return str_contains($value, sprintf('%s/1.0', strtoupper($this->getName()))); } /** diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php index 4a1626eca0..cd6a00a10d 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php @@ -37,7 +37,7 @@ class Esi extends AbstractSurrogate */ public function addSurrogateControl(Response $response) { - if (false !== strpos($response->getContent(), 'getContent(), 'headers->set('Surrogate-Control', 'content="ESI/1.0"'); } } diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Ssi.php b/src/Symfony/Component/HttpKernel/HttpCache/Ssi.php index 0ba351dd12..f114e05cfb 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/Ssi.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/Ssi.php @@ -34,7 +34,7 @@ class Ssi extends AbstractSurrogate */ public function addSurrogateControl(Response $response) { - if (false !== strpos($response->getContent(), '