diff --git a/core/lib/Drupal/Core/Asset/AssetResolver.php b/core/lib/Drupal/Core/Asset/AssetResolver.php
index d90506e4a060dd89f942d3f71b8a18c26b9c7dd9..c0b0f26fa75e22c0d84a2317535c1263fdc758f9 100644
--- a/core/lib/Drupal/Core/Asset/AssetResolver.php
+++ b/core/lib/Drupal/Core/Asset/AssetResolver.php
@@ -312,7 +312,7 @@ public function getJsAssets(AttachedAssetsInterface $assets, $optimize) {
         $settings = $this->getJsSettingsAssets($assets);
         // Allow modules to add cached JavaScript settings.
         foreach ($this->moduleHandler->getImplementations('js_settings_build') as $module) {
-          $function = $module . '_' . 'js_settings_build';
+          $function = $module . '_js_settings_build';
           $function($settings, $assets);
         }
       }
diff --git a/core/lib/Drupal/Core/Command/DbDumpCommand.php b/core/lib/Drupal/Core/Command/DbDumpCommand.php
index 26b4363cdd3cac504389aa5b315cfbb96c461367..b5db612517503fc9374f9016a5695e456474a284 100644
--- a/core/lib/Drupal/Core/Command/DbDumpCommand.php
+++ b/core/lib/Drupal/Core/Command/DbDumpCommand.php
@@ -418,10 +418,13 @@ protected function getTableScript($table, array $schema, array $data) {
       foreach ($data as $record) {
         $insert .= "->values(" . Variable::export($record) . ")\n";
       }
-      $output .= "\$connection->insert('" . $table . "')\n"
-        . "->fields(" . Variable::export(array_keys($schema['fields'])) . ")\n"
-        . $insert
-        . "->execute();\n\n";
+      $fields = Variable::export(array_keys($schema['fields']));
+      $output .= <<<EOT
+\$connection->insert('$table')
+->fields($fields)
+{$insert}->execute();
+
+EOT;
     }
     return $output;
   }
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeManager.php b/core/lib/Drupal/Core/Entity/EntityTypeManager.php
index 9d7fdc5e9294141e8d040cd79c4ad71c223aa053..69c2736232f01eddc8f60623285be5fc710a916e 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeManager.php
@@ -108,7 +108,7 @@ protected function findDefinitions() {
     // Directly call the hook implementations to pass the definitions to them
     // by reference, so new entity types can be added.
     foreach ($this->moduleHandler->getImplementations('entity_type_build') as $module) {
-      $function = $module . '_' . 'entity_type_build';
+      $function = $module . '_entity_type_build';
       $function($definitions);
     }
     foreach ($definitions as $plugin_id => $definition) {
diff --git a/core/lib/Drupal/Core/Render/theme.api.php b/core/lib/Drupal/Core/Render/theme.api.php
index 2bb2eb9aa8fd9615335c14d037d4c01461321a2c..d52a7c3da956a71f505c352259e4ba32c3f1c45d 100644
--- a/core/lib/Drupal/Core/Render/theme.api.php
+++ b/core/lib/Drupal/Core/Render/theme.api.php
@@ -715,7 +715,7 @@ function hook_theme_suggestions_alter(array &$suggestions, array $variables, $ho
  */
 function hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables) {
   if (empty($variables['header'])) {
-    $suggestions[] = 'hookname__' . 'no_header';
+    $suggestions[] = 'hookname__no_header';
   }
 }
 
diff --git a/core/modules/config/config.module b/core/modules/config/config.module
index b280fe84fa285cdc562a53f155f48fcc14d479b2..c47cf300ca4ba0700a13ee9ad657c9568acb6a9b 100644
--- a/core/modules/config/config.module
+++ b/core/modules/config/config.module
@@ -70,7 +70,7 @@ function config_file_download($uri) {
       $date = DateTime::createFromFormat('U', $request->server->get('REQUEST_TIME'));
       $date_string = $date->format('Y-m-d-H-i');
       $hostname = str_replace('.', '-', $request->getHttpHost());
-      $filename = 'config' . '-' . $hostname . '-' . $date_string . '.tar.gz';
+      $filename = 'config-' . $hostname . '-' . $date_string . '.tar.gz';
       $disposition = 'attachment; filename="' . $filename . '"';
       return [
         'Content-disposition' => $disposition,
diff --git a/core/modules/config/tests/src/Functional/ConfigExportUITest.php b/core/modules/config/tests/src/Functional/ConfigExportUITest.php
index d92071e89de45b910dabc04207cb2aa6b73ac6c6..4cd23acf56ceaae4f61dd51c22484b1b167d07dc 100644
--- a/core/modules/config/tests/src/Functional/ConfigExportUITest.php
+++ b/core/modules/config/tests/src/Functional/ConfigExportUITest.php
@@ -57,7 +57,7 @@ public function testExport() {
     $this->assertTrue($header_match, "Header with filename matches the expected format.");
 
     // Extract the archive and verify it's not empty.
-    $file_path = file_directory_temp() . '/' . 'config.tar.gz';
+    $file_path = file_directory_temp() . '/config.tar.gz';
     $archiver = new Tar($file_path);
     $archive_contents = $archiver->listContents();
     $this->assert(!empty($archive_contents), 'Downloaded archive file is not empty.');
diff --git a/core/modules/link/src/Plugin/migrate/process/FieldLink.php b/core/modules/link/src/Plugin/migrate/process/FieldLink.php
index 4d3d7eec674523cd5292f4c93ddf8358b57c4d62..680049ce5088e314bf8b3c113033defcee8a4c34 100644
--- a/core/modules/link/src/Plugin/migrate/process/FieldLink.php
+++ b/core/modules/link/src/Plugin/migrate/process/FieldLink.php
@@ -85,7 +85,7 @@ protected function canonicalizeUri($uri) {
       $anchor = "(?:#[a-z0-9" . $link_ichars . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)";
 
       // The rest of the path for a standard URL.
-      $end = $directories . '?' . $query . '?' . $anchor . '?' . '$/i';
+      $end = $directories . '?' . $query . '?' . $anchor . '?$/i';
 
       if (!preg_match($internal_pattern . $end, $uri)) {
         $link_domains = '[a-z][a-z0-9-]{1,62}';
diff --git a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module
index cbc5b380206ab32b423b24ffca0a925a6aa37a28..5d4420270a8ade3ee20c47e46ba74163a96767a6 100644
--- a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module
+++ b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module
@@ -32,21 +32,21 @@ function theme_suggestions_test_theme_suggestions_alter(array &$suggestions, arr
  */
 function theme_suggestions_test_theme_suggestions_theme_test_suggestions_alter(array &$suggestions, array $variables) {
   \Drupal::messenger()->addStatus(__FUNCTION__ . '() executed.');
-  $suggestions[] = 'theme_test_suggestions__' . 'module_override';
+  $suggestions[] = 'theme_test_suggestions__module_override';
 }
 
 /**
  * Implements hook_theme_suggestions_HOOK_alter().
  */
 function theme_suggestions_test_theme_suggestions_theme_test_function_suggestions_alter(array &$suggestions, array $variables) {
-  $suggestions[] = 'theme_test_function_suggestions__' . 'module_override';
+  $suggestions[] = 'theme_test_function_suggestions__module_override';
 }
 
 /**
  * Implements hook_theme_suggestions_HOOK_alter().
  */
 function theme_suggestions_test_theme_suggestions_theme_test_specific_suggestions_alter(array &$suggestions, array $variables) {
-  $suggestions[] = 'theme_test_specific_suggestions__' . 'variant__foo';
+  $suggestions[] = 'theme_test_specific_suggestions__variant__foo';
 }
 
 /**
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.module b/core/modules/system/tests/modules/theme_test/theme_test.module
index 901449696caf17b3e3f7571c05f483ea8a653b49..701f033666dd1565b0f1fb4939eed180892de349 100644
--- a/core/modules/system/tests/modules/theme_test/theme_test.module
+++ b/core/modules/system/tests/modules/theme_test/theme_test.module
@@ -171,7 +171,7 @@ function theme_theme_test_function_suggestions($variables) {
  * Implements hook_theme_suggestions_HOOK().
  */
 function theme_test_theme_suggestions_theme_test_suggestion_provided(array $variables) {
-  return ['theme_test_suggestion_provided__' . 'foo'];
+  return ['theme_test_suggestion_provided__foo'];
 }
 
 /**
diff --git a/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php b/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
index 02bfca8441263d4f0ba2bf15ec1aab91ddd3f118..97092232d76e9ef6cce734f37913aaa70519f7f1 100644
--- a/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
+++ b/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
@@ -54,8 +54,8 @@ protected function assertHtmlToText($html, $text, $message, $allowed_tags = NULL
     $result = MailFormatHelper::htmlToText($html, $allowed_tags);
     $pass = $this->assertEqual($result, $text, Html::escape($message));
     $verbose = 'html = <pre>' . $this->stringToHtml($html)
-      . '</pre><br />' . 'result = <pre>' . $this->stringToHtml($result)
-      . '</pre><br />' . 'expected = <pre>' . $this->stringToHtml($text)
+      . '</pre><br />result = <pre>' . $this->stringToHtml($result)
+      . '</pre><br />expected = <pre>' . $this->stringToHtml($text)
       . '</pre>';
     $this->verbose($verbose);
     if (!$pass) {
@@ -212,27 +212,30 @@ public function testDrupalHtmltoTextCollapsesWhitespace() {
    * (at least) a newline in the plaintext version.
    */
   public function testDrupalHtmlToTextBlockTagToNewline() {
-    $input = '[text]'
-      . '<blockquote>[blockquote]</blockquote>'
-      . '<br />[br]'
-      . '<dl><dt>[dl-dt]</dt>'
-      . '<dt>[dt]</dt>'
-      . '<dd>[dd]</dd>'
-      . '<dd>[dd-dl]</dd></dl>'
-      . '<h1>[h1]</h1>'
-      . '<h2>[h2]</h2>'
-      . '<h3>[h3]</h3>'
-      . '<h4>[h4]</h4>'
-      . '<h5>[h5]</h5>'
-      . '<h6>[h6]</h6>'
-      . '<hr />[hr]'
-      . '<ol><li>[ol-li]</li>'
-      . '<li>[li]</li>'
-      . '<li>[li-ol]</li></ol>'
-      . '<p>[p]</p>'
-      . '<ul><li>[ul-li]</li>'
-      . '<li>[li-ul]</li></ul>'
-      . '[text]';
+    $input = <<<'EOT'
+[text]
+<blockquote>[blockquote]</blockquote>
+<br />[br]
+<dl><dt>[dl-dt]</dt>
+<dt>[dt]</dt>
+<dd>[dd]</dd>
+<dd>[dd-dl]</dd></dl>
+<h1>[h1]</h1>
+<h2>[h2]</h2>
+<h3>[h3]</h3>
+<h4>[h4]</h4>
+<h5>[h5]</h5>
+<h6>[h6]</h6>
+<hr />[hr]
+<ol><li>[ol-li]</li>
+<li>[li]</li>
+<li>[li-ol]</li></ol>
+<p>[p]</p>
+<ul><li>[ul-li]</li>
+<li>[li-ul]</li></ul>
+[text]
+EOT;
+    $input = str_replace(["\r", "\n"], '', $input);
     $output = MailFormatHelper::htmlToText($input);
     $pass = $this->assertFalse(
       preg_match('/\][^\n]*\[/s', $output),
@@ -288,23 +291,28 @@ public function testHeaderSeparation() {
    */
   public function testFootnoteReferences() {
     global $base_path, $base_url;
-    $source = '<a href="http://www.example.com/node/1">Host and path</a>'
-      . '<br /><a href="http://www.example.com">Host, no path</a>'
-      . '<br /><a href="' . $base_path . 'node/1">Path, no host</a>'
-      . '<br /><a href="node/1">Relative path</a>';
+    $source = <<<EOT
+<a href="http://www.example.com/node/1">Host and path</a>
+<br /><a href="http://www.example.com">Host, no path</a>
+<br /><a href="{$base_path}node/1">Path, no host</a>
+<br /><a href="node/1">Relative path</a>
+EOT;
+    $source = str_replace(["\r", "\n"], '', $source);
     // @todo Footnote URLs should be absolute.
-    $tt = "Host and path [1]"
-      . "\nHost, no path [2]"
-      // @todo The following two references should be combined.
-      . "\nPath, no host [3]"
-      . "\nRelative path [4]"
-      . "\n"
-      . "\n[1] http://www.example.com/node/1"
-      . "\n[2] http://www.example.com"
-      // @todo The following two references should be combined.
-      . "\n[3] $base_url/node/1"
-      . "\n[4] node/1\n";
-    $this->assertHtmlToText($source, $tt, 'Footnotes');
+    // @todo The last two references should be combined.
+    $text = <<<EOT
+Host and path [1]
+Host, no path [2]
+Path, no host [3]
+Relative path [4]
+
+[1] http://www.example.com/node/1
+[2] http://www.example.com
+[3] $base_url/node/1
+[4] node/1
+
+EOT;
+    $this->assertHtmlToText($source, $text, 'Footnotes');
   }
 
   /**
diff --git a/core/modules/user/src/Plugin/views/field/Roles.php b/core/modules/user/src/Plugin/views/field/Roles.php
index eec26f88ac214f5551cfee20e81c76918a5e7d1f..c1cd8969e898f4b4250ca84c87e4f346b714d456 100644
--- a/core/modules/user/src/Plugin/views/field/Roles.php
+++ b/core/modules/user/src/Plugin/views/field/Roles.php
@@ -101,8 +101,8 @@ protected function documentSelfTokens(&$tokens) {
 
   protected function addSelfTokens(&$tokens, $item) {
     if (!empty($item['role'])) {
-      $tokens['{{ ' . $this->options['id'] . '__role' . ' }}'] = $item['role'];
-      $tokens['{{ ' . $this->options['id'] . '__rid' . ' }}'] = $item['rid'];
+      $tokens['{{ ' . $this->options['id'] . '__role }}'] = $item['role'];
+      $tokens['{{ ' . $this->options['id'] . '__rid }}'] = $item['rid'];
     }
   }
 
diff --git a/core/phpcs.xml.dist b/core/phpcs.xml.dist
index 2427d344123880475bd999c1e64d6fce669179a7..b5f3f4847b88add10d31f43136cc9103adc6d254 100644
--- a/core/phpcs.xml.dist
+++ b/core/phpcs.xml.dist
@@ -130,6 +130,7 @@
   <rule ref="Drupal.Semantics.PregSecurity"/>
   <rule ref="Drupal.Semantics.TInHookMenu"/>
   <rule ref="Drupal.Semantics.TInHookSchema"/>
+  <rule ref="Drupal.Strings.UnnecessaryStringConcat"/>
   <rule ref="Drupal.WhiteSpace.CloseBracketSpacing"/>
   <rule ref="Drupal.WhiteSpace.Comma"/>
   <rule ref="Drupal.WhiteSpace.EmptyLines"/>