minor #41973 Leverage str_ends_with (Tobion)

This PR was merged into the 4.4 branch.

Discussion
----------

Leverage str_ends_with

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       |
| License       | MIT
| Doc PR        |

added the php80 polyfill to requirements when necessary. some components already had the requirement anyway.
Related to #41576

Commits
-------

9d807298be Leverage str_ends_with
This commit is contained in:
Nicolas Grekas 2021-07-21 14:12:37 +02:00
commit a5675d3599
66 changed files with 80 additions and 62 deletions

View File

@ -96,7 +96,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); $message = sprintf('No extensions with configuration available for "%s".', $name);
} else { } else {
$message = sprintf('No extension with alias "%s" is enabled.', $name); $message = sprintf('No extension with alias "%s" is enabled.', $name);

View File

@ -81,7 +81,7 @@ EOF
$realCacheDir = $kernel->getContainer()->getParameter('kernel.cache_dir'); $realCacheDir = $kernel->getContainer()->getParameter('kernel.cache_dir');
// the old cache dir name must not be longer than the real one to avoid exceeding // 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) // 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); $fs->remove($oldCacheDir);
if (!is_writable($realCacheDir)) { if (!is_writable($realCacheDir)) {

View File

@ -25,6 +25,7 @@
"symfony/http-foundation": "^4.4|^5.0", "symfony/http-foundation": "^4.4|^5.0",
"symfony/http-kernel": "^4.4", "symfony/http-kernel": "^4.4",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.16",
"symfony/filesystem": "^3.4|^4.0|^5.0", "symfony/filesystem": "^3.4|^4.0|^5.0",
"symfony/finder": "^3.4|^4.0|^5.0", "symfony/finder": "^3.4|^4.0|^5.0",
"symfony/routing": "^4.4.12|^5.1.4" "symfony/routing": "^4.4.12|^5.1.4"

View File

@ -201,7 +201,7 @@ class TwigExtension extends Extension
private function normalizeBundleName(string $name): string private function normalizeBundleName(string $name): string
{ {
if ('Bundle' === substr($name, -6)) { if (str_ends_with($name, 'Bundle')) {
$name = substr($name, 0, -6); $name = substr($name, 0, -6);
} }

View File

@ -61,7 +61,7 @@ class TemplateIterator implements \IteratorAggregate
} }
foreach ($this->kernel->getBundles() as $bundle) { foreach ($this->kernel->getBundles() as $bundle) {
$name = $bundle->getName(); $name = $bundle->getName();
if ('Bundle' === substr($name, -6)) { if (str_ends_with($name, 'Bundle')) {
$name = substr($name, 0, -6); $name = substr($name, 0, -6);
} }

View File

@ -21,6 +21,7 @@
"symfony/http-foundation": "^4.3|^5.0", "symfony/http-foundation": "^4.3|^5.0",
"symfony/http-kernel": "^4.4", "symfony/http-kernel": "^4.4",
"symfony/polyfill-ctype": "~1.8", "symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-php80": "^1.16",
"twig/twig": "^1.43|^2.13|^3.0.4" "twig/twig": "^1.43|^2.13|^3.0.4"
}, },
"require-dev": { "require-dev": {

View File

@ -221,7 +221,7 @@ class ContentSecurityPolicyHandler
private function hasHashOrNonce(array $directives): bool private function hasHashOrNonce(array $directives): bool
{ {
foreach ($directives as $directive) { foreach ($directives as $directive) {
if ('\'' !== substr($directive, -1)) { if (!str_ends_with($directive, '\'')) {
continue; continue;
} }
if ('\'nonce-' === substr($directive, 0, 7)) { if ('\'nonce-' === substr($directive, 0, 7)) {

View File

@ -82,7 +82,7 @@ class TemplateManager
continue; continue;
} }
if ('.html.twig' === substr($template, -10)) { if (str_ends_with($template, '.html.twig')) {
$template = substr($template, 0, -10); $template = substr($template, 0, -10);
} }

View File

@ -20,6 +20,7 @@
"symfony/config": "^4.2|^5.0", "symfony/config": "^4.2|^5.0",
"symfony/framework-bundle": "^4.4|^5.0", "symfony/framework-bundle": "^4.4|^5.0",
"symfony/http-kernel": "^4.4", "symfony/http-kernel": "^4.4",
"symfony/polyfill-php80": "^1.16",
"symfony/routing": "^4.3|^5.0", "symfony/routing": "^4.3|^5.0",
"symfony/twig-bundle": "^4.2|^5.0", "symfony/twig-bundle": "^4.2|^5.0",
"twig/twig": "^1.43|^2.13|^3.0.4" "twig/twig": "^1.43|^2.13|^3.0.4"

View File

@ -688,7 +688,7 @@ abstract class Client
if ('/' !== $uri[0]) { if ('/' !== $uri[0]) {
$path = parse_url($currentUri, \PHP_URL_PATH); $path = parse_url($currentUri, \PHP_URL_PATH);
if ('/' !== substr($path, -1)) { if (!str_ends_with($path, '/')) {
$path = substr($path, 0, strrpos($path, '/') + 1); $path = substr($path, 0, strrpos($path, '/') + 1);
} }

View File

@ -46,7 +46,7 @@ class CookieJar
foreach ($this->cookieJar as $cookieDomain => $pathCookies) { foreach ($this->cookieJar as $cookieDomain => $pathCookies) {
if ($cookieDomain && $domain) { if ($cookieDomain && $domain) {
$cookieDomain = '.'.ltrim($cookieDomain, '.'); $cookieDomain = '.'.ltrim($cookieDomain, '.');
if ($cookieDomain !== substr('.'.$domain, -\strlen($cookieDomain))) { if (!str_ends_with('.'.$domain, $cookieDomain)) {
continue; continue;
} }
} }

View File

@ -17,7 +17,8 @@
], ],
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/dom-crawler": "^3.4|^4.0|^5.0" "symfony/dom-crawler": "^3.4|^4.0|^5.0",
"symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"symfony/css-selector": "^3.4|^4.0|^5.0", "symfony/css-selector": "^3.4|^4.0|^5.0",

View File

@ -34,7 +34,7 @@ class FileLoaderLoadException extends \Exception
// Include the previous exception, to help the user see what might be the underlying cause // Include the previous exception, to help the user see what might be the underlying cause
// Trim the trailing period of the previous message. We only want 1 period remove so no rtrim... // Trim the trailing period of the previous message. We only want 1 period remove so no rtrim...
if ('.' === substr($previous->getMessage(), -1)) { if (str_ends_with($previous->getMessage(), '.')) {
$trimmedMessage = substr($previous->getMessage(), 0, -1); $trimmedMessage = substr($previous->getMessage(), 0, -1);
$message .= sprintf('%s', $trimmedMessage).' in '; $message .= sprintf('%s', $trimmedMessage).' in ';
} else { } else {

View File

@ -83,7 +83,7 @@ class DirectoryResource implements SelfCheckingResourceInterface
// always monitor directories for changes, except the .. entries // always monitor directories for changes, except the .. entries
// (otherwise deleted files wouldn't get detected) // (otherwise deleted files wouldn't get detected)
if ($file->isDir() && '/..' === substr($file, -3)) { if ($file->isDir() && str_ends_with($file, '/..')) {
continue; continue;
} }

View File

@ -19,6 +19,7 @@
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/filesystem": "^3.4|^4.0|^5.0", "symfony/filesystem": "^3.4|^4.0|^5.0",
"symfony/polyfill-ctype": "~1.8", "symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-php80": "^1.16",
"symfony/polyfill-php81": "^1.22" "symfony/polyfill-php81": "^1.22"
}, },
"require-dev": { "require-dev": {

View File

@ -54,7 +54,7 @@ class OutputFormatter implements WrappableOutputFormatterInterface
*/ */
public static function escapeTrailingBackslash(string $text): string public static function escapeTrailingBackslash(string $text): string
{ {
if ('\\' === substr($text, -1)) { if (str_ends_with($text, '\\')) {
$len = \strlen($text); $len = \strlen($text);
$text = rtrim($text, '\\'); $text = rtrim($text, '\\');
$text = str_replace("\0", '', $text); $text = str_replace("\0", '', $text);

View File

@ -442,7 +442,7 @@ class SymfonyStyle extends OutputStyle
{ {
$fetched = $this->bufferedOutput->fetch(); $fetched = $this->bufferedOutput->fetch();
//Prepend new line if last char isn't EOL: //Prepend new line if last char isn't EOL:
if ("\n" !== substr($fetched, -1)) { if (!str_ends_with($fetched, "\n")) {
$this->newLine(); $this->newLine();
} }
} }

View File

@ -19,7 +19,7 @@
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8", "symfony/polyfill-php73": "^1.8",
"symfony/polyfill-php80": "^1.15", "symfony/polyfill-php80": "^1.16",
"symfony/service-contracts": "^1.1|^2" "symfony/service-contracts": "^1.1|^2"
}, },
"require-dev": { "require-dev": {

View File

@ -61,7 +61,7 @@ class DebugClassLoader
if (false === $test || false === $i) { if (false === $test || false === $i) {
// filesystem is case sensitive // filesystem is case sensitive
self::$caseCheck = 0; 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 // filesystem is case insensitive and realpath() normalizes the case of characters
self::$caseCheck = 1; self::$caseCheck = 1;
} elseif (false !== stripos(\PHP_OS, 'darwin')) { } elseif (false !== stripos(\PHP_OS, 'darwin')) {

View File

@ -18,7 +18,7 @@
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/polyfill-php80": "^1.15" "symfony/polyfill-php80": "^1.16"
}, },
"conflict": { "conflict": {
"symfony/http-kernel": "<3.4" "symfony/http-kernel": "<3.4"

View File

@ -504,7 +504,7 @@ EOF;
return; return;
} }
$file = $r->getFileName(); $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)); $file = substr($file, 0, strrpos($file, '(', -17));
} }
if (!$file || $this->doExport($file) === $exportedFile = $this->export($file)) { if (!$file || $this->doExport($file) === $exportedFile = $this->export($file)) {
@ -2095,7 +2095,7 @@ EOF;
if ($resolveEnv && "'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'")) { if ($resolveEnv && "'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'")) {
$export = $resolvedExport; $export = $resolvedExport;
if (".''" === substr($export, -3)) { if (str_ends_with($export, ".''")) {
$export = substr($export, 0, -3); $export = substr($export, 0, -3);
if ("'" === $export[1]) { if ("'" === $export[1]) {
$export = substr_replace($export, '', 18, 7); $export = substr_replace($export, '', 18, 7);

View File

@ -66,7 +66,7 @@ abstract class Extension implements ExtensionInterface, ConfigurationExtensionIn
public function getAlias() public function getAlias()
{ {
$className = static::class; $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.'); throw new BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.');
} }
$classBaseName = substr(strrchr($className, '\\'), 1, -9); $classBaseName = substr(strrchr($className, '\\'), 1, -9);

View File

@ -49,6 +49,6 @@ class DirectoryLoader extends FileLoader
return true; return true;
} }
return null === $type && \is_string($resource) && '/' === substr($resource, -1); return null === $type && \is_string($resource) && str_ends_with($resource, '/');
} }
} }

View File

@ -91,7 +91,7 @@ abstract class FileLoader extends BaseFileLoader
*/ */
public function registerClasses(Definition $prototype, $namespace, $resource, $exclude = null) 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)); 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)) { if (!preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\\)++$/', $namespace)) {

View File

@ -31,7 +31,7 @@ class EnvPlaceholderParameterBag extends ParameterBag
*/ */
public function get($name) public function get($name)
{ {
if (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) { if (0 === strpos($name, 'env(') && str_ends_with($name, ')') && 'env()' !== $name) {
$env = substr($name, 4, -1); $env = substr($name, 4, -1);
if (isset($this->envPlaceholders[$env])) { if (isset($this->envPlaceholders[$env])) {

View File

@ -18,6 +18,7 @@
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"psr/container": "^1.0", "psr/container": "^1.0",
"symfony/polyfill-php80": "^1.16",
"symfony/service-contracts": "^1.1.6|^2" "symfony/service-contracts": "^1.1.6|^2"
}, },
"require-dev": { "require-dev": {

View File

@ -142,7 +142,7 @@ abstract class AbstractUriElement
return $path; return $path;
} }
if ('.' === substr($path, -1)) { if (str_ends_with($path, '.')) {
$path .= '/'; $path .= '/';
} }

View File

@ -18,7 +18,8 @@
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/polyfill-ctype": "~1.8", "symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0" "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"symfony/css-selector": "^3.4|^4.0|^5.0", "symfony/css-selector": "^3.4|^4.0|^5.0",

View File

@ -205,7 +205,7 @@ class DebugClassLoader
if (false === $test || false === $i) { if (false === $test || false === $i) {
// filesystem is case sensitive // filesystem is case sensitive
self::$caseCheck = 0; 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 // filesystem is case insensitive and realpath() normalizes the case of characters
self::$caseCheck = 1; self::$caseCheck = 1;
} elseif (false !== stripos(\PHP_OS, 'darwin')) { } elseif (false !== stripos(\PHP_OS, 'darwin')) {

View File

@ -19,7 +19,7 @@
"php": ">=7.1.3", "php": ">=7.1.3",
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/debug": "^4.4.5", "symfony/debug": "^4.4.5",
"symfony/polyfill-php80": "^1.15", "symfony/polyfill-php80": "^1.16",
"symfony/var-dumper": "^4.4|^5.0" "symfony/var-dumper": "^4.4|^5.0"
}, },
"require-dev": { "require-dev": {

View File

@ -78,6 +78,6 @@ class Gitignore
return ($isAbsolute ? '' : '(?:[^/]+/)*') return ($isAbsolute ? '' : '(?:[^/]+/)*')
.$regex .$regex
.('/' !== substr($gitignoreLine, -1) ? '(?:$|/)' : ''); .(!str_ends_with($gitignoreLine, '/') ? '(?:$|/)' : '');
} }
} }

View File

@ -16,7 +16,8 @@
} }
], ],
"require": { "require": {
"php": ">=7.1.3" "php": ">=7.1.3",
"symfony/polyfill-php80": "^1.16"
}, },
"autoload": { "autoload": {
"psr-4": { "Symfony\\Component\\Finder\\": "" }, "psr-4": { "Symfony\\Component\\Finder\\": "" },

View File

@ -167,7 +167,7 @@ EOF
$classes[] = $fqcn; $classes[] = $fqcn;
} elseif (class_exists($fqcn = $namespace.'\\'.ucfirst($shortClassName).'Type')) { } elseif (class_exists($fqcn = $namespace.'\\'.ucfirst($shortClassName).'Type')) {
$classes[] = $fqcn; $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; $classes[] = $fqcn;
} }
} }

View File

@ -22,6 +22,7 @@
"symfony/options-resolver": "~4.3|^5.0", "symfony/options-resolver": "~4.3|^5.0",
"symfony/polyfill-ctype": "~1.8", "symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.16",
"symfony/property-access": "^3.4.40|^4.4.8|^5.0.8", "symfony/property-access": "^3.4.40|^4.4.8|^5.0.8",
"symfony/service-contracts": "^1.1|^2" "symfony/service-contracts": "^1.1|^2"
}, },

View File

@ -460,7 +460,7 @@ final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterfac
foreach ($noProxy as $rule) { foreach ($noProxy as $rule) {
$dotRule = '.'.ltrim($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', 'proxy', null);
stream_context_set_option($context, 'http', 'request_fulluri', false); stream_context_set_option($context, 'http', 'request_fulluri', false);
stream_context_set_option($context, 'http', 'header', $requestHeaders); stream_context_set_option($context, 'http', 'header', $requestHeaders);

View File

@ -25,6 +25,7 @@
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/http-client-contracts": "^1.1.10|^2", "symfony/http-client-contracts": "^1.1.10|^2",
"symfony/polyfill-php73": "^1.11", "symfony/polyfill-php73": "^1.11",
"symfony/polyfill-php80": "^1.16",
"symfony/service-contracts": "^1.0|^2" "symfony/service-contracts": "^1.0|^2"
}, },
"require-dev": { "require-dev": {

View File

@ -2011,7 +2011,7 @@ class Request
continue; continue;
} }
if (self::HEADER_X_FORWARDED_PORT === $type) { 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 = $this->isSecure() ? ':443' : ':80';
} }
$v = '0.0.0.0'.$v; $v = '0.0.0.0'.$v;

View File

@ -88,7 +88,7 @@ class MimeTypeTest extends TestCase
touch($path); touch($path);
@chmod($path, 0333); @chmod($path, 0333);
if ('0333' == substr(sprintf('%o', fileperms($path)), -4)) { if (str_ends_with(sprintf('%o', fileperms($path)), '0333')) {
$this->expectException(AccessDeniedException::class); $this->expectException(AccessDeniedException::class);
MimeTypeGuesser::getInstance()->guess($path); MimeTypeGuesser::getInstance()->guess($path);
} else { } else {

View File

@ -19,7 +19,7 @@
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/mime": "^4.3|^5.0", "symfony/mime": "^4.3|^5.0",
"symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-mbstring": "~1.1",
"symfony/polyfill-php80": "^1.15" "symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"predis/predis": "~1.0", "predis/predis": "~1.0",

View File

@ -62,7 +62,7 @@ class AddAnnotatedClassesToCachePass implements CompilerPassInterface
// Explicit classes declared in the patterns are returned directly // Explicit classes declared in the patterns are returned directly
foreach ($patterns as $key => $pattern) { foreach ($patterns as $key => $pattern) {
if ('\\' !== substr($pattern, -1) && false === strpos($pattern, '*')) { if (!str_ends_with($pattern, '\\') && false === strpos($pattern, '*')) {
unset($patterns[$key]); unset($patterns[$key]);
$expanded[] = ltrim($pattern, '\\'); $expanded[] = ltrim($pattern, '\\');
} }

View File

@ -23,7 +23,7 @@
"symfony/http-foundation": "^4.4|^5.0", "symfony/http-foundation": "^4.4|^5.0",
"symfony/polyfill-ctype": "^1.8", "symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-php73": "^1.9", "symfony/polyfill-php73": "^1.9",
"symfony/polyfill-php80": "^1.15", "symfony/polyfill-php80": "^1.16",
"psr/log": "^1|^2" "psr/log": "^1|^2"
}, },
"require-dev": { "require-dev": {

View File

@ -18,7 +18,7 @@
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/polyfill-php80": "^1.15" "symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"doctrine/dbal": "^2.6|^3.0", "doctrine/dbal": "^2.6|^3.0",

View File

@ -116,7 +116,7 @@ abstract class AbstractMimeTypeGuesserTest extends TestCase
touch($path); touch($path);
@chmod($path, 0333); @chmod($path, 0333);
if ('0333' == substr(sprintf('%o', fileperms($path)), -4)) { if (str_ends_with(sprintf('%o', fileperms($path)), '0333')) {
$this->expectException(\InvalidArgumentException::class); $this->expectException(\InvalidArgumentException::class);
$this->getGuesser()->guessMimeType($path); $this->getGuesser()->guessMimeType($path);
} else { } else {

View File

@ -18,7 +18,8 @@
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0" "symfony/polyfill-mbstring": "^1.0",
"symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"egulias/email-validator": "^2.1.10|^3.1", "egulias/email-validator": "^2.1.10|^3.1",

View File

@ -927,7 +927,7 @@ class OptionsResolver implements Options
$fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]); $fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]);
$fmtProvidedTypes = implode('|', array_keys($invalidTypes)); $fmtProvidedTypes = implode('|', array_keys($invalidTypes));
$allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static function ($item) { $allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static function ($item) {
return '[]' === substr(self::TYPE_ALIASES[$item] ?? $item, -2); return str_ends_with(self::TYPE_ALIASES[$item] ?? $item, '[]');
})) > 0; })) > 0;
if (\is_array($value) && $allowedContainsArrayType) { if (\is_array($value) && $allowedContainsArrayType) {

View File

@ -16,7 +16,8 @@
} }
], ],
"require": { "require": {
"php": ">=7.1.3" "php": ">=7.1.3",
"symfony/polyfill-php80": "^1.16"
}, },
"autoload": { "autoload": {
"psr-4": { "Symfony\\Component\\OptionsResolver\\": "" }, "psr-4": { "Symfony\\Component\\OptionsResolver\\": "" },

View File

@ -108,7 +108,7 @@ final class PhpDocTypeHelper
return null; return null;
} }
if ('[]' === substr($docType, -2)) { if (str_ends_with($docType, '[]')) {
if ('mixed[]' === $docType) { if ('mixed[]' === $docType) {
$collectionKeyType = null; $collectionKeyType = null;
$collectionValueType = null; $collectionValueType = null;

View File

@ -24,7 +24,8 @@
], ],
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/inflector": "^3.4|^4.0|^5.0" "symfony/inflector": "^3.4|^4.0|^5.0",
"symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"symfony/serializer": "^3.4|^4.0|^5.0", "symfony/serializer": "^3.4|^4.0|^5.0",

View File

@ -221,9 +221,9 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
// so we need to encode them as they are not used for this purpose here // so we need to encode them as they are not used for this purpose here
// otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route // otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route
$url = strtr($url, ['/../' => '/%2E%2E/', '/./' => '/%2E/']); $url = strtr($url, ['/../' => '/%2E%2E/', '/./' => '/%2E/']);
if ('/..' === substr($url, -3)) { if (str_ends_with($url, '/..')) {
$url = substr($url, 0, -2).'%2E%2E'; $url = substr($url, 0, -2).'%2E%2E';
} elseif ('/.' === substr($url, -2)) { } elseif (str_ends_with($url, '/.')) {
$url = substr($url, 0, -1).'%2E'; $url = substr($url, 0, -1).'%2E';
} }

View File

@ -54,7 +54,7 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
}); });
foreach ($files as $file) { foreach ($files as $file) {
if (!$file->isFile() || '.php' !== substr($file->getFilename(), -4)) { if (!$file->isFile() || !str_ends_with($file->getFilename(), '.php')) {
continue; continue;
} }

View File

@ -527,7 +527,7 @@ class Route implements \Serializable
$regex = (string) substr($regex, 1); // returns false for a single character $regex = (string) substr($regex, 1); // returns false for a single character
} }
if ('$' === substr($regex, -1)) { if (str_ends_with($regex, '$')) {
$regex = substr($regex, 0, -1); $regex = substr($regex, 0, -1);
} }

