diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index c054cfbacf39b8fbffd3dfe3a90c87b48e0df67b..9d37754d73b3115ba2b0bb434b4d2c5c7a53de3e 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -168,7 +168,7 @@ function drupal_find_theme_templates($cache, $extension, $path) {
   // implementation.
   foreach ($files as $template => $file) {
     // Ignore sub-theme templates for the current theme.
-    if (strpos($file->uri, str_replace($subtheme_paths, '', $file->uri)) !== 0) {
+    if (!str_starts_with($file->uri, str_replace($subtheme_paths, '', $file->uri))) {
       continue;
     }
     // Remove the extension from the filename.
diff --git a/core/lib/Drupal/Component/Utility/Unicode.php b/core/lib/Drupal/Component/Utility/Unicode.php
index 8fdfd7bcf82dde165750285d712f8502436774f7..6a61a45103691d75f09431eea1810afc91f96bc8 100644
--- a/core/lib/Drupal/Component/Utility/Unicode.php
+++ b/core/lib/Drupal/Component/Utility/Unicode.php
@@ -163,7 +163,7 @@ public static function encodingFromBOM($data) {
     ];
 
     foreach ($bomMap as $bom => $encoding) {
-      if (strpos($data, $bom) === 0) {
+      if (str_starts_with($data, $bom)) {
         return $encoding;
       }
     }
diff --git a/core/lib/Drupal/Component/Utility/UrlHelper.php b/core/lib/Drupal/Component/Utility/UrlHelper.php
index ef118716d0b8fde227b8ba95eb757eba5dfbb535..e2e8f6dfc5698c786ae0983b9a3e2a0b84207967 100644
--- a/core/lib/Drupal/Component/Utility/UrlHelper.php
+++ b/core/lib/Drupal/Component/Utility/UrlHelper.php
@@ -259,7 +259,7 @@ public static function isExternal($path) {
     $path = str_replace('\\', '/', $path);
     // If the path starts with 2 slashes then it is always considered an
     // external URL without an explicit protocol part.
-    return (strpos($path, '//') === 0)
+    return (str_starts_with($path, '//'))
       // Leading control characters may be ignored or mishandled by browsers,
       // so assume such a path may lead to an external location. The \p{C}
       // character class matches all UTF-8 control, unassigned, and private
diff --git a/core/lib/Drupal/Core/Annotation/ContextDefinition.php b/core/lib/Drupal/Core/Annotation/ContextDefinition.php
index 695bf1169affb901508519d3102ad87ac1c2c1ca..64f7d7b497d137f79aa054a8243f2415c3b9f1cf 100644
--- a/core/lib/Drupal/Core/Annotation/ContextDefinition.php
+++ b/core/lib/Drupal/Core/Annotation/ContextDefinition.php
@@ -145,7 +145,7 @@ protected function getDefinitionClass(array $values) {
     if (isset($values['class'])) {
       return $values['class'];
     }
-    if (strpos($values['value'], 'entity:') === 0) {
+    if (str_starts_with($values['value'], 'entity:')) {
       return 'Drupal\Core\Plugin\Context\EntityContextDefinition';
     }
     return 'Drupal\Core\Plugin\Context\ContextDefinition';
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 702441d1fbe68edb2b5dac1ed7305eb8133c31af..480ca234423ba0c0c5d4acfbbac6b3e9cf27473c 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -208,7 +208,7 @@ public function buildByExtension($extension) {
               if ($source[1] !== '/') {
                 $source = substr($source, 1);
                 // Non core provided libraries can be in multiple locations.
-                if (strpos($source, 'libraries/') === 0) {
+                if (str_starts_with($source, 'libraries/')) {
                   $path_to_source = $this->librariesDirectoryFileFinder->find(substr($source, 10));
                   if ($path_to_source) {
                     $source = $path_to_source;
diff --git a/core/lib/Drupal/Core/Cache/Context/CacheContextsPass.php b/core/lib/Drupal/Core/Cache/Context/CacheContextsPass.php
index 2025fbbf61cad423076b892f4f436fb33f3ab83c..579fc2a886416854bf89e628762ece39e1c6beae 100644
--- a/core/lib/Drupal/Core/Cache/Context/CacheContextsPass.php
+++ b/core/lib/Drupal/Core/Cache/Context/CacheContextsPass.php
@@ -18,7 +18,7 @@ class CacheContextsPass implements CompilerPassInterface {
   public function process(ContainerBuilder $container) {
     $cache_contexts = [];
     foreach (array_keys($container->findTaggedServiceIds('cache.context')) as $id) {
-      if (strpos($id, 'cache_context.') !== 0) {
+      if (!str_starts_with($id, 'cache_context.')) {
         throw new \InvalidArgumentException(sprintf('The service "%s" has an invalid service ID: cache context service IDs must use the "cache_context." prefix. (The suffix is the cache context ID developers may use.)', $id));
       }
       $cache_contexts[] = substr($id, 14);
diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
index 852f1d07b4741b8164237bd28aa7e258e4f64977..ef0e22d482bf2114dbed4e23ac6b58cd8b3e6082 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactory.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -309,7 +309,7 @@ protected function getConfigCacheKeys($name) {
     return array_filter(array_keys($this->cache), function ($key) use ($name) {
       // Return TRUE if the key is the name or starts with the configuration
       // name plus the delimiter.
-      return $key === $name || strpos($key, $name . ':') === 0;
+      return $key === $name || str_starts_with($key, $name . ':');
     });
   }
 
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityDependency.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityDependency.php
index 11ac81aba9ffd102356de1f01b4ce07b5af11882..a7a2abe65e97d8f6c45d2b372725d51e239903db 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityDependency.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityDependency.php
@@ -85,7 +85,7 @@ public function getDependencies($type) {
   public function hasDependency($type, $name) {
     // Add a dependency on the provider module (which defines this config
     // entity type, such as 'node' in the case of 'node.type' configuration).
-    if ($type == 'module' && strpos($this->name, $name . '.') === 0) {
+    if ($type == 'module' && str_starts_with($this->name, $name . '.')) {
       return TRUE;
     }
     return isset($this->dependencies[$type]) && array_search($name, $this->dependencies[$type]) !== FALSE;
diff --git a/core/lib/Drupal/Core/Config/InstallStorage.php b/core/lib/Drupal/Core/Config/InstallStorage.php
index a21388b3cbc398560c5351d41d64879ac3e748b8..136be5d6bd7c54efd5351386a0683b59caaa8055 100644
--- a/core/lib/Drupal/Core/Config/InstallStorage.php
+++ b/core/lib/Drupal/Core/Config/InstallStorage.php
@@ -133,7 +133,7 @@ public function listAll($prefix = '') {
     else {
       $return = [];
       foreach ($names as $index => $name) {
-        if (strpos($name, $prefix) === 0) {
+        if (str_starts_with($name, $prefix)) {
           $return[$index] = $names[$index];
         }
       }
diff --git a/core/lib/Drupal/Core/Config/MemoryStorage.php b/core/lib/Drupal/Core/Config/MemoryStorage.php
index 054b605ba75b70f91559105c903fbfdb39149b94..0c02659918e64e0b1394742f9417e7295084c44a 100644
--- a/core/lib/Drupal/Core/Config/MemoryStorage.php
+++ b/core/lib/Drupal/Core/Config/MemoryStorage.php
@@ -118,7 +118,7 @@ public function listAll($prefix = '') {
     $names = array_keys($this->config[$this->collection]);
     if ($prefix !== '') {
       $names = array_filter($names, function ($name) use ($prefix) {
-        return strpos($name, $prefix) === 0;
+        return str_starts_with($name, $prefix);
       });
     }
     return $names;
@@ -138,7 +138,7 @@ public function deleteAll($prefix = '') {
     }
     $success = FALSE;
     foreach (array_keys($this->config[$this->collection]) as $name) {
-      if (strpos($name, $prefix) === 0) {
+      if (str_starts_with($name, $prefix)) {
         $success = TRUE;
         unset($this->config[$this->collection][$name]);
       }
diff --git a/core/lib/Drupal/Core/Database/Database.php b/core/lib/Drupal/Core/Database/Database.php
index 809b1552ca0e421f33f308b53480516d7d46d622..425a271cfaec2c207b31040af17dcbfd7c81d64e 100644
--- a/core/lib/Drupal/Core/Database/Database.php
+++ b/core/lib/Drupal/Core/Database/Database.php
@@ -240,7 +240,7 @@ final public static function parseConnectionInfo(array $info) {
     // Backwards compatibility layer for Drupal 8 style database connection
     // arrays. Those have the wrong 'namespace' key set, or not set at all
     // for core supported database drivers.
-    if (empty($info['namespace']) || (strpos($info['namespace'], 'Drupal\\Core\\Database\\Driver\\') === 0)) {
+    if (empty($info['namespace']) || str_starts_with($info['namespace'], 'Drupal\\Core\\Database\\Driver\\')) {
       switch (strtolower($info['driver'])) {
         case 'mysql':
           $info['namespace'] = 'Drupal\\mysql\\Driver\\Database\\mysql';
diff --git a/core/lib/Drupal/Core/Database/Log.php b/core/lib/Drupal/Core/Database/Log.php
index b310d1728482d2aa74f34668a8b3c00469cc0074..6a1de6a0c3ad7b750722c5eb8e49d6c6d43b12da 100644
--- a/core/lib/Drupal/Core/Database/Log.php
+++ b/core/lib/Drupal/Core/Database/Log.php
@@ -187,7 +187,7 @@ public static function removeDatabaseEntries(array $backtrace, string $driver_na
       // If the call was made from a function, 'class' will be empty. We give
       // it a default empty string value in that case.
       $class = $backtrace[$n]['class'] ?? '';
-      if (strpos($class, __NAMESPACE__, 0) === 0 || strpos($class, $driver_namespace, 0) === 0) {
+      if (str_starts_with($class, __NAMESPACE__) || str_starts_with($class, $driver_namespace)) {
         break;
       }
     }
diff --git a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
index f1fcfabd0f54412ca4c2c57c7abb8b7f3b2ce37d..159f643166b922961772acbdb484b201cf935ba8 100644
--- a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
+++ b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
@@ -205,7 +205,7 @@ private function parseDefaults(array &$content, string $file): array
      */
     private function parseDefinition(string $id, $service, string $file, array $defaults)
     {
-        if (\is_string($service) && 0 === strpos($service, '@')) {
+        if (\is_string($service) && str_starts_with($service, '@')) {
             $this->container->setAlias($id, $alias = new Alias(substr($service, 1)));
             if (isset($defaults['public'])) {
                 $alias->setPublic($defaults['public']);
@@ -456,15 +456,15 @@ private function resolveServices($value)
     {
         if (is_array($value)) {
             $value = array_map(array($this, 'resolveServices'), $value);
-        } elseif (is_string($value) &&  0 === strpos($value, '@=')) {
+        } elseif (is_string($value) && str_starts_with($value, '@=')) {
             // Not supported.
             //return new Expression(substr($value, 2));
             throw new InvalidArgumentException(sprintf("'%s' is an Expression, but expressions are not supported.", $value));
-        } 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_INVALID_REFERENCE;
             } else {
diff --git a/core/lib/Drupal/Core/Entity/EntityBase.php b/core/lib/Drupal/Core/Entity/EntityBase.php
index 44a6734896796651140fb33bdea7f8eeb61725c8..a42ef483366fe86768bafa54d50ed3b32158d6a2 100644
--- a/core/lib/Drupal/Core/Entity/EntityBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityBase.php
@@ -271,7 +271,7 @@ protected function urlRouteParameters($rel) {
       $parameter_name = $this->getEntityType()->getBundleEntityType() ?: $this->getEntityType()->getKey('bundle');
       $uri_route_parameters[$parameter_name] = $this->bundle();
     }
-    if ($this instanceof RevisionableInterface && strpos($rel, 'revision') === 0) {
+    if ($this instanceof RevisionableInterface && str_starts_with($rel, 'revision')) {
       $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
     }
 
diff --git a/core/lib/Drupal/Core/Entity/EntityResolverManager.php b/core/lib/Drupal/Core/Entity/EntityResolverManager.php
index 88baec68bd4c2946487fae31e7159ac521afab0c..55f87ea2b70cae176803c43552e1137f56479449 100644
--- a/core/lib/Drupal/Core/Entity/EntityResolverManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityResolverManager.php
@@ -188,7 +188,7 @@ protected function setParametersFromEntityInformation(Route $route) {
       // First try to figure out whether there is already a parameter upcasting
       // the same entity type already.
       foreach ($parameter_definitions as $info) {
-        if (isset($info['type']) && (strpos($info['type'], 'entity:') === 0)) {
+        if (isset($info['type']) && str_starts_with($info['type'], 'entity:')) {
           // The parameter types are in the form 'entity:$entity_type'.
           [, $parameter_entity_type] = explode(':', $info['type'], 2);
           if ($parameter_entity_type == $entity_type) {
diff --git a/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php
index 0ee35bec1887c6842044b759de81f4ee83d772ef..e950eae1bf331e6019ff7bcd1272f8b81319d42b 100644
--- a/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php
@@ -112,7 +112,7 @@ protected function getDestinationAsAbsoluteUrl($destination, $scheme_and_host) {
       // not including the scheme and host, but its path is expected to be
       // absolute (start with a '/'). For such a case, prepend the scheme and
       // host, because the 'Location' header must be absolute.
-      if (strpos($destination, '/') === 0) {
+      if (str_starts_with($destination, '/')) {
         $destination = $scheme_and_host . $destination;
       }
       else {
diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
index ce6ecbddfa5f35c259c164ba2cdd6f916ed90baa..32e205119114b18545230d2a180a1df3b710faa3 100644
--- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
+++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
@@ -274,13 +274,13 @@ protected function filterByProfileDirectories(array $all_files) {
     }
 
     $all_files = array_filter($all_files, function ($file) {
-      if (strpos($file->subpath, 'profiles') !== 0) {
+      if (!str_starts_with($file->subpath, 'profiles')) {
         // This extension doesn't belong to a profile, ignore it.
         return TRUE;
       }
 
       foreach ($this->profileDirectories as $profile_path) {
-        if (strpos($file->getPath(), $profile_path) === 0) {
+        if (str_starts_with($file->getPath(), $profile_path)) {
           // Parent profile found.
           return TRUE;
         }
@@ -309,7 +309,7 @@ protected function sort(array $all_files, array $weights) {
     foreach ($all_files as $key => $file) {
       // If the extension does not belong to a profile, just apply the weight
       // of the originating directory.
-      if (strpos($file->subpath, 'profiles') !== 0) {
+      if (!str_starts_with($file->subpath, 'profiles')) {
         $origins[$key] = $weights[$file->origin];
         $profiles[$key] = NULL;
       }
@@ -323,7 +323,7 @@ protected function sort(array $all_files, array $weights) {
       else {
         // Apply the weight of the originating profile directory.
         foreach ($this->profileDirectories as $weight => $profile_path) {
-          if (strpos($file->getPath(), $profile_path) === 0) {
+          if (str_starts_with($file->getPath(), $profile_path)) {
             $origins[$key] = static::ORIGIN_PROFILE;
             $profiles[$key] = $weight;
             continue 2;
diff --git a/core/lib/Drupal/Core/Extension/ExtensionVersion.php b/core/lib/Drupal/Core/Extension/ExtensionVersion.php
index 928744dbd9a905ff8093deb1590ef2fb08eff063..a5c064b49f2725bb2d50f6006c472e722a57f944 100644
--- a/core/lib/Drupal/Core/Extension/ExtensionVersion.php
+++ b/core/lib/Drupal/Core/Extension/ExtensionVersion.php
@@ -53,7 +53,7 @@ final class ExtensionVersion {
    */
   public static function createFromVersionString(string $version_string): ExtensionVersion {
     $original_version = $version_string;
-    if (strpos($version_string, static::CORE_PREFIX) === 0 && $version_string !== '8.x-dev') {
+    if (str_starts_with($version_string, static::CORE_PREFIX) && $version_string !== '8.x-dev') {
       $version_string = preg_replace('/8\.x-/', '', $version_string, 1);
     }
     else {
diff --git a/core/lib/Drupal/Core/Extension/InfoParserDynamic.php b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
index 55c6ddd953ee32d961ad1d5610c555b566d7ab96..8298223a374c2ce9fcc307b4c7e4382c116dbb03 100644
--- a/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
+++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
@@ -51,7 +51,7 @@ public function parse($filename) {
         throw new InfoParserException('Missing required keys (' . implode(', ', $missing_keys) . ') in ' . $filename);
       }
       if (!isset($parsed_info['core_version_requirement'])) {
-        if (strpos($filename, 'core/') === 0 || strpos($filename, $this->root . '/core/') === 0) {
+        if (str_starts_with($filename, 'core/') || str_starts_with($filename, $this->root . '/core/')) {
           // Core extensions do not need to specify core compatibility: they are
           // by definition compatible so a sensible default is used. Core
           // modules are allowed to provide these for testing purposes.
diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php
index 55c5b1ecd5c1408ad595d22ac6b8b6085c208be8..39daf849aa8efc7a8b8ab89c14d20709832ac008 100644
--- a/core/lib/Drupal/Core/Field/WidgetBase.php
+++ b/core/lib/Drupal/Core/Field/WidgetBase.php
@@ -427,7 +427,7 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis
       $element_path = implode('][', $element['#parents']);
       if ($reported_errors = $form_state->getErrors()) {
         foreach (array_keys($reported_errors) as $error_path) {
-          if (strpos($error_path, $element_path) === 0) {
+          if (str_starts_with($error_path, $element_path)) {
             return;
           }
         }
diff --git a/core/lib/Drupal/Core/FileTransfer/FileTransfer.php b/core/lib/Drupal/Core/FileTransfer/FileTransfer.php
index 26fd98b342f378c4c1eb38455242fe2d886e18de..2724b0d792ac4e80c6221d219b062ffd8742fb27 100644
--- a/core/lib/Drupal/Core/FileTransfer/FileTransfer.php
+++ b/core/lib/Drupal/Core/FileTransfer/FileTransfer.php
@@ -293,7 +293,7 @@ final protected function fixRemotePath($path, $strip_chroot = TRUE) {
     // Strip out windows drive letter if its there.
     $path = preg_replace('|^([a-z]{1}):|i', '', $path);
     if ($strip_chroot) {
-      if ($this->chrootPath && strpos($path, $this->chrootPath) === 0) {
+      if ($this->chrootPath && str_starts_with($path, $this->chrootPath)) {
         $path = ($path == $this->chrootPath) ? '' : substr($path, strlen($this->chrootPath));
       }
     }
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index cec98161251c518939a327f297479c890823d3b7..6b3393e2fb1db9af3ab3d904505e82a66349d89f 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -853,7 +853,7 @@ protected function buildFormAction() {
 
     // Prevent cross site requests via the Form API by using an absolute URL
     // when the request uri starts with multiple slashes..
-    if (strpos($request_uri, '//') === 0) {
+    if (str_starts_with($request_uri, '//')) {
       $request_uri = $request->getUri();
     }
 
diff --git a/core/lib/Drupal/Core/Mail/MailFormatHelper.php b/core/lib/Drupal/Core/Mail/MailFormatHelper.php
index 4d7a1ae7ae95ffb3ac927ccf4830f2a734b071e9..4198d443e6fc0363b878506dac33fa1ffa4c57e7 100644
--- a/core/lib/Drupal/Core/Mail/MailFormatHelper.php
+++ b/core/lib/Drupal/Core/Mail/MailFormatHelper.php
@@ -302,7 +302,7 @@ protected static function wrapMailLine(&$line, $key, $values) {
 
     // Do not break MIME headers which could be longer than 77 characters.
     foreach ($mime_headers as $header) {
-      if (strpos($line, $header . ': ') === 0) {
+      if (str_starts_with($line, $header . ': ')) {
         $line_is_mime_header = TRUE;
         break;
       }
diff --git a/core/lib/Drupal/Core/ParamConverter/AdminPathConfigEntityConverter.php b/core/lib/Drupal/Core/ParamConverter/AdminPathConfigEntityConverter.php
index 790f32b5bcf1f30159f54df551c8ca521213267e..2985f8def6feffdea79f9a643f1882c05097e831 100644
--- a/core/lib/Drupal/Core/ParamConverter/AdminPathConfigEntityConverter.php
+++ b/core/lib/Drupal/Core/ParamConverter/AdminPathConfigEntityConverter.php
@@ -68,7 +68,7 @@ public function convert($value, $definition, $name, array $defaults) {
     }
     // If the entity type is dynamic, confirm it to be a config entity. Static
     // entity types will have performed this check in self::applies().
-    if (strpos($definition['type'], 'entity:{') === 0) {
+    if (str_starts_with($definition['type'], 'entity:{')) {
       $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
       if (!$entity_type->entityClassImplements(ConfigEntityInterface::class)) {
         return parent::convert($value, $definition, $name, $defaults);
@@ -92,7 +92,7 @@ public function applies($definition, $name, Route $route) {
     if (parent::applies($definition, $name, $route)) {
       $entity_type_id = substr($definition['type'], strlen('entity:'));
       // If the entity type is dynamic, defer checking to self::convert().
-      if (strpos($entity_type_id, '{') === 0) {
+      if (str_starts_with($entity_type_id, '{')) {
         return TRUE;
       }
       // As we only want to override EntityConverter for ConfigEntities, find
diff --git a/core/lib/Drupal/Core/ParamConverter/DynamicEntityTypeParamConverterTrait.php b/core/lib/Drupal/Core/ParamConverter/DynamicEntityTypeParamConverterTrait.php
index 0c3a589967d283627c19d96afc609a2f631d8e68..f4cfd928540ac08ac6bf01c5d9904a80e224f128 100644
--- a/core/lib/Drupal/Core/ParamConverter/DynamicEntityTypeParamConverterTrait.php
+++ b/core/lib/Drupal/Core/ParamConverter/DynamicEntityTypeParamConverterTrait.php
@@ -31,7 +31,7 @@ protected function getEntityTypeFromDefaults($definition, $name, array $defaults
     $entity_type_id = substr($type_part, 1);
 
     // If the entity type is dynamic, it will be pulled from the route defaults.
-    if (strpos($entity_type_id, '{') === 0) {
+    if (str_starts_with($entity_type_id, '{')) {
       $entity_type_slug = substr($entity_type_id, 1, -1);
       if (!isset($defaults[$entity_type_slug])) {
         throw new ParamNotConvertedException(sprintf('The "%s" parameter was not converted because the "%s" parameter is missing.', $name, $entity_type_slug));
diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php b/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
index c2e5d53331faf416e7aac2d23b2c368ac048caf9..bfc234b958e6107d5751e396fc6898f38005935d 100644
--- a/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
+++ b/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
@@ -81,7 +81,7 @@ class ContextDefinition implements ContextDefinitionInterface {
    *   The created context definition object.
    */
   public static function create($data_type = 'any') {
-    if (strpos($data_type, 'entity:') === 0) {
+    if (str_starts_with($data_type, 'entity:')) {
       return new EntityContextDefinition($data_type);
     }
     return new static(
@@ -113,7 +113,7 @@ public function __construct($data_type = 'any', $label = NULL, $required = TRUE,
     $this->description = $description;
     $this->defaultValue = $default_value;
 
-    assert(strpos($data_type, 'entity:') !== 0 || $this instanceof EntityContextDefinition);
+    assert(!str_starts_with($data_type, 'entity:') || $this instanceof EntityContextDefinition);
   }
 
   /**
@@ -280,7 +280,7 @@ protected function dataTypeMatches(ContextInterface $context) {
       // Allow a more generic data type like 'entity' to be fulfilled by a more
       // specific data type like 'entity:user'. However, if this type is more
       // specific, do not consider a more generic type to be a match.
-      strpos($that_type, "$this_type:") === 0
+      str_starts_with($that_type, "$this_type:")
     );
   }
 
diff --git a/core/lib/Drupal/Core/Plugin/Context/EntityContextDefinition.php b/core/lib/Drupal/Core/Plugin/Context/EntityContextDefinition.php
index 08c620b637d067f6135ebaabf0bd914d27800efb..abdcf05116f37e495a6bf40ec8770481ddaad8f4 100644
--- a/core/lib/Drupal/Core/Plugin/Context/EntityContextDefinition.php
+++ b/core/lib/Drupal/Core/Plugin/Context/EntityContextDefinition.php
@@ -20,7 +20,7 @@ class EntityContextDefinition extends ContextDefinition {
   public function __construct($data_type = 'any', $label = NULL, $required = TRUE, $multiple = FALSE, $description = NULL, $default_value = NULL) {
     // Prefix the data type with 'entity:' so that this class can be constructed
     // like so: new EntityContextDefinition('node')
-    if (strpos($data_type, 'entity:') !== 0) {
+    if (!str_starts_with($data_type, 'entity:')) {
       $data_type = "entity:$data_type";
     }
     parent::__construct($data_type, $label, $required, $multiple, $description, $default_value);
diff --git a/core/lib/Drupal/Core/Plugin/PluginManagerPass.php b/core/lib/Drupal/Core/Plugin/PluginManagerPass.php
index 9d4a483ae17df426b04a55da16283185de21f221..a29138b6d01e0cbc50fcadb41bdb023122a57ea6 100644
--- a/core/lib/Drupal/Core/Plugin/PluginManagerPass.php
+++ b/core/lib/Drupal/Core/Plugin/PluginManagerPass.php
@@ -17,7 +17,7 @@ class PluginManagerPass implements CompilerPassInterface {
   public function process(ContainerBuilder $container) {
     $cache_clearer_definition = $container->getDefinition('plugin.cache_clearer');
     foreach ($container->getDefinitions() as $service_id => $definition) {
-      if (strpos($service_id, 'plugin.manager.') === 0 || $definition->hasTag('plugin_manager_cache_clear')) {
+      if (str_starts_with($service_id, 'plugin.manager.') || $definition->hasTag('plugin_manager_cache_clear')) {
         if (is_subclass_of($definition->getClass(), '\Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface')) {
           $cache_clearer_definition->addMethodCall('addCachedDiscovery', [new Reference($service_id)]);
         }
diff --git a/core/lib/Drupal/Core/Routing/Enhancer/EntityRevisionRouteEnhancer.php b/core/lib/Drupal/Core/Routing/Enhancer/EntityRevisionRouteEnhancer.php
index bdd52cbdd30d643f908503d47dd446f5ff2d349e..18f0fb598fab50967140cbeb50fb12f708a5027a 100644
--- a/core/lib/Drupal/Core/Routing/Enhancer/EntityRevisionRouteEnhancer.php
+++ b/core/lib/Drupal/Core/Routing/Enhancer/EntityRevisionRouteEnhancer.php
@@ -24,7 +24,7 @@ protected function applies(Route $route) {
     // Check whether there is any entity revision parameter.
     $parameters = $route->getOption('parameters') ?: [];
     foreach ($parameters as $info) {
-      if (isset($info['type']) && strpos($info['type'], 'entity_revision:') === 0) {
+      if (isset($info['type']) && str_starts_with($info['type'], 'entity_revision:')) {
         return TRUE;
       }
     }
diff --git a/core/lib/Drupal/Core/Routing/RoutePreloader.php b/core/lib/Drupal/Core/Routing/RoutePreloader.php
index 9081941e6c3573dcf867c641cde3691b3ccb708e..eb2d13e6986b193a2047bfa81080cfb8720d4008 100644
--- a/core/lib/Drupal/Core/Routing/RoutePreloader.php
+++ b/core/lib/Drupal/Core/Routing/RoutePreloader.php
@@ -100,7 +100,7 @@ public function onRequest(KernelEvent $event) {
   public function onAlterRoutes(RouteBuildEvent $event) {
     $collection = $event->getRouteCollection();
     foreach ($collection->all() as $name => $route) {
-      if (strpos($route->getPath(), '/admin/') !== 0 && $route->getPath() != '/admin' && static::isGetAndHtmlRoute($route)) {
+      if (!str_starts_with($route->getPath(), '/admin/') && $route->getPath() != '/admin' && static::isGetAndHtmlRoute($route)) {
         $this->nonAdminRoutesOnRebuild[] = $name;
       }
     }
diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php
index 968bb5a951ae9563ebcc2f885c0f89cbedc59930..cf0f24b4085475f3a67214232ac6ba9377cd1168 100644
--- a/core/lib/Drupal/Core/Routing/UrlGenerator.php
+++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php
@@ -298,7 +298,7 @@ public function generateFromRoute($name, $parameters = [], $options = [], $colle
     }
     // Ensure the resulting path has at most one leading slash, to prevent it
     // becoming an external URL without a protocol like //example.com.
-    if (strpos($path, '//') === 0) {
+    if (str_starts_with($path, '//')) {
       $path = '/' . ltrim($path, '/');
     }
     // The contexts base URL is already encoded
diff --git a/core/lib/Drupal/Core/StreamWrapper/LocalStream.php b/core/lib/Drupal/Core/StreamWrapper/LocalStream.php
index b4430966847d9a0686edccd4e0119198c5792652..23e67d2829376e9c835256f7d2c291164650a39b 100644
--- a/core/lib/Drupal/Core/StreamWrapper/LocalStream.php
+++ b/core/lib/Drupal/Core/StreamWrapper/LocalStream.php
@@ -125,7 +125,7 @@ protected function getLocalPath($uri = NULL) {
     // filesystem stream wrapper URI, in which case this local stream acts like
     // a proxy. realpath() is not supported by vfsStream, because a virtual
     // file system does not have a real filepath.
-    if (strpos($path, 'vfs://') === 0) {
+    if (str_starts_with($path, 'vfs://')) {
       return $path;
     }
 
@@ -135,7 +135,7 @@ protected function getLocalPath($uri = NULL) {
       $realpath = realpath(dirname($path)) . '/' . \Drupal::service('file_system')->basename($path);
     }
     $directory = realpath($this->getDirectoryPath());
-    if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) {
+    if (!$realpath || !$directory || !str_starts_with($realpath, $directory)) {
       return FALSE;
     }
     return $realpath;
diff --git a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
index 1747bf37c5f58ecb19582ddbe7d9e5926b0ba330..f0ed4d5fd9d3d6d56888cc864220387e7ce4352e 100644
--- a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
+++ b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
@@ -120,7 +120,7 @@ public static function basePath($site_path = NULL) {
    */
   protected function getLocalPath($uri = NULL) {
     $path = parent::getLocalPath($uri);
-    if (!$path || (strpos($path, 'vfs://') === 0)) {
+    if (!$path || str_starts_with($path, 'vfs://')) {
       return $path;
     }
 
@@ -131,7 +131,7 @@ protected function getLocalPath($uri = NULL) {
     $private_path = Settings::get('file_private_path');
     if ($private_path) {
       $private_path = realpath($private_path);
-      if ($private_path && strpos($path, $private_path) === 0) {
+      if ($private_path && str_starts_with($path, $private_path)) {
         return FALSE;
       }
     }
diff --git a/core/lib/Drupal/Core/Template/Loader/StringLoader.php b/core/lib/Drupal/Core/Template/Loader/StringLoader.php
index 5049c6a48637964da78066c3f9bdc91e5ca35eb2..97c8f3be8f17dd9d5b175d8e0e11323a109441b5 100644
--- a/core/lib/Drupal/Core/Template/Loader/StringLoader.php
+++ b/core/lib/Drupal/Core/Template/Loader/StringLoader.php
@@ -29,7 +29,7 @@ class StringLoader implements LoaderInterface {
    * {@inheritdoc}
    */
   public function exists($name) {
-    if (strpos($name, '{# inline_template_start #}') === 0) {
+    if (str_starts_with($name, '{# inline_template_start #}')) {
       return TRUE;
     }
     else {
diff --git a/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php b/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php
index 7c2f44f6b7527d09e3622e9f508bd70825d5c5fb..89a7a7522e4d5ff77b15cb040cde7cb43a912e81 100644
--- a/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php
+++ b/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php
@@ -74,7 +74,7 @@ protected function storage() {
    * {@inheritdoc}
    */
   public function generateKey(string $name, string $className): string {
-    if (strpos($name, '{# inline_template_start #}') === 0) {
+    if (str_starts_with($name, '{# inline_template_start #}')) {
       // $name is an inline template, and can have characters that are not valid
       // for a filename. $suffix is unique for each inline template so we just
       // use the generic name 'inline-template' here.
diff --git a/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
index c10ad6932381f8e33b40b053521fab9175cee8f9..42d1811877e8890183047c14ce1a55397138dd43 100644
--- a/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
+++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
@@ -101,7 +101,7 @@ public function checkMethodAllowed($obj, $method): void {
     // If the method name starts with an allowed prefix, allow it. Note:
     // strpos() is between 3x and 7x faster than preg_match() in this case.
     foreach ($this->allowed_prefixes as $prefix) {
-      if (strpos($method, $prefix) === 0) {
+      if (str_starts_with($method, $prefix)) {
         return;
       }
     }
diff --git a/core/lib/Drupal/Core/Update/UpdateRegistry.php b/core/lib/Drupal/Core/Update/UpdateRegistry.php
index d5c8108842fb69a1491204de7e954528ef73c9b1..be0711a5c40222a4fcb6c001d366d54271d1cd5f 100644
--- a/core/lib/Drupal/Core/Update/UpdateRegistry.php
+++ b/core/lib/Drupal/Core/Update/UpdateRegistry.php
@@ -288,7 +288,7 @@ public function filterOutInvokedUpdatesByExtension(string $extension) {
     $existing_update_functions = $this->keyValue->get('existing_updates', []);
 
     $remaining_update_functions = array_filter($existing_update_functions, function ($function_name) use ($extension) {
-      return strpos($function_name, "{$extension}_{$this->updateType}_") !== 0;
+      return !str_starts_with($function_name, "{$extension}_{$this->updateType}_");
     });
 
     $this->keyValue->set('existing_updates', array_values($remaining_update_functions));
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index 2f1cee32fe9eb0c57a1d3272be85952f1903f872..cdec8e62f97667b286fa53349f2f98775c27b2fd 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -212,7 +212,7 @@ public static function fromUserInput($user_input, $options = []) {
     // passed is a relative URI reference rather than an absolute URI,
     // because these are URI reserved characters that a scheme name may not
     // start with.
-    if ((strpos($user_input, '/') !== 0) && (strpos($user_input, '#') !== 0) && (strpos($user_input, '?') !== 0)) {
+    if (!str_starts_with($user_input, '/') && !str_starts_with($user_input, '#') && !str_starts_with($user_input, '?')) {
       throw new \InvalidArgumentException("The user-entered string '$user_input' must begin with a '/', '?', or '#'.");
     }
 
@@ -286,7 +286,7 @@ public static function fromUri($uri, $options = []) {
       throw new \InvalidArgumentException("The URI '$uri' is malformed.");
     }
     // We support protocol-relative URLs.
-    if (strpos($uri, '//') === 0) {
+    if (str_starts_with($uri, '//')) {
       $uri_parts['scheme'] = '';
     }
     elseif (empty($uri_parts['scheme'])) {
diff --git a/core/lib/Drupal/Core/Utility/ProjectInfo.php b/core/lib/Drupal/Core/Utility/ProjectInfo.php
index d51f558b3f61d40d9be6e5042c20b094a2ce0121..a9604f0e313f81284b3f242b1368b08bae44e0fc 100644
--- a/core/lib/Drupal/Core/Utility/ProjectInfo.php
+++ b/core/lib/Drupal/Core/Utility/ProjectInfo.php
@@ -153,7 +153,7 @@ public function getProjectName(Extension $file) {
     if (isset($file->info['project'])) {
       $project_name = $file->info['project'];
     }
-    elseif (strpos($file->getPath(), 'core/modules') === 0) {
+    elseif (str_starts_with($file->getPath(), 'core/modules')) {
       $project_name = 'drupal';
     }
     return $project_name;
diff --git a/core/lib/Drupal/Core/Validation/DrupalTranslator.php b/core/lib/Drupal/Core/Validation/DrupalTranslator.php
index 90542fd98dae7721a36b59c41228724f28121f50..6654f4e719bc805b311a99197c3f2a2db4be8741 100644
--- a/core/lib/Drupal/Core/Validation/DrupalTranslator.php
+++ b/core/lib/Drupal/Core/Validation/DrupalTranslator.php
@@ -86,7 +86,7 @@ protected function processParameters(array $parameters) {
         // replacement strings.
       }
       // Check for symfony replacement patterns in the form "{{ name }}".
-      elseif (strpos($key, '{{ ') === 0 && strrpos($key, ' }}') == strlen($key) - 3) {
+      elseif (str_starts_with($key, '{{ ') && strrpos($key, ' }}') == strlen($key) - 3) {
         // Transform it into a Drupal pattern using the format %name.
         $key = '%' . substr($key, 3, strlen($key) - 6);
         $return[$key] = $value;
diff --git a/core/modules/block/block.api.php b/core/modules/block/block.api.php
index 8c2e5b0b0bed092ac0d6e2636076bc8b25482764..14e5ecc08d58fa90df794ac75b86cea281d55c84 100644
--- a/core/modules/block/block.api.php
+++ b/core/modules/block/block.api.php
@@ -227,7 +227,7 @@ function hook_block_access(\Drupal\block\Entity\Block $block, $operation, \Drupa
  */
 function hook_block_alter(&$definitions) {
   foreach ($definitions as $id => $definition) {
-    if (strpos($id, 'system_menu_block:') === 0) {
+    if (str_starts_with($id, 'system_menu_block:')) {
       // Replace $definition properties: id, deriver, class, provider to ones
       // provided by this custom module.
     }
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 11bb4492b57d9ba8ab8891f15131734b285b1d47..8105812c9c89667057af78cf1557084fac748eb5 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -127,7 +127,7 @@ function block_theme_initialize($theme) {
     $regions = system_region_list($theme, REGIONS_VISIBLE);
     $default_theme_blocks = \Drupal::entityTypeManager()->getStorage('block')->loadByProperties(['theme' => $default_theme]);
     foreach ($default_theme_blocks as $default_theme_block_id => $default_theme_block) {
-      if (strpos($default_theme_block_id, $default_theme . '_') === 0) {
+      if (str_starts_with($default_theme_block_id, $default_theme . '_')) {
         $id = str_replace($default_theme, $theme, $default_theme_block_id);
       }
       else {
diff --git a/core/modules/ckeditor5/src/Plugin/CKEditor5PluginManager.php b/core/modules/ckeditor5/src/Plugin/CKEditor5PluginManager.php
index 3558ab407bc0afc7f8c3cf063fe0a0bde340d838..5f900126b1b14edbecbc531ebe52343531542cdf 100644
--- a/core/modules/ckeditor5/src/Plugin/CKEditor5PluginManager.php
+++ b/core/modules/ckeditor5/src/Plugin/CKEditor5PluginManager.php
@@ -89,7 +89,7 @@ public function processDefinition(&$definition, $plugin_id) {
 
     $expected_prefix = sprintf("%s_", $definition->getProvider());
     $id = $definition->id();
-    if (strpos($id, $expected_prefix) !== 0) {
+    if (!str_starts_with($id, $expected_prefix)) {
       throw new InvalidPluginDefinitionException($id, sprintf('The "%s" CKEditor 5 plugin definition must have a plugin ID that starts with "%s".', $id, $expected_prefix));
     }
 
diff --git a/core/modules/config/src/Form/ConfigSingleExportForm.php b/core/modules/config/src/Form/ConfigSingleExportForm.php
index dc46b45814d3d74be43605b5741b7da954735f10..c31daca71f6d07c220978f6fb8a5b1338ab5dc2d 100644
--- a/core/modules/config/src/Form/ConfigSingleExportForm.php
+++ b/core/modules/config/src/Form/ConfigSingleExportForm.php
@@ -191,7 +191,7 @@ protected function findConfiguration($config_type) {
       $names = array_combine($names, $names);
       foreach ($names as $config_name) {
         foreach ($config_prefixes as $config_prefix) {
-          if (strpos($config_name, $config_prefix) === 0) {
+          if (str_starts_with($config_name, $config_prefix)) {
             unset($names[$config_name]);
           }
         }
diff --git a/core/modules/config/src/StorageReplaceDataWrapper.php b/core/modules/config/src/StorageReplaceDataWrapper.php
index 91c3a7cfcc1748be5ce1c89c1a23739bc90be6af..8c9fa138a72f573302303c78f000b098b47a5e8f 100644
--- a/core/modules/config/src/StorageReplaceDataWrapper.php
+++ b/core/modules/config/src/StorageReplaceDataWrapper.php
@@ -133,7 +133,7 @@ public function listAll($prefix = '') {
     }
     else {
       foreach (array_keys($this->replacementData[$this->collection]) as $name) {
-        if (strpos($name, $prefix) === 0) {
+        if (str_starts_with($name, $prefix)) {
           $additional_names[] = $name;
         }
       }
@@ -153,7 +153,7 @@ public function deleteAll($prefix = '') {
     }
     else {
       foreach (array_keys($this->replacementData[$this->collection]) as $name) {
-        if (strpos($name, $prefix) === 0) {
+        if (str_starts_with($name, $prefix)) {
           unset($this->replacementData[$this->collection][$name]);
         }
       }
diff --git a/core/modules/config/tests/config_test/src/ConfigValidation.php b/core/modules/config/tests/config_test/src/ConfigValidation.php
index afb86c34c9fc7d5b8539216174a354a92383af7f..511aad0294876901dd29ac035e55a3ea06acee9e 100644
--- a/core/modules/config/tests/config_test/src/ConfigValidation.php
+++ b/core/modules/config/tests/config_test/src/ConfigValidation.php
@@ -60,7 +60,7 @@ public static function validateCatCount($count, ExecutionContextInterface $conte
    *   The validation execution context.
    */
   public static function validateGiraffes($string, ExecutionContextInterface $context) {
-    if (strpos($string, 'hum') !== 0) {
+    if (!str_starts_with($string, 'hum')) {
       $context->addViolation('Giraffes just hum');
     }
   }
diff --git a/core/modules/content_moderation/content_moderation.module b/core/modules/content_moderation/content_moderation.module
index 2652e2d257fe76530790540af547bd2d1562843d..f6ab8657ca3a40c8162d4105e3ecae714ce193b5 100644
--- a/core/modules/content_moderation/content_moderation.module
+++ b/core/modules/content_moderation/content_moderation.module
@@ -437,7 +437,7 @@ function content_moderation_views_post_execute(ViewExecutable $view) {
   // @todo, remove this once broken handlers in views configuration result in
   // a view no longer returning results. https://www.drupal.org/node/2907954.
   foreach ($view->filter as $id => $filter) {
-    if (strpos($id, 'moderation_state') === 0 && $filter instanceof Broken) {
+    if (str_starts_with($id, 'moderation_state') && $filter instanceof Broken) {
       $view->result = [];
       break;
     }
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index 0e0a547dbe0b5493b23fa8e75151ccc69209b951..a05537586f00eb9da32060fcd801964d25be7d1c 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -678,7 +678,7 @@ function content_translation_page_attachments(&$page) {
 
   // Determine if the current route represents an entity.
   foreach ($parameters as $name => $options) {
-    if (!isset($options['type']) || strpos($options['type'], 'entity:') !== 0) {
+    if (!isset($options['type']) || !str_starts_with($options['type'], 'entity:')) {
       continue;
     }
 
diff --git a/core/modules/field/src/ConfigImporterFieldPurger.php b/core/modules/field/src/ConfigImporterFieldPurger.php
index 22bf7c2058a912a0b552aa1419b7f1fce0080241..b2efb68d22dd6a5012278ca30d07c647a7faf758 100644
--- a/core/modules/field/src/ConfigImporterFieldPurger.php
+++ b/core/modules/field/src/ConfigImporterFieldPurger.php
@@ -118,7 +118,7 @@ public static function getFieldStoragesToPurge(array $extensions, array $deletes
     $field_storage_ids = [];
     foreach ($deletes as $config_name) {
       $field_storage_config_prefix = \Drupal::entityTypeManager()->getDefinition('field_storage_config')->getConfigPrefix();
-      if (strpos($config_name, $field_storage_config_prefix . '.') === 0) {
+      if (str_starts_with($config_name, $field_storage_config_prefix . '.')) {
         $field_storage_ids[] = ConfigEntityStorage::getIDFromConfigName($config_name, $field_storage_config_prefix);
       }
     }
diff --git a/core/modules/file/file.api.php b/core/modules/file/file.api.php
index 8c2cb93b7ba659b409cb0667bc743d2f7ce181e6..429dbd037814c86aac25ddce9183dd65562ca619 100644
--- a/core/modules/file/file.api.php
+++ b/core/modules/file/file.api.php
@@ -98,7 +98,7 @@ function hook_file_validate(\Drupal\file\FileInterface $file) {
  */
 function hook_file_copy(\Drupal\file\FileInterface $file, \Drupal\file\FileInterface $source) {
   // Make sure that the file name starts with the owner's user name.
-  if (strpos($file->getFilename(), $file->getOwner()->name) !== 0) {
+  if (!str_starts_with($file->getFilename(), $file->getOwner()->name)) {
     $file->setFilename($file->getOwner()->name . '_' . $file->getFilename());
     $file->save();
 
@@ -118,7 +118,7 @@ function hook_file_copy(\Drupal\file\FileInterface $file, \Drupal\file\FileInter
  */
 function hook_file_move(\Drupal\file\FileInterface $file, \Drupal\file\FileInterface $source) {
   // Make sure that the file name starts with the owner's user name.
-  if (strpos($file->getFilename(), $file->getOwner()->name) !== 0) {
+  if (!str_starts_with($file->getFilename(), $file->getOwner()->name)) {
     $file->setFilename($file->getOwner()->name . '_' . $file->getFilename());
     $file->save();
 
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index d8c9ab3a02d8b5499f0649191c33427540a00304..63f50c730160fa99ae0b1319dbed0c187347538d 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -915,7 +915,7 @@ function file_managed_file_submit($form, FormStateInterface $form_state) {
     if ($element['#multiple']) {
       $remove_fids = [];
       foreach (Element::children($element) as $name) {
-        if (strpos($name, 'file_') === 0 && $element[$name]['selected']['#value']) {
+        if (str_starts_with($name, 'file_') && $element[$name]['selected']['#value']) {
           $remove_fids[] = (int) substr($name, 5);
         }
       }
@@ -1096,7 +1096,7 @@ function file_icon_class($mime_type) {
 
   // Use generic icons for each category that provides such icons.
   foreach (['audio', 'image', 'text', 'video'] as $category) {
-    if (strpos($mime_type, $category) === 0) {
+    if (str_starts_with($mime_type, $category)) {
       return $category;
     }
   }
diff --git a/core/modules/filter/src/Plugin/Filter/FilterHtml.php b/core/modules/filter/src/Plugin/Filter/FilterHtml.php
index e4474320c39bd94b5869bb6313a22108331cef73..88cf3484a0aad5ad973ad8c1fa80926285e73e6b 100644
--- a/core/modules/filter/src/Plugin/Filter/FilterHtml.php
+++ b/core/modules/filter/src/Plugin/Filter/FilterHtml.php
@@ -203,7 +203,7 @@ protected function findAllowedValue(array $allowed, $name) {
     }
     // Handle prefix (wildcard) matches.
     foreach ($allowed['prefix'] as $prefix => $value) {
-      if (strpos($name, $prefix) === 0) {
+      if (str_starts_with($name, $prefix)) {
         return $value;
       }
     }
diff --git a/core/modules/help_topics/tests/src/Functional/HelpTopicsSyntaxTest.php b/core/modules/help_topics/tests/src/Functional/HelpTopicsSyntaxTest.php
index 06d288933629a0bd0a5020e854a1869f40d0853e..db3b6ad5d3ba1b52cc1a6433e71fe99c92d9a65a 100644
--- a/core/modules/help_topics/tests/src/Functional/HelpTopicsSyntaxTest.php
+++ b/core/modules/help_topics/tests/src/Functional/HelpTopicsSyntaxTest.php
@@ -60,7 +60,7 @@ public function testHelpTopics() {
     // Filter out directories outside of core. If you want to run this test
     // on a contrib/custom module, remove the next line.
     $directories = array_filter($directories, function ($directory) {
-      return strpos($directory, 'core') === 0;
+      return str_starts_with($directory, 'core');
     });
 
     // Verify that a few key modules, themes, and profiles are listed, so that
@@ -80,7 +80,7 @@ public function testHelpTopics() {
     // Test each topic for compliance with standards, or for failing in the
     // right way.
     foreach (array_keys($definitions) as $id) {
-      if (strpos($id, 'bad_help_topics.') === 0) {
+      if (str_starts_with($id, 'bad_help_topics.')) {
         $this->verifyBadTopic($id, $definitions);
       }
       else {
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index aa9faef2d4e14de2148b29017bb9a52e30b8ee85..59127a41b9eaa46f7f2bb158ad676cc3592de437 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -139,7 +139,7 @@ function image_file_download($uri) {
   $path = StreamWrapperManager::getTarget($uri);
 
   // Private file access for image style derivatives.
-  if (strpos($path, 'styles/') === 0) {
+  if (str_starts_with($path, 'styles/')) {
     $args = explode('/', $path);
 
     // Discard "styles", style name, and scheme from the path
diff --git a/core/modules/image/src/Controller/ImageStyleDownloadController.php b/core/modules/image/src/Controller/ImageStyleDownloadController.php
index 775949dcb61b714860281b642e483ca64f7bf774..b077c93336a97726152b1b2d255831784b893fd4 100644
--- a/core/modules/image/src/Controller/ImageStyleDownloadController.php
+++ b/core/modules/image/src/Controller/ImageStyleDownloadController.php
@@ -125,7 +125,7 @@ public function deliver(Request $request, $scheme, ImageStyleInterface $image_st
     // starts with styles/.
     $token = $request->query->get(IMAGE_DERIVATIVE_TOKEN, '');
     $token_is_valid = hash_equals($image_style->getPathToken($image_uri), $token);
-    if (!$this->config('image.settings')->get('allow_insecure_derivatives') || strpos(ltrim($target, '\/'), 'styles/') === 0) {
+    if (!$this->config('image.settings')->get('allow_insecure_derivatives') || str_starts_with(ltrim($target, '\/'), 'styles/')) {
       $valid = $valid && $token_is_valid;
     }
 
@@ -249,7 +249,7 @@ private function sourceImageExists(string $image_uri, bool $token_is_valid): boo
     $private_path = Settings::get('file_private_path');
     if ($private_path) {
       $private_path = realpath($private_path);
-      if ($private_path && strpos($image_path, $private_path) === 0) {
+      if ($private_path && str_starts_with($image_path, $private_path)) {
         return FALSE;
       }
     }
diff --git a/core/modules/jsonapi/src/Controller/EntityResource.php b/core/modules/jsonapi/src/Controller/EntityResource.php
index 541fbd06795aab42a1ca34dfeb4f626e9bd705c5..20d9c06da69e98351fc325b56bc431c8d35eb921 100644
--- a/core/modules/jsonapi/src/Controller/EntityResource.php
+++ b/core/modules/jsonapi/src/Controller/EntityResource.php
@@ -429,7 +429,7 @@ public function getCollection(ResourceType $resource_type, Request $request) {
       // For example: getting users with a particular role, which is a config
       // entity type: https://www.drupal.org/project/drupal/issues/2959445.
       // @todo Remove the message parsing in https://www.drupal.org/project/drupal/issues/3028967.
-      if (strpos($e->getMessage(), 'Getting the base fields is not supported for entity type') === 0) {
+      if (str_starts_with($e->getMessage(), 'Getting the base fields is not supported for entity type')) {
         preg_match('/entity type (.*)\./', $e->getMessage(), $matches);
         $config_entity_type_id = $matches[1];
         $cacheability = (new CacheableMetadata())->addCacheContexts(['url.path', 'url.query_args:filter']);
diff --git a/core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php b/core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php
index 3cae9f8e9d5d945d62817f2d88d558e1cbd7969e..a7910a1f9cffd23d2acb9d4aa8f78341a6179e59 100644
--- a/core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php
+++ b/core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php
@@ -84,7 +84,7 @@ public function convert($value, $definition, $name, array $defaults) {
   public function applies($definition, $name, Route $route) {
     return (
       (bool) Routes::getResourceTypeNameFromParameters($route->getDefaults()) &&
-      !empty($definition['type']) && strpos($definition['type'], 'entity') === 0
+      !empty($definition['type']) && str_starts_with($definition['type'], 'entity')
     );
   }
 
diff --git a/core/modules/jsonapi/src/Revisions/VersionNegotiator.php b/core/modules/jsonapi/src/Revisions/VersionNegotiator.php
index 857582a4119f657655348dfd32c7c7573f47bc86..d0e2d9a822c62e321a6ee8c82020be80c3f37fba 100644
--- a/core/modules/jsonapi/src/Revisions/VersionNegotiator.php
+++ b/core/modules/jsonapi/src/Revisions/VersionNegotiator.php
@@ -43,7 +43,7 @@ class VersionNegotiator {
    *   The name of the negotiation strategy used by the version negotiator.
    */
   public function addVersionNegotiator(VersionNegotiatorInterface $version_negotiator, $negotiator_name) {
-    assert(strpos(get_class($version_negotiator), 'Drupal\\jsonapi\\') === 0, 'Version negotiators are not a public API.');
+    assert(str_starts_with(get_class($version_negotiator), 'Drupal\\jsonapi\\'), 'Version negotiators are not a public API.');
     $this->negotiators[$negotiator_name] = $version_negotiator;
   }
 
diff --git a/core/modules/jsonapi/src/Routing/Routes.php b/core/modules/jsonapi/src/Routing/Routes.php
index 609ed91312a091fd2c0b5e17c921c9b4fab24967..f4766f5a875b9d9e5f32cb0f17b568375996a72f 100644
--- a/core/modules/jsonapi/src/Routing/Routes.php
+++ b/core/modules/jsonapi/src/Routing/Routes.php
@@ -265,7 +265,7 @@ protected static function getFileUploadRoutesForResourceType(ResourceType $resou
    */
   public static function isJsonApiRequest(array $defaults) {
     return isset($defaults[RouteObjectInterface::CONTROLLER_NAME])
-      && strpos($defaults[RouteObjectInterface::CONTROLLER_NAME], static::CONTROLLER_SERVICE_NAME) === 0;
+      && str_starts_with($defaults[RouteObjectInterface::CONTROLLER_NAME], static::CONTROLLER_SERVICE_NAME);
   }
 
   /**
diff --git a/core/modules/jsonapi/src/Serializer/Serializer.php b/core/modules/jsonapi/src/Serializer/Serializer.php
index 2541bc4206dce1b6258dca712ad06a2b5607df59..e93243ae6f5878db7ec16756583b33b98c1d2640 100644
--- a/core/modules/jsonapi/src/Serializer/Serializer.php
+++ b/core/modules/jsonapi/src/Serializer/Serializer.php
@@ -34,7 +34,7 @@ final class Serializer extends SymfonySerializer {
    */
   public function __construct(array $normalizers = [], array $encoders = []) {
     foreach ($normalizers as $normalizer) {
-      if (strpos(get_class($normalizer), 'Drupal\jsonapi\Normalizer') !== 0) {
+      if (!str_starts_with(get_class($normalizer), 'Drupal\jsonapi\Normalizer')) {
         throw new \LogicException('JSON:API does not allow adding more normalizers!');
       }
     }
diff --git a/core/modules/jsonapi/tests/modules/jsonapi_test_field_aliasing/src/ResourceType/AliasingResourceTypeRepository.php b/core/modules/jsonapi/tests/modules/jsonapi_test_field_aliasing/src/ResourceType/AliasingResourceTypeRepository.php
index f50e098253faa9425c24f890d9fe80ad9f2eeabb..f4e2bf3750c51d94c2f679dbf5ac879708139cf3 100644
--- a/core/modules/jsonapi/tests/modules/jsonapi_test_field_aliasing/src/ResourceType/AliasingResourceTypeRepository.php
+++ b/core/modules/jsonapi/tests/modules/jsonapi_test_field_aliasing/src/ResourceType/AliasingResourceTypeRepository.php
@@ -16,7 +16,7 @@ class AliasingResourceTypeRepository extends ResourceTypeRepository {
   protected function getFields(array $field_names, EntityTypeInterface $entity_type, $bundle) {
     $fields = parent::getFields($field_names, $entity_type, $bundle);
     foreach ($fields as $field_name => $field) {
-      if (strpos($field_name, 'field_test_alias_') === 0) {
+      if (str_starts_with($field_name, 'field_test_alias_')) {
         $fields[$field_name] = $fields[$field_name]->withPublicName('field_test_alias');
       }
     }
diff --git a/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php b/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php
index a08b0163833941aa38a2af0cb7cdbb09c2cb884e..7a2b19a45f7797b2805d337812a52d2df03568fa 100644
--- a/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php
+++ b/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php
@@ -1041,7 +1041,7 @@ public function testGetIndividual() {
     ];
     $header_cleaner = function ($headers) use ($ignored_headers) {
       foreach ($headers as $header => $value) {
-        if (strpos($header, 'X-Drupal-Assertion-') === 0 || in_array($header, $ignored_headers)) {
+        if (str_starts_with($header, 'X-Drupal-Assertion-') || in_array($header, $ignored_headers)) {
           unset($headers[$header]);
         }
       }
@@ -2658,7 +2658,7 @@ protected function doTestSparseFieldSets(Url $url, array $request_options) {
       $expected_cacheability->setCacheTags($this->getExpectedCacheTags($field_set));
       $expected_cacheability->setCacheContexts($this->getExpectedCacheContexts($field_set));
       // This tests sparse field sets on included entities.
-      if (strpos($type, 'nested') === 0) {
+      if (str_starts_with($type, 'nested')) {
         $this->grantPermissionsToTestedRole(['access user profiles']);
         $query['fields[user--user]'] = implode(',', $field_set);
         $query['include'] = 'uid';
diff --git a/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php b/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
index 12b5693140791f508728ab5afb2f2c7d2807c379..6134c0871ff2aaeb32a3892c61942307136d7a70 100644
--- a/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
+++ b/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
@@ -475,7 +475,7 @@ public function testAliasFieldRouteException() {
       )->getNormalization();
     $this->assertNotEmpty($jsonapi_doc_object['meta']['omitted']);
     foreach ($jsonapi_doc_object['meta']['omitted']['links'] as $key => $link) {
-      if (strpos($key, 'item--') === 0) {
+      if (str_starts_with($key, 'item--')) {
         // Ensure that resource link contains url with the alias field.
         $resource_link = Url::fromUri('internal:/jsonapi/user/user/' . $user->uuid() . '/user_roles')->setAbsolute()->toString(TRUE);
         $this->assertEquals($resource_link->getGeneratedUrl(), $link['href']);
diff --git a/core/modules/layout_builder/layout_builder.module b/core/modules/layout_builder/layout_builder.module
index 1646139aa7bf8aed43d3d91c698a6311746a7215..e71dfaa84c9214d59386cb5519a04c6d0b0edfe7 100644
--- a/core/modules/layout_builder/layout_builder.module
+++ b/core/modules/layout_builder/layout_builder.module
@@ -158,7 +158,7 @@ function layout_builder_entity_view_alter(array &$build, EntityInterface $entity
   // If the entity is displayed within a Layout Builder block and the current
   // route is in the Layout Builder UI, then remove all contextual link
   // placeholders.
-  if ($display instanceof LayoutBuilderEntityViewDisplay && strpos($route_name, 'layout_builder.') === 0) {
+  if ($display instanceof LayoutBuilderEntityViewDisplay && str_starts_with($route_name, 'layout_builder.')) {
     unset($build['#contextual_links']);
   }
 }
diff --git a/core/modules/layout_builder/src/Cache/LayoutBuilderUiCacheContext.php b/core/modules/layout_builder/src/Cache/LayoutBuilderUiCacheContext.php
index 4626d1cd86df4ca411c2e0628997bf7cdca8a8e3..a4946f6b4ed875b78bc8e13833964bf8a1b3454c 100644
--- a/core/modules/layout_builder/src/Cache/LayoutBuilderUiCacheContext.php
+++ b/core/modules/layout_builder/src/Cache/LayoutBuilderUiCacheContext.php
@@ -25,7 +25,7 @@ public static function getLabel() {
    * {@inheritdoc}
    */
   public function getContext() {
-    return 'is_layout_builder_ui.' . (int) (strpos($this->routeMatch->getRouteName(), 'layout_builder.') !== 0);
+    return 'is_layout_builder_ui.' . (int) !str_starts_with($this->routeMatch->getRouteName(), 'layout_builder.');
   }
 
 }
diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php
index 4474947a7ecadfac42baa9c038332d01670e5365..b2024f26486ff4794df4c4bf068fce4906b4273f 100644
--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php
+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php
@@ -116,7 +116,7 @@ public function testBlockFilter() {
     $this->assertCount(0, $visible_categories);
     $announce_element = $page->find('css', '#drupal-live-announce');
     $page->waitFor(2, function () use ($announce_element) {
-      return strpos($announce_element->getText(), '0 blocks are available') === 0;
+      return str_starts_with($announce_element->getText(), '0 blocks are available');
     });
 
     // Test Drupal.announce() message when all blocks are listed.
diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
index ebc3ee61e99fa797c6ef8a503d34cb0e1b8e6252..8bee9d98064d87fe9b88dbdff8c0929f66e742b2 100644
--- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -125,7 +125,7 @@ protected static function getUserEnteredStringAsUri($string) {
       //   https://www.drupal.org/node/2421941
       // - '<front>' -> '/'
       // - '<front>#foo' -> '/#foo'
-      if (strpos($string, '<front>') === 0) {
+      if (str_starts_with($string, '<front>')) {
         $string = '/' . substr($string, strlen('<front>'));
       }
       $uri = 'internal:' . $string;
diff --git a/core/modules/link/src/Plugin/migrate/process/FieldLink.php b/core/modules/link/src/Plugin/migrate/process/FieldLink.php
index c3efed474d41e7bf2bc4a7d65bb4dee8f9b31748..0bea5203a9aef09b27d3e0e488642d3a0f292eae 100644
--- a/core/modules/link/src/Plugin/migrate/process/FieldLink.php
+++ b/core/modules/link/src/Plugin/migrate/process/FieldLink.php
@@ -62,7 +62,7 @@ protected function canonicalizeUri($uri) {
     // If the path starts with 2 slashes then it is always considered an
     // external URL without an explicit protocol part.
     // @todo Remove this when https://www.drupal.org/node/2744729 lands.
-    if (strpos($uri, '//') === 0) {
+    if (str_starts_with($uri, '//')) {
       return $this->configuration['uri_scheme'] . ltrim($uri, '/');
     }
 
@@ -77,7 +77,7 @@ protected function canonicalizeUri($uri) {
     }
 
     // Remove the <front> component of the URL.
-    if (strpos($uri, '<front>') === 0) {
+    if (str_starts_with($uri, '<front>')) {
       $uri = substr($uri, strlen('<front>'));
     }
     else {
diff --git a/core/modules/locale/src/LocaleDefaultConfigStorage.php b/core/modules/locale/src/LocaleDefaultConfigStorage.php
index d68d71804106397452457486b357324741bde217..c99dabd0df9f4c489893f932708f9ed55d67115c 100644
--- a/core/modules/locale/src/LocaleDefaultConfigStorage.php
+++ b/core/modules/locale/src/LocaleDefaultConfigStorage.php
@@ -83,7 +83,7 @@ public function read($name) {
     elseif ($this->optionalInstallStorage->exists($name)) {
       return $this->optionalInstallStorage->read($name);
     }
-    elseif (strpos($name, 'language.entity.') === 0) {
+    elseif (str_starts_with($name, 'language.entity.')) {
       // Simulate default languages as if they were shipped as default
       // configuration.
       $langcode = str_replace('language.entity.', '', $name);
diff --git a/core/modules/media_library/media_library.module b/core/modules/media_library/media_library.module
index 0c8e197f836932d0be795ebcf3ddf03ffbfedcb7..6e8a8e58a34106d5a83713079b0707f9cc7c6395 100644
--- a/core/modules/media_library/media_library.module
+++ b/core/modules/media_library/media_library.module
@@ -165,7 +165,7 @@ function media_library_views_pre_render(ViewExecutable $view) {
         $add_classes($view->field['media_bulk_form']->options['element_class'], ['js-click-to-select-checkbox']);
       }
     }
-    elseif (strpos($view->current_display, 'widget') === 0) {
+    elseif (str_starts_with($view->current_display, 'widget')) {
       if (array_key_exists('media_library_select_form', $view->field)) {
         $add_classes($view->field['media_library_select_form']->options['element_wrapper_class'], ['js-click-to-select-checkbox']);
       }
@@ -189,7 +189,7 @@ function media_library_views_pre_render(ViewExecutable $view) {
 function media_library_views_post_render(ViewExecutable $view, &$output, CachePluginBase $cache) {
   if ($view->id() === 'media_library') {
     $output['#attached']['library'][] = 'media_library/view';
-    if (strpos($view->current_display, 'widget') === 0) {
+    if (str_starts_with($view->current_display, 'widget')) {
       try {
         $query = MediaLibraryState::fromRequest($view->getRequest())->all();
       }
@@ -291,7 +291,7 @@ function media_library_form_views_form_media_library_page_alter(array &$form, Fo
 function media_library_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
   // Add a process callback to ensure that the media library view's exposed
   // filters submit button is not moved to the modal dialog's button area.
-  if ($form_id === 'views_exposed_form' && strpos($form['#id'], 'views-exposed-form-media-library-widget') === 0) {
+  if ($form_id === 'views_exposed_form' && str_starts_with($form['#id'], 'views-exposed-form-media-library-widget')) {
     $form['#after_build'][] = '_media_library_views_form_media_library_after_build';
   }
 
diff --git a/core/modules/menu_link_content/menu_link_content.module b/core/modules/menu_link_content/menu_link_content.module
index a593bef4e3c986e376e6fb8b58f66a0faad087aa..057a22842f395cf461710fda4244ab3fd483df1b 100644
--- a/core/modules/menu_link_content/menu_link_content.module
+++ b/core/modules/menu_link_content/menu_link_content.module
@@ -120,7 +120,7 @@ function menu_link_content_entity_predelete(EntityInterface $entity) {
 
     if ($result) {
       foreach ($result as $id => $instance) {
-        if ($instance->isDeletable() && strpos($id, 'menu_link_content:') === 0) {
+        if ($instance->isDeletable() && str_starts_with($id, 'menu_link_content:')) {
           $instance->deleteLink();
         }
       }
diff --git a/core/modules/menu_ui/tests/src/Traits/MenuUiTrait.php b/core/modules/menu_ui/tests/src/Traits/MenuUiTrait.php
index 0d0d14bf0d75492368e06c526daee8de8f994d3c..d9eaa78c67f9b566783e68de6b4e34d968dfbd06 100644
--- a/core/modules/menu_ui/tests/src/Traits/MenuUiTrait.php
+++ b/core/modules/menu_ui/tests/src/Traits/MenuUiTrait.php
@@ -27,7 +27,7 @@ protected function assertMenuLink(array $expected_item, $menu_plugin_id) {
     $entity = NULL;
 
     // Pull the path from the menu link content.
-    if (strpos($menu_plugin_id, 'menu_link_content') === 0) {
+    if (str_starts_with($menu_plugin_id, 'menu_link_content')) {
       [, $uuid] = explode(':', $menu_plugin_id, 2);
       /** @var \Drupal\menu_link_content\Entity\MenuLinkContent $entity */
       $entity = \Drupal::service('entity.repository')
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/FieldableEntity.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/FieldableEntity.php
index ba724872192bcca1d76d2abcd2f8e63b1fb390d8..1e75872be6ae5d337c947d9f644643ed7fbfd7e3 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/FieldableEntity.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/FieldableEntity.php
@@ -92,7 +92,7 @@ protected function getFieldValues($entity_type, $field, $entity_id, $revision_id
     foreach ($query->execute() as $row) {
       foreach ($row as $key => $value) {
         $delta = $row['delta'];
-        if (strpos($key, $field) === 0) {
+        if (str_starts_with($key, $field)) {
           $column = substr($key, strlen($field) + 1);
           $values[$delta][$column] = $value;
         }
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index 46e58e7b0b3f6e0c4ecc8f1d050cbe763ce1d540..d87c4b39e7d8e7577f23d104e9c14e29f2bd4834 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -599,7 +599,7 @@ public function testGet() {
     $ignored_headers = ['Date', 'Content-Length', 'X-Drupal-Cache', 'X-Drupal-Dynamic-Cache', 'Transfer-Encoding', 'Vary'];
     $header_cleaner = function ($headers) use ($ignored_headers) {
       foreach ($headers as $header => $value) {
-        if (strpos($header, 'X-Drupal-Assertion-') === 0 || in_array($header, $ignored_headers)) {
+        if (str_starts_with($header, 'X-Drupal-Assertion-') || in_array($header, $ignored_headers)) {
           unset($headers[$header]);
         }
       }
diff --git a/core/modules/sqlite/src/Driver/Database/sqlite/Schema.php b/core/modules/sqlite/src/Driver/Database/sqlite/Schema.php
index 1ff5e7d19f9ffeb167a50aca01641aaca4a30c39..eb836eb453635d4d866179ee5a2339378d731b2e 100644
--- a/core/modules/sqlite/src/Driver/Database/sqlite/Schema.php
+++ b/core/modules/sqlite/src/Driver/Database/sqlite/Schema.php
@@ -541,7 +541,7 @@ protected function introspectSchema($table) {
     $indexes = [];
     $result = $this->connection->query('PRAGMA [' . $info['schema'] . '].index_list([' . $info['table'] . '])');
     foreach ($result as $row) {
-      if (strpos($row->name, 'sqlite_autoindex_') !== 0) {
+      if (!str_starts_with($row->name, 'sqlite_autoindex_')) {
         $indexes[] = [
           'schema_key' => $row->unique ? 'unique keys' : 'indexes',
           'name' => $row->name,
diff --git a/core/modules/system/src/EventSubscriber/AdminRouteSubscriber.php b/core/modules/system/src/EventSubscriber/AdminRouteSubscriber.php
index 7c1d9a30a5401a271acdc21bb0bb5fa073741675..cdeca6691b3242806dfe40ce773ee4576d432fdc 100644
--- a/core/modules/system/src/EventSubscriber/AdminRouteSubscriber.php
+++ b/core/modules/system/src/EventSubscriber/AdminRouteSubscriber.php
@@ -18,7 +18,7 @@ class AdminRouteSubscriber extends RouteSubscriberBase {
   protected function alterRoutes(RouteCollection $collection) {
     foreach ($collection->all() as $route) {
       $path = $route->getPath();
-      if (($path == '/admin' || strpos($path, '/admin/') === 0) && !$route->hasOption('_admin_route') && static::isHtmlRoute($route)) {
+      if (($path == '/admin' || str_starts_with($path, '/admin/')) && !$route->hasOption('_admin_route') && static::isHtmlRoute($route)) {
         $route->setOption('_admin_route', TRUE);
       }
     }
diff --git a/core/modules/system/src/PathProcessor/PathProcessorFiles.php b/core/modules/system/src/PathProcessor/PathProcessorFiles.php
index 8a120972483791ef74e42d1b8298921ebbe0bcd6..fb38515262ab6d4c6554abb6d9e94231a333788d 100644
--- a/core/modules/system/src/PathProcessor/PathProcessorFiles.php
+++ b/core/modules/system/src/PathProcessor/PathProcessorFiles.php
@@ -17,7 +17,7 @@ class PathProcessorFiles implements InboundPathProcessorInterface {
    * {@inheritdoc}
    */
   public function processInbound($path, Request $request) {
-    if (strpos($path, '/system/files/') === 0 && !$request->query->has('file')) {
+    if (str_starts_with($path, '/system/files/') && !$request->query->has('file')) {
       $file_path = preg_replace('|^\/system\/files\/|', '', $path);
       $request->query->set('file', $file_path);
       return '/system/files';
diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/MockBlockManager.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/MockBlockManager.php
index d53901f6b2c160c7c455eb43d0aa78c44ae78ceb..c993b794ac53d3d9f07cf9c51b9e82985401d9e4 100644
--- a/core/modules/system/tests/modules/plugin_test/src/Plugin/MockBlockManager.php
+++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/MockBlockManager.php
@@ -145,7 +145,7 @@ protected function createContextDefinition($data_type, $label, $required = TRUE)
     // include ContextDefinition objects, and var_export() has problems
     // printing TranslatableMarkup objects.
     $class = ContextDefinition::class;
-    if (strpos($data_type, 'entity:') === 0) {
+    if (str_starts_with($data_type, 'entity:')) {
       $class = EntityContextDefinition::class;
     }
     return new $class($data_type, (string) $label, $required);
diff --git a/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php b/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php
index eb03f83506e88f8798ac01930d972a0da56e0e64..1b6f9c8db13eccc50d4dd76dcc6b1ad00f20faf8 100644
--- a/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php
+++ b/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php
@@ -107,7 +107,7 @@ public function assertModuleConfig($module) {
       // All configuration in a module's config/install directory should depend
       // on the module as it must be removed on uninstall or the module will not
       // be re-installable.
-      $this->assertTrue(strpos($name, $module . '.') === 0 || isset($module_config_dependencies[$name]), "Configuration $name provided by $module in its config/install directory does not depend on it.");
+      $this->assertTrue(str_starts_with($name, $module . '.') || isset($module_config_dependencies[$name]), "Configuration $name provided by $module in its config/install directory does not depend on it.");
     }
     // Verify that all configuration has been installed (which means that $names
     // is empty).
diff --git a/core/modules/taxonomy/src/Form/OverviewTerms.php b/core/modules/taxonomy/src/Form/OverviewTerms.php
index d199c8b10dd407dc980248e5aae3d97f3f4e3676..c73bcf504fe446a634390fa6ef508d064998d935 100644
--- a/core/modules/taxonomy/src/Form/OverviewTerms.php
+++ b/core/modules/taxonomy/src/Form/OverviewTerms.php
@@ -435,7 +435,7 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
 
       // Add an error class if this row contains a form error.
       foreach ($errors as $error_key => $error) {
-        if (strpos($error_key, $key) === 0) {
+        if (str_starts_with($error_key, $key)) {
           $form['terms'][$key]['#attributes']['class'][] = 'error';
         }
       }
diff --git a/core/modules/update/update.compare.inc b/core/modules/update/update.compare.inc
index 8f134037c9631c5afb145a2e60b0b180572ddc05..7b8fc6899cfdca33577c9fa11c8d74a3d8deecbf 100644
--- a/core/modules/update/update.compare.inc
+++ b/core/modules/update/update.compare.inc
@@ -291,7 +291,7 @@ function update_calculate_project_update_status(&$project_data, $available) {
 
   $is_in_supported_branch = function ($version) use ($supported_branches) {
     foreach ($supported_branches as $supported_branch) {
-      if (strpos($version, $supported_branch) === 0) {
+      if (str_starts_with($version, $supported_branch)) {
         return TRUE;
       }
     }
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index 11cbaf44901be7c0e09ba1206fa5def80a92956a..83d65c2bc0c04c0f72ddd71d0b3f76996d6ed17f 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -2637,7 +2637,7 @@ public function getSpecialBlocks() {
   public function viewExposedFormBlocks() {
     // Avoid interfering with the admin forms.
     $route_name = \Drupal::routeMatch()->getRouteName();
-    if (strpos($route_name, 'views_ui.') === 0) {
+    if (str_starts_with($route_name, 'views_ui.')) {
       return;
     }
     $this->view->initHandlers();
diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
index b8eb284a3b567923100e7dfc86bc6f1fcb8211b9..0dbe55ffc669d4e06cb728073413e6fc3cf9b184 100644
--- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -159,7 +159,7 @@ protected function getRoute($view_id, $display_id) {
           $bits[$pos] = '{' . $arg_id . '}';
           $argument_map[$arg_id] = $arg_id;
         }
-        elseif (strpos($bit, '%') === 0) {
+        elseif (str_starts_with($bit, '%')) {
           // Use the name defined in the path.
           $parameter_name = substr($bit, 1);
           $arg_id = 'arg_' . $arg_counter++;
@@ -492,7 +492,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) {
    */
   protected function validatePath($path) {
     $errors = [];
-    if (strpos($path, '%') === 0) {
+    if (str_starts_with($path, '%')) {
       $errors[] = $this->t('"%" may not be used for the first segment of a path.');
     }
 
diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index 77eec2fa132c239c460d34d32a838ccb75db4494..e49be3139d7653ab49d284d9ec562723eb0bcb26 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -1314,7 +1314,7 @@ public function renderText($alter) {
         // well.
         $base_path = base_path();
         // Checks whether the path starts with the base_path.
-        if (strpos($more_link_path, $base_path) === 0) {
+        if (str_starts_with($more_link_path, $base_path)) {
           $more_link_path = mb_substr($more_link_path, mb_strlen($base_path));
         }
 
@@ -1434,7 +1434,7 @@ protected function renderAsLink($alter, $text, $tokens) {
       // Tokens might have resolved URL's, as is the case for tokens provided by
       // Link fields, so all internal paths will be prefixed by base_path(). For
       // proper further handling reset this to internal:/.
-      if (strpos($path, base_path()) === 0) {
+      if (str_starts_with($path, base_path())) {
         $path = 'internal:/' . substr($path, strlen(base_path()));
       }
 
@@ -1449,7 +1449,7 @@ protected function renderAsLink($alter, $text, $tokens) {
       // 'http://www.example.com'.
       // Only do this when flag for external has been set, $path doesn't contain
       // a scheme and $path doesn't have a leading /.
-      if ($alter['external'] && !parse_url($path, PHP_URL_SCHEME) && strpos($path, '/') !== 0) {
+      if ($alter['external'] && !parse_url($path, PHP_URL_SCHEME) && !str_starts_with($path, '/')) {
         // There is no scheme, add the default 'http://' to the $path.
         $path = "http://" . $path;
       }
diff --git a/core/modules/views/src/Plugin/views/row/RssFields.php b/core/modules/views/src/Plugin/views/row/RssFields.php
index 30abed3dd544ecd1380aab332d36cb2b428d506d..734e338b3337e6a27ef2252d0e8bfe7d4db9ab6e 100644
--- a/core/modules/views/src/Plugin/views/row/RssFields.php
+++ b/core/modules/views/src/Plugin/views/row/RssFields.php
@@ -206,7 +206,7 @@ public function getField($index, $field_id) {
   protected function getAbsoluteUrl($url_string) {
     // If the given URL already starts with a leading slash, it's been processed
     // and we need to simply make it an absolute path by prepending the host.
-    if (strpos($url_string, '/') === 0) {
+    if (str_starts_with($url_string, '/')) {
       $host = \Drupal::request()->getSchemeAndHttpHost();
       // @todo Views should expect and store a leading /.
       // @see https://www.drupal.org/node/2423913
diff --git a/core/modules/views/tests/src/Kernel/Handler/ArgumentStringTest.php b/core/modules/views/tests/src/Kernel/Handler/ArgumentStringTest.php
index 59ab946656a7639043ea9e9b162c2d0df9ab0b67..4fbb1f0a399df8dd81a0747ca7f49b1d945dcd26 100644
--- a/core/modules/views/tests/src/Kernel/Handler/ArgumentStringTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/ArgumentStringTest.php
@@ -50,13 +50,13 @@ public function testGlossary() {
 
     $count_field = 'nid';
     foreach ($view->result as &$row) {
-      if (strpos($view->field['title']->getValue($row), 'a') === 0) {
+      if (str_starts_with($view->field['title']->getValue($row), 'a')) {
         $this->assertEquals(1, $row->{$count_field});
       }
-      if (strpos($view->field['title']->getValue($row), 'b') === 0) {
+      if (str_starts_with($view->field['title']->getValue($row), 'b')) {
         $this->assertEquals(2, $row->{$count_field});
       }
-      if (strpos($view->field['title']->getValue($row), 'c') === 0) {
+      if (str_starts_with($view->field['title']->getValue($row), 'c')) {
         $this->assertEquals(3, $row->{$count_field});
       }
     }
diff --git a/core/modules/views/tests/src/Kernel/TestViewsTest.php b/core/modules/views/tests/src/Kernel/TestViewsTest.php
index 1b21dfeaf81505206b3761b24292a0df8336e46e..7ca4d888b51c304b1fbe97883956598a3d33ed77 100644
--- a/core/modules/views/tests/src/Kernel/TestViewsTest.php
+++ b/core/modules/views/tests/src/Kernel/TestViewsTest.php
@@ -45,7 +45,7 @@ public function testDefaultConfig() {
     foreach ($default_config_storage->listAll() as $config_name) {
       // Skip files provided by the config_schema_test module since that module
       // is explicitly for testing schema.
-      if (strpos($config_name, 'config_schema_test') === 0) {
+      if (str_starts_with($config_name, 'config_schema_test')) {
         continue;
       }
 
diff --git a/core/modules/workflows/src/WorkflowAccessControlHandler.php b/core/modules/workflows/src/WorkflowAccessControlHandler.php
index dac375e3351fdf3a98e56ebe411654f001238b04..3774ae2276de7c89bcc1f9950fcf973e831e49dd 100644
--- a/core/modules/workflows/src/WorkflowAccessControlHandler.php
+++ b/core/modules/workflows/src/WorkflowAccessControlHandler.php
@@ -54,7 +54,7 @@ public function __construct(EntityTypeInterface $entity_type, PluginManagerInter
   protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
     /** @var \Drupal\workflows\Entity\Workflow $entity */
     $workflow_type = $entity->getTypePlugin();
-    if (strpos($operation, 'delete-state') === 0) {
+    if (str_starts_with($operation, 'delete-state')) {
       [, $state_id] = explode(':', $operation, 2);
       // Deleting a state is editing a workflow, but also we should forbid
       // access if there is only one state.
diff --git a/core/profiles/demo_umami/themes/umami/umami.theme b/core/profiles/demo_umami/themes/umami/umami.theme
index 97f10d7846951d7ea361ab1b21a960bb208cbc8a..cd53e63530f41efa3ac08247c407f030135b52f7 100644
--- a/core/profiles/demo_umami/themes/umami/umami.theme
+++ b/core/profiles/demo_umami/themes/umami/umami.theme
@@ -118,7 +118,7 @@ function umami_preprocess_links__media_library_menu(array &$variables) {
 function umami_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
   $form_object = $form_state->getFormObject();
 
-  if ($form_object instanceof ViewsForm && strpos($form_object->getBaseFormId(), 'views_form_media_library') === 0) {
+  if ($form_object instanceof ViewsForm && str_starts_with($form_object->getBaseFormId(), 'views_form_media_library')) {
     $form['#attributes']['class'][] = 'media-library-views-form';
   }
 }
diff --git a/core/tests/Drupal/BuildTests/Framework/ExternalCommandRequirementsTrait.php b/core/tests/Drupal/BuildTests/Framework/ExternalCommandRequirementsTrait.php
index 2fb4b1497b35e60e081c0c5d219f97fa89d1439a..0faf6d5f7ddcec99f03f0717a0a58018fc6ff17a 100644
--- a/core/tests/Drupal/BuildTests/Framework/ExternalCommandRequirementsTrait.php
+++ b/core/tests/Drupal/BuildTests/Framework/ExternalCommandRequirementsTrait.php
@@ -62,7 +62,7 @@ private static function checkExternalCommandRequirements(array $annotations) {
     // Make a list of required commands.
     $required_commands = [];
     foreach ($annotations as $requirement) {
-      if (strpos($requirement, 'externalCommand ') === 0) {
+      if (str_starts_with($requirement, 'externalCommand ')) {
         $command = trim(str_replace('externalCommand ', '', $requirement));
         // Use named keys to avoid duplicates.
         $required_commands[$command] = $command;
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
index 56c311df78e2af1a9a86bcc0430bf1bb75eec3bb..5ea74a35078a06a22c3b66bffb1813a829cc232e 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
@@ -97,7 +97,7 @@ public function testDialog() {
     $contents_no_target = $no_target_dialog->find('css', 'div.ui-dialog-content');
     $this->assertNotNull($contents_no_target, 'non-modal dialog opens ( no target ). ');
     $id = $contents_no_target->getAttribute('id');
-    $partial_match = strpos($id, 'drupal-dialog-ajax-testdialog-contents') === 0;
+    $partial_match = str_starts_with($id, 'drupal-dialog-ajax-testdialog-contents');
     $this->assertTrue($partial_match, 'The non-modal ID has the expected prefix.');
 
     $no_target_button = $no_target_dialog->findButton('Close');
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php
index 8348b76f28089c5de52fb2596f52ae844ac81754..e3f011c554f409085334a9ac4a348e05bbc47954 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php
@@ -111,7 +111,7 @@ protected function tearDown(): void {
 
       $warnings = $this->getSession()->evaluateScript("JSON.parse(sessionStorage.getItem('js_testing_log_test.warnings') || JSON.stringify([]))");
       foreach ($warnings as $warning) {
-        if (strpos($warning, '[Deprecation]') === 0) {
+        if (str_starts_with($warning, '[Deprecation]')) {
           @trigger_error('Javascript Deprecation:' . substr($warning, 13), E_USER_DEPRECATED);
         }
       }
diff --git a/core/tests/Drupal/KernelTests/AssertConfigTrait.php b/core/tests/Drupal/KernelTests/AssertConfigTrait.php
index f4e04260ce81cf4ce33a63d10256c4e56b492ebe..307bdcb170f833607dde959c6351d470b080d43d 100644
--- a/core/tests/Drupal/KernelTests/AssertConfigTrait.php
+++ b/core/tests/Drupal/KernelTests/AssertConfigTrait.php
@@ -77,7 +77,7 @@ protected function assertConfigDiff(Diff $result, $config_name, array $skipped_c
           }
           foreach ($op->closing as $closing) {
             // The UUIDs don't exist in the default config.
-            if (strpos($closing, 'uuid: ') === 0) {
+            if (str_starts_with($closing, 'uuid: ')) {
               break;
             }
             throw new \Exception($config_name . ': ' . var_export($op, TRUE));
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigDiffTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigDiffTest.php
index bc465ea31eccaab56c7859f34e0f862c32aaf6a2..eabc0d97d817e31f520edd7fa868f4541eb8e361 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigDiffTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigDiffTest.php
@@ -162,7 +162,7 @@ protected function assertYamlEdit(array $edits, string $field, string $type, $or
       // Look through each line and try and find the key.
       if (is_array($haystack)) {
         foreach ($haystack as $item) {
-          if (strpos($item, $field . ':') === 0) {
+          if (str_starts_with($item, $field . ':')) {
             $match = TRUE;
             // Assert that the edit is of the type specified.
             $this->assertEquals($type, $edit->type, "The {$field} item in the diff is a {$type}");
diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/ContextDefinitionTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/ContextDefinitionTest.php
index e332be68df6a041eff494c561970bc7610d1a039..6476dc5dab0a7f766aa5e1c17e48263f2e52d9d1 100644
--- a/core/tests/Drupal/KernelTests/Core/Plugin/ContextDefinitionTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Plugin/ContextDefinitionTest.php
@@ -51,7 +51,7 @@ public function testIsSatisfiedBy() {
    */
   public function testEntityContextDefinitionAssert() {
     $this->expectException(\AssertionError::class);
-    $this->expectExceptionMessage('assert(strpos($data_type, \'entity:\') !== 0 || $this instanceof EntityContextDefinition)');
+    $this->expectExceptionMessage('assert(!str_starts_with($data_type, \'entity:\') || $this instanceof EntityContextDefinition)');
     new ContextDefinition('entity:entity_test');
   }
 
diff --git a/core/tests/Drupal/Tests/ComposerIntegrationTest.php b/core/tests/Drupal/Tests/ComposerIntegrationTest.php
index 93342f01b24558023028eae119542fe03dd15d98..ecf7c27a505d61ae0f2e254e88bbe928f358e429 100644
--- a/core/tests/Drupal/Tests/ComposerIntegrationTest.php
+++ b/core/tests/Drupal/Tests/ComposerIntegrationTest.php
@@ -63,7 +63,7 @@ public function testComposerTilde($path) {
       foreach ($content[$composer_key] as $dependency => $version) {
         // We allow tildes if the dependency is a Symfony component.
         // @see https://www.drupal.org/node/2887000
-        if (strpos($dependency, 'symfony/') === 0) {
+        if (str_starts_with($dependency, 'symfony/')) {
           continue;
         }
         $this->assertStringNotContainsString('~', $version, "Dependency $dependency in $path contains a tilde, use a caret.");
diff --git a/core/tests/Drupal/Tests/DrupalTestBrowser.php b/core/tests/Drupal/Tests/DrupalTestBrowser.php
index 4e6d4325f681087217e35a337465abc2976c221b..8546e785c2bdc69cf614b7455680cfa6c960b6fe 100644
--- a/core/tests/Drupal/Tests/DrupalTestBrowser.php
+++ b/core/tests/Drupal/Tests/DrupalTestBrowser.php
@@ -89,7 +89,7 @@ protected function doRequest($request): object {
         'content-md5' => TRUE,
         'content-type' => TRUE,
       ];
-      if (strpos($key, 'http-') === 0) {
+      if (str_starts_with($key, 'http-')) {
         $headers[substr($key, 5)] = $val;
       }
       // CONTENT_* are not prefixed with HTTP_
diff --git a/core/tests/Drupal/Tests/TestRequirementsTrait.php b/core/tests/Drupal/Tests/TestRequirementsTrait.php
index 5a3a8857e21a5fc8cfe1cb33a7f35159bfee9075..e7a9548fee39b3a489b060b10beedbd87a49c5c7 100644
--- a/core/tests/Drupal/Tests/TestRequirementsTrait.php
+++ b/core/tests/Drupal/Tests/TestRequirementsTrait.php
@@ -83,7 +83,7 @@ private function checkModuleRequirements($root, array $annotations) {
     // Make a list of required modules.
     $required_modules = [];
     foreach ($annotations as $requirement) {
-      if (strpos($requirement, 'module ') === 0) {
+      if (str_starts_with($requirement, 'module ')) {
         $required_modules[] = trim(str_replace('module ', '', $requirement));
       }
     }
diff --git a/core/tests/Drupal/Tests/WebAssert.php b/core/tests/Drupal/Tests/WebAssert.php
index 7f9b5dbeb14fd077bd93d1c17125764116149652..f76c0790ae76cd930657a39fceb10a313d91e346 100644
--- a/core/tests/Drupal/Tests/WebAssert.php
+++ b/core/tests/Drupal/Tests/WebAssert.php
@@ -50,13 +50,13 @@ protected function cleanUrl($url, $include_query = FALSE) {
       $url = $url->setAbsolute()->toString();
     }
     // Strip the base URL from the beginning for absolute URLs.
-    if ($this->baseUrl !== '' && strpos($url, $this->baseUrl) === 0) {
+    if ($this->baseUrl !== '' && str_starts_with($url, $this->baseUrl)) {
       $url = substr($url, strlen($this->baseUrl));
     }
     $parts = parse_url($url);
     // Make sure there is a forward slash at the beginning of relative URLs for
     // consistency.
-    if (empty($parts['host']) && strpos($url, '/') !== 0) {
+    if (empty($parts['host']) && !str_starts_with($url, '/')) {
       $parts['path'] = '/' . $parts['path'];
     }
     $fragment = empty($parts['fragment']) ? '' : '#' . $parts['fragment'];
diff --git a/core/themes/claro/claro.theme b/core/themes/claro/claro.theme
index 846aa4291db802e71e4667ec1aadfa4c81ee5b86..a2d85f94e87ce8a6b4ee9c9ddee6dac693c9b555 100644
--- a/core/themes/claro/claro.theme
+++ b/core/themes/claro/claro.theme
@@ -400,7 +400,7 @@ function claro_form_alter(array &$form, FormStateInterface $form_state, $form_id
     $form['override']['#prefix'] = str_replace('form--inline', 'form--flex', $form['override']['#prefix']);
   }
 
-  if ($form_object instanceof ViewsForm && strpos($form_object->getBaseFormId(), 'views_form_media_library') === 0) {
+  if ($form_object instanceof ViewsForm && str_starts_with($form_object->getBaseFormId(), 'views_form_media_library')) {
     if (isset($form['header'])) {
       $form['header']['#attributes']['class'][] = 'media-library-views-form__header';
       $form['header']['media_bulk_form']['#attributes']['class'][] = 'media-library-views-form__bulk_form';
@@ -1557,7 +1557,7 @@ function claro_views_pre_render(ViewExecutable $view) {
         $add_classes($view->field['delete_media']->options['alter']['link_class'], ['icon-link']);
       }
     }
-    elseif (strpos($view->current_display, 'widget') === 0) {
+    elseif (str_starts_with($view->current_display, 'widget')) {
       if (array_key_exists('rendered_entity', $view->field)) {
         $add_classes($view->field['rendered_entity']->options['element_class'], ['media-library-item__content']);
       }