View File

@ -16,7 +16,8 @@
} }
], ],
"require": { "require": {
"php": ">=7.1.3" "php": ">=7.1.3",
"symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"symfony/config": "^4.2|^5.0", "symfony/config": "^4.2|^5.0",

View File

@ -46,7 +46,7 @@ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, Serializer
if (!\is_array($data)) { if (!\is_array($data)) {
throw new InvalidArgumentException('Data expected to be an array, '.\gettype($data).' given.'); throw new InvalidArgumentException('Data expected to be an array, '.\gettype($data).' given.');
} }
if ('[]' !== substr($type, -2)) { if (!str_ends_with($type, '[]')) {
throw new InvalidArgumentException('Unsupported class: '.$type); throw new InvalidArgumentException('Unsupported class: '.$type);
} }
@ -74,7 +74,7 @@ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, Serializer
throw new BadMethodCallException(sprintf('The serializer needs to be set to allow "%s()" to be used.', __METHOD__)); throw new BadMethodCallException(sprintf('The serializer needs to be set to allow "%s()" to be used.', __METHOD__));
} }
return '[]' === substr($type, -2) return str_ends_with($type, '[]')
&& $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context); && $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context);
} }

View File

@ -484,7 +484,7 @@ class ArrayDenormalizerDummy implements DenormalizerInterface, SerializerAwareIn
*/ */
public function supportsDenormalization($data, $type, $format = null, array $context = []): bool public function supportsDenormalization($data, $type, $format = null, array $context = []): bool
{ {
return '[]' === substr($type, -2) return str_ends_with($type, '[]')
&& $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context); && $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context);
} }

View File

@ -17,7 +17,8 @@
], ],
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/polyfill-ctype": "~1.8" "symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"doctrine/annotations": "^1.10.4", "doctrine/annotations": "^1.10.4",

View File

@ -141,8 +141,8 @@ class XliffFileDumper extends FileDumper
$xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale())); $xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));
$xliffFile = $xliff->appendChild($dom->createElement('file')); $xliffFile = $xliff->appendChild($dom->createElement('file'));
if (MessageCatalogue::INTL_DOMAIN_SUFFIX === substr($domain, -($suffixLength = \strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)))) { if (str_ends_with($domain, MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
$xliffFile->setAttribute('id', substr($domain, 0, -$suffixLength).'.'.$messages->getLocale()); $xliffFile->setAttribute('id', substr($domain, 0, -\strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)).'.'.$messages->getLocale());
} else { } else {
$xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale()); $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
} }

View File

@ -18,6 +18,7 @@
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.16",
"symfony/translation-contracts": "^1.1.6|^2" "symfony/translation-contracts": "^1.1.6|^2"
}, },
"require-dev": { "require-dev": {

View File

@ -59,7 +59,7 @@ class DateTimeValidator extends DateValidator
return; return;
} }
if ('+' === substr($constraint->format, -1)) { if (str_ends_with($constraint->format, '+')) {
$errors['warnings'] = array_filter($errors['warnings'], function ($warning) { $errors['warnings'] = array_filter($errors['warnings'], function ($warning) {
return 'Trailing data' !== $warning; return 'Trailing data' !== $warning;
}); });

View File

@ -84,7 +84,7 @@ class AddAutoMappingConfigurationPass implements CompilerPassInterface
$regex = strtr($regex, ['\\*\\*' => '.*?', '\\*' => '[^\\\\]*?']); $regex = strtr($regex, ['\\*\\*' => '.*?', '\\*' => '[^\\\\]*?']);
// If this class does not end by a slash, anchor the end // If this class does not end by a slash, anchor the end
if ('\\' !== substr($regex, -1)) { if (!str_ends_with($regex, '\\')) {
$regex .= '$'; $regex .= '$';
} }

View File

@ -19,6 +19,7 @@
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/polyfill-ctype": "~1.8", "symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.16",
"symfony/translation-contracts": "^1.1|^2" "symfony/translation-contracts": "^1.1|^2"
}, },
"require-dev": { "require-dev": {

View File

@ -65,7 +65,7 @@ class ClassStub extends ConstStub
$s = ReflectionCaster::castFunctionAbstract($r, [], new Stub(), true, Caster::EXCLUDE_VERBOSE); $s = ReflectionCaster::castFunctionAbstract($r, [], new Stub(), true, Caster::EXCLUDE_VERBOSE);
$s = ReflectionCaster::getSignature($s); $s = ReflectionCaster::getSignature($s);
if ('()' === substr($identifier, -2)) { if (str_ends_with($identifier, '()')) {
$this->value = substr_replace($identifier, $s, -2); $this->value = substr_replace($identifier, $s, -2);
} else { } else {
$this->value .= $s; $this->value .= $s;

View File

@ -479,7 +479,7 @@ class CliDumper extends AbstractDumper
} else { } else {
$value = "\033[{$this->styles[$style]}m".$value; $value = "\033[{$this->styles[$style]}m".$value;
} }
if ($cchrCount && $endCchr === substr($value, -\strlen($endCchr))) { if ($cchrCount && str_ends_with($value, $endCchr)) {
$value = substr($value, 0, -\strlen($endCchr)); $value = substr($value, 0, -\strlen($endCchr));
} else { } else {
$value .= "\033[{$this->styles['default']}m"; $value .= "\033[{$this->styles['default']}m";

View File

@ -19,7 +19,7 @@
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php72": "~1.5", "symfony/polyfill-php72": "~1.5",
"symfony/polyfill-php80": "^1.15" "symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"ext-iconv": "*", "ext-iconv": "*",

View File

@ -114,7 +114,7 @@ class ParseException extends RuntimeException
$this->message = $this->rawMessage; $this->message = $this->rawMessage;
$dot = false; $dot = false;
if ('.' === substr($this->message, -1)) { if (str_ends_with($this->message, '.')) {
$this->message = substr($this->message, 0, -1); $this->message = substr($this->message, 0, -1);
$dot = true; $dot = true;
} }

View File

@ -463,7 +463,7 @@ class Parser
$value .= ' '; $value .= ' ';
} }
if ('' !== trim($line) && '\\' === substr($line, -1)) { if ('' !== trim($line) && str_ends_with($line, '\\')) {
$value .= ltrim(substr($line, 0, -1)); $value .= ltrim(substr($line, 0, -1));
} elseif ('' !== trim($line)) { } elseif ('' !== trim($line)) {
$value .= trim($line); $value .= trim($line);
@ -472,7 +472,7 @@ class Parser
if ('' === trim($line)) { if ('' === trim($line)) {
$previousLineWasNewline = true; $previousLineWasNewline = true;
$previousLineWasTerminatedWithBackslash = false; $previousLineWasTerminatedWithBackslash = false;
} elseif ('\\' === substr($line, -1)) { } elseif (str_ends_with($line, '\\')) {
$previousLineWasNewline = false; $previousLineWasNewline = false;
$previousLineWasTerminatedWithBackslash = true; $previousLineWasTerminatedWithBackslash = true;
} else { } else {

View File

@ -17,7 +17,8 @@
], ],
"require": { "require": {
"php": ">=7.1.3", "php": ">=7.1.3",
"symfony/polyfill-ctype": "~1.8" "symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-php80": "^1.16"
}, },
"require-dev": { "require-dev": {
"symfony/console": "^3.4|^4.0|^5.0" "symfony/console": "^3.4|^4.0|^5.0"