diff --git a/core/INSTALL.sqlite.txt b/core/INSTALL.sqlite.txt
index adff4682e25290deeed6c3887301b42422288fe9..e22aaa89c3cc2d7d639bcfc5f24469e7432783dc 100644
--- a/core/INSTALL.sqlite.txt
+++ b/core/INSTALL.sqlite.txt
@@ -2,11 +2,8 @@
 SQLITE REQUIREMENTS
 -------------------
 
-To use SQLite with your Drupal installation, the following requirements must be
-met: Server has PHP 5.3.10 or later with PDO, and the PDO SQLite driver must be
-enabled.
-
-If you have not pdo_sqlite available depending on your system there are different ways to install it.
+PHP's PDO SQLite driver must be enabled. If you do not have pdo_sqlite
+available, depending on your system there are different ways to install it.
 
 Windows
 -------
diff --git a/core/INSTALL.txt b/core/INSTALL.txt
index 22cd8ceca3d69687ff05ebc6b1e6e9e3e18b85b1..5dbc9e0233080f57d2a218fbb82b6837efbb3348 100644
--- a/core/INSTALL.txt
+++ b/core/INSTALL.txt
@@ -15,7 +15,7 @@ QUICKSTART
 ----------------------
 
 Prerequisites:
-- PHP 5.5.9 (or greater) (https://php.net).
+- PHP 7.0.8 (or greater) (https://php.net).
 
 In the instructions below, replace the version x.y.z with the specific version
 you wish to download. Example: 8.6.0.zip. You can find the latest stable version
@@ -48,8 +48,8 @@ Drupal requires:
 - A web server with PHP support, for example:
   - Apache 2.0 (or greater) (http://httpd.apache.org/).
   - Nginx 1.1 (or greater) (http://nginx.com/).
-- PHP 5.5.9 (or greater) (http://php.net/). For better security support it is
-  recommended to update to at least 5.5.21 or 5.6.5.
+- PHP 7.0.8 (or greater) (http://php.net/). For better security support it is
+  recommended to update to at least 7.2.17.
 - One of the following databases:
   - MySQL 5.5.3 (or greater) (http://www.mysql.com/).
   - MariaDB 5.5.20 (or greater) (https://mariadb.org/). MariaDB is a fully
@@ -93,10 +93,6 @@ OPTIONAL SERVER REQUIREMENTS
   configuration allows the web server to initiate outbound connections. Most web
   hosting setups allow this.
 
-- PHP 5.5.21 provides features for improved security when used with MySQL. While
-  this is not required, it is highly encouraged to use PHP 5.5.21 or 5.6.5 and
-  above.
-
 INSTALLATION
 ------------
 
diff --git a/core/composer.json b/core/composer.json
index 810ec27e59566cbc39ba075645ff92f85bc813b6..2af439826fe4f82316b706c5e910f93d1cbe0fcc 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -17,7 +17,7 @@
         "ext-SPL": "*",
         "ext-tokenizer": "*",
         "ext-xml": "*",
-        "php": "^5.5.9|>=7.0.8",
+        "php": ">=7.0.8",
         "symfony/class-loader": "~3.4.0",
         "symfony/console": "~3.4.0",
         "symfony/dependency-injection": "~3.4.26",
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 133aa907d7b6b842de9dd271f7455d095d1a9e7c..b7e1f741a4b32d6173eddbc27bba681070db55b0 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -32,7 +32,7 @@
  * @todo Move this to an appropriate autoloadable class. See
  *   https://www.drupal.org/project/drupal/issues/2908079
  */
-const DRUPAL_MINIMUM_PHP = '5.5.9';
+const DRUPAL_MINIMUM_PHP = '7.0.8';
 
 /**
  * Minimum supported version of PHP.
@@ -604,15 +604,10 @@ function _drupal_exception_handler($exception) {
     // Log the message to the watchdog and return an error page to the user.
     _drupal_log_error(Error::decodeException($exception), TRUE);
   }
-  // PHP 7 introduces Throwable, which covers both Error and
-  // Exception throwables.
+  // Catch \Throwable, which covers both Error and Exception throwables.
   catch (\Throwable $error) {
     _drupal_exception_handler_additional($exception, $error);
   }
-  // In order to be compatible with PHP 5 we also catch regular Exceptions.
-  catch (\Exception $exception2) {
-    _drupal_exception_handler_additional($exception, $exception2);
-  }
 }
 
 /**
@@ -1057,15 +1052,10 @@ function _drupal_shutdown_function() {
       next($callbacks);
     }
   }
-  // PHP 7 introduces Throwable, which covers both Error and
-  // Exception throwables.
+  // Catch \Throwable, which covers both Error and Exception throwables.
   catch (\Throwable $error) {
     _drupal_shutdown_function_handle_exception($error);
   }
-  // In order to be compatible with PHP 5 we also catch regular Exceptions.
-  catch (\Exception $exception) {
-    _drupal_shutdown_function_handle_exception($exception);
-  }
 }
 
 /**
diff --git a/core/install.php b/core/install.php
index c88ffeedaacd938eafffc1b47c0d7d6bae163c9e..8cc3880c81ce9ee89ff8a4243a25b2a580537f49 100644
--- a/core/install.php
+++ b/core/install.php
@@ -25,8 +25,8 @@
 // The minimum version is specified explicitly, as DRUPAL_MINIMUM_PHP is not
 // yet available. It is defined in bootstrap.inc, but it is not possible to
 // load that file yet as it would cause a fatal error on older versions of PHP.
-if (version_compare(PHP_VERSION, '5.5.9') < 0) {
-  print 'Your PHP installation is too old. Drupal requires at least PHP 5.5.9. See the <a href="https://www.drupal.org/requirements">system requirements</a> page for more information.';
+if (version_compare(PHP_VERSION, '7.0.8') < 0) {
+  print 'Your PHP installation is too old. Drupal requires at least PHP 7.0.8. See the <a href="https://www.drupal.org/requirements">system requirements</a> page for more information.';
   exit;
 }
 
diff --git a/core/lib/Drupal/Component/Annotation/composer.json b/core/lib/Drupal/Component/Annotation/composer.json
index 51e7d25b00b355adf685f570b6aa34732a69e51a..49e0ced813f0305c2c51db0cc6950703a0db0aef 100644
--- a/core/lib/Drupal/Component/Annotation/composer.json
+++ b/core/lib/Drupal/Component/Annotation/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "doctrine/common": "^2.5",
     "doctrine/annotations": "1.2.*",
     "drupal/core-file-cache": "^8.2",
diff --git a/core/lib/Drupal/Component/Assertion/Handle.php b/core/lib/Drupal/Component/Assertion/Handle.php
index f1e1e6ace0fbd5ac0488efe18095fc9e591caf6c..ed8ff8f7f6d22d0c3e859132bd560758f9832513 100644
--- a/core/lib/Drupal/Component/Assertion/Handle.php
+++ b/core/lib/Drupal/Component/Assertion/Handle.php
@@ -5,37 +5,21 @@
 /**
  * Handler for runtime assertion failures.
  *
- * This class allows PHP 5.x to throw exceptions on runtime assertion fails
- * in the same manner as PHP 7, and sets the ASSERT_EXCEPTION flag to TRUE
- * for the PHP 7 runtime.
- *
  * @ingroup php_assert
+ *
+ * @todo Deprecate this class. https://www.drupal.org/node/3054072
  */
 class Handle {
 
   /**
-   * Registers uniform assertion handling.
+   * Ensures exceptions are thrown when an assertion fails.
    */
   public static function register() {
     // Since we're using exceptions, turn error warnings off.
     assert_options(ASSERT_WARNING, FALSE);
 
-    if (version_compare(PHP_VERSION, '7.0.0-dev') < 0) {
-      if (!class_exists('AssertionError', FALSE)) {
-        require __DIR__ . '/global_namespace_php5.php';
-      }
-      // PHP 5 - create a handler to throw the exception directly.
-      assert_options(ASSERT_CALLBACK, function ($file = '', $line = 0, $code = '', $message = '') {
-        if (empty($message)) {
-          $message = $code;
-        }
-        throw new \AssertionError($message, 0, NULL, $file, $line);
-      });
-    }
-    else {
-      // PHP 7 - just turn exception throwing on.
-      assert_options(ASSERT_EXCEPTION, TRUE);
-    }
+    // Turn exception throwing on.
+    assert_options(ASSERT_EXCEPTION, TRUE);
   }
 
 }
diff --git a/core/lib/Drupal/Component/Assertion/composer.json b/core/lib/Drupal/Component/Assertion/composer.json
index cdc8c928fbdc47c436565d0a00b0e9aa5625ace3..40ddc38819ccd98c850407b061a475c0c68d934d 100644
--- a/core/lib/Drupal/Component/Assertion/composer.json
+++ b/core/lib/Drupal/Component/Assertion/composer.json
@@ -1,11 +1,11 @@
 {
   "name": "drupal/core-assertion",
-  "description": "Provides runtime assertions similar to those in PHP 7, under PHP 5.",
+  "description": "Provides helper functionality for runtime assertions.",
   "keywords": ["drupal"],
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9"
+    "php": ">=7.0.8"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Component/Assertion/global_namespace_php5.php b/core/lib/Drupal/Component/Assertion/global_namespace_php5.php
deleted file mode 100644
index 1b5caf46eafb2cb63ea83d3b4d1f3c8e2cc232fe..0000000000000000000000000000000000000000
--- a/core/lib/Drupal/Component/Assertion/global_namespace_php5.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains PHP5 version of the \AssertionError class.
- */
-
-/**
- * Emulates PHP 7 AssertionError as closely as possible.
- *
- * This class is declared in the global namespace. It will only be included by
- * \Drupal\Component\Assertion\Handle for PHP5 since this class exists natively
- * in PHP 7. Note that in PHP 7 it extends from Error, not Exception, but that
- * isn't possible for PHP 5 - all exceptions must extend from exception.
- */
-class AssertionError extends Exception {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct($message = '', $code = 0, Exception $previous = NULL, $file = '', $line = 0) {
-    parent::__construct($message, $code, $previous);
-    // Preserve the filename and line number of the assertion failure.
-    $this->file = $file;
-    $this->line = $line;
-  }
-
-}
diff --git a/core/lib/Drupal/Component/Bridge/composer.json b/core/lib/Drupal/Component/Bridge/composer.json
index 19c8a3b1d35666b0d44d8b977490abc6fbfab1c3..90a04b4cb4838f1caa4baa98571e805f857c5749 100644
--- a/core/lib/Drupal/Component/Bridge/composer.json
+++ b/core/lib/Drupal/Component/Bridge/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "zendframework/zend-feed": "^2.4"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/ClassFinder/composer.json b/core/lib/Drupal/Component/ClassFinder/composer.json
index c5a97b09f1c25e0d48f195f98276b3238d97f095..e62104a3577801a97a092de8d6481acbc9072e54 100644
--- a/core/lib/Drupal/Component/ClassFinder/composer.json
+++ b/core/lib/Drupal/Component/ClassFinder/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "doctrine/common": "^2.5"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/Datetime/composer.json b/core/lib/Drupal/Component/Datetime/composer.json
index 6b7f89f00bd699041d241aa3e4f1957a186dc0f7..41d8e13531abe4399689d0839fc2a5b3141df398 100644
--- a/core/lib/Drupal/Component/Datetime/composer.json
+++ b/core/lib/Drupal/Component/Datetime/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "drupal/core-utility": "^8.2"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/DependencyInjection/composer.json b/core/lib/Drupal/Component/DependencyInjection/composer.json
index 846034affae87fcb386b4f11aeacf7e2b186f961..530bef4372361a07d255a8235183d9963c773b5e 100644
--- a/core/lib/Drupal/Component/DependencyInjection/composer.json
+++ b/core/lib/Drupal/Component/DependencyInjection/composer.json
@@ -11,7 +11,7 @@
     "source": "https://www.drupal.org/project/drupal/git-instructions"
   },
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "symfony/dependency-injection": ">=2.8 <4.0.0"
   },
   "suggest": {
diff --git a/core/lib/Drupal/Component/Diff/composer.json b/core/lib/Drupal/Component/Diff/composer.json
index b3016084a2048cd61d8dfbd552fdf8476bbdb280..dbec520b9e8c495c3d1e41f3941099523b8f1efb 100644
--- a/core/lib/Drupal/Component/Diff/composer.json
+++ b/core/lib/Drupal/Component/Diff/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "symfony/polyfill-mbstring": "~1.0"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/Discovery/composer.json b/core/lib/Drupal/Component/Discovery/composer.json
index 4de189402ae3fe51ae11c17994233c299a2ea4e1..bcc26f18c4c963b70580860a1263bd523890a5db 100644
--- a/core/lib/Drupal/Component/Discovery/composer.json
+++ b/core/lib/Drupal/Component/Discovery/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "drupal/core-file-cache": "^8.2",
     "drupal/core-serialization": "^8.2"
   },
diff --git a/core/lib/Drupal/Component/EventDispatcher/composer.json b/core/lib/Drupal/Component/EventDispatcher/composer.json
index cfbcc72e3f71978d25a82b0eed9fdadbd71cfa1b..31c82a5cf17b78b25db6488d6f3cd99f6bd32819 100644
--- a/core/lib/Drupal/Component/EventDispatcher/composer.json
+++ b/core/lib/Drupal/Component/EventDispatcher/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "symfony/dependency-injection": ">=2.8 <4.0.0",
     "symfony/event-dispatcher": ">=2.7 <4.0.0"
   },
diff --git a/core/lib/Drupal/Component/FileCache/composer.json b/core/lib/Drupal/Component/FileCache/composer.json
index 86e33a5f919270648cf1d26921d926909ac05640..5f18f2bb9b5a5ad183fa39bd850cbef70ac66282 100644
--- a/core/lib/Drupal/Component/FileCache/composer.json
+++ b/core/lib/Drupal/Component/FileCache/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9"
+    "php": ">=7.0.8"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Component/FileSystem/composer.json b/core/lib/Drupal/Component/FileSystem/composer.json
index 528bb0744af56b35ce172ac25fb621b79d26dbfb..e9433c08e5413124c04b5163270dae4ba82430a3 100644
--- a/core/lib/Drupal/Component/FileSystem/composer.json
+++ b/core/lib/Drupal/Component/FileSystem/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9"
+    "php": ">=7.0.8"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Component/Gettext/composer.json b/core/lib/Drupal/Component/Gettext/composer.json
index 87f500a108c4180d7d4415e523b99319e4fb6b81..ff578b3e3d7eb397cac0fac8cb010dec57d10364 100644
--- a/core/lib/Drupal/Component/Gettext/composer.json
+++ b/core/lib/Drupal/Component/Gettext/composer.json
@@ -9,7 +9,7 @@
     "source": "https://www.drupal.org/project/drupal/git-instructions"
   },
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "drupal/core-utility": "^8.2"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/Graph/composer.json b/core/lib/Drupal/Component/Graph/composer.json
index e8f645fd20c1da0a196188949cfc82bb5d9261a2..ea144deb8e0739afcd3681ed1066533142b38cd9 100644
--- a/core/lib/Drupal/Component/Graph/composer.json
+++ b/core/lib/Drupal/Component/Graph/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9"
+    "php": ">=7.0.8"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Component/HttpFoundation/composer.json b/core/lib/Drupal/Component/HttpFoundation/composer.json
index 910a648a2115d212691fbd5ebc7ed50fa4a53c4c..7c133d6cdfdfb885266f3443e8f5863d7d0c515b 100644
--- a/core/lib/Drupal/Component/HttpFoundation/composer.json
+++ b/core/lib/Drupal/Component/HttpFoundation/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "symfony/http-foundation": ">=2.7 <4.0.0"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/PhpStorage/composer.json b/core/lib/Drupal/Component/PhpStorage/composer.json
index 614652a95c6c4aa5595147f4fe3c6aeeb254c5cf..e4ff9b69be2f440e333cf5f484b431c968d79838 100644
--- a/core/lib/Drupal/Component/PhpStorage/composer.json
+++ b/core/lib/Drupal/Component/PhpStorage/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9"
+    "php": ">=7.0.8"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Component/Plugin/composer.json b/core/lib/Drupal/Component/Plugin/composer.json
index 77f02d6fb1c2ddf42e9c18216ba9b9063938272a..76883c83f0c91c1a0efb58a32fb41fc81364bbe9 100644
--- a/core/lib/Drupal/Component/Plugin/composer.json
+++ b/core/lib/Drupal/Component/Plugin/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "symfony/validator": ">=2.7 <4.0.0"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/ProxyBuilder/composer.json b/core/lib/Drupal/Component/ProxyBuilder/composer.json
index 52fbdb8065762738767f574b84d82861f2028b50..7e024a82453b61cd8277a7a9fda8341b093f6134 100644
--- a/core/lib/Drupal/Component/ProxyBuilder/composer.json
+++ b/core/lib/Drupal/Component/ProxyBuilder/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9"
+    "php": ">=7.0.8"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Component/Render/composer.json b/core/lib/Drupal/Component/Render/composer.json
index 9e44b2dd395cac418b255891271399849c4f93f8..e92cd1e28f4436365ceb8c51e7a98897f244ec3c 100644
--- a/core/lib/Drupal/Component/Render/composer.json
+++ b/core/lib/Drupal/Component/Render/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "drupal/core-utility": "^8.2"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/Serialization/composer.json b/core/lib/Drupal/Component/Serialization/composer.json
index 3439f5863980f955443f35a0c8688b122df28c16..9466c010e28fda201243fac18add50a893116f2d 100644
--- a/core/lib/Drupal/Component/Serialization/composer.json
+++ b/core/lib/Drupal/Component/Serialization/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "symfony/yaml": ">=2.7 <4.0.0"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/Utility/Crypt.php b/core/lib/Drupal/Component/Utility/Crypt.php
index 6ebdc4aac831b4cd4824417d6e3f9be452470322..7791b05a1a76d5dd4bd9f2300e1b965475f458d5 100644
--- a/core/lib/Drupal/Component/Utility/Crypt.php
+++ b/core/lib/Drupal/Component/Utility/Crypt.php
@@ -27,45 +27,12 @@ class Crypt {
    *
    * @return string
    *   A randomly generated string.
+   *
+   * @todo Deprecate in favor of random_bytes().
+   *   https://www.drupal.org/node/3054311
    */
   public static function randomBytes($count) {
-    try {
-      return random_bytes($count);
-    }
-    catch (\Exception $e) {
-      // $random_state does not use drupal_static as it stores random bytes.
-      static $random_state, $bytes;
-      // If the compatibility library fails, this simple hash-based PRNG will
-      // generate a good set of pseudo-random bytes on any system.
-      // Note that it may be important that our $random_state is passed
-      // through hash() prior to being rolled into $output, that the two hash()
-      // invocations are different, and that the extra input into the first one
-      // - the microtime() - is prepended rather than appended. This is to avoid
-      // directly leaking $random_state via the $output stream, which could
-      // allow for trivial prediction of further "random" numbers.
-      if (strlen($bytes) < $count) {
-        // Initialize on the first call. The $_SERVER variable includes user and
-        // system-specific information that varies a little with each page.
-        if (!isset($random_state)) {
-          $random_state = print_r($_SERVER, TRUE);
-          if (function_exists('getmypid')) {
-            // Further initialize with the somewhat random PHP process ID.
-            $random_state .= getmypid();
-          }
-          $bytes = '';
-          // Ensure mt_rand() is reseeded before calling it the first time.
-          mt_srand();
-        }
-
-        do {
-          $random_state = hash('sha256', microtime() . mt_rand() . $random_state);
-          $bytes .= hash('sha256', mt_rand() . $random_state, TRUE);
-        } while (strlen($bytes) < $count);
-      }
-      $output = substr($bytes, 0, $count);
-      $bytes = substr($bytes, $count);
-      return $output;
-    }
+    return random_bytes($count);
   }
 
   /**
@@ -120,37 +87,12 @@ public static function hashBase64($data) {
    *
    * @return bool
    *   Returns TRUE when the two strings are equal, FALSE otherwise.
+   *
+   * @todo Deprecate in favor of hash_equals().
+   *   https://www.drupal.org/node/3053956
    */
   public static function hashEquals($known_string, $user_string) {
-    if (function_exists('hash_equals')) {
-      return hash_equals($known_string, $user_string);
-    }
-    else {
-      // Backport of hash_equals() function from PHP 5.6
-      // @see https://github.com/php/php-src/blob/PHP-5.6/ext/hash/hash.c#L739
-      if (!is_string($known_string)) {
-        trigger_error(sprintf("Expected known_string to be a string, %s given", gettype($known_string)), E_USER_WARNING);
-        return FALSE;
-      }
-
-      if (!is_string($user_string)) {
-        trigger_error(sprintf("Expected user_string to be a string, %s given", gettype($user_string)), E_USER_WARNING);
-        return FALSE;
-      }
-
-      $known_len = strlen($known_string);
-      if ($known_len !== strlen($user_string)) {
-        return FALSE;
-      }
-
-      // This is security sensitive code. Do not optimize this for speed.
-      $result = 0;
-      for ($i = 0; $i < $known_len; $i++) {
-        $result |= (ord($known_string[$i]) ^ ord($user_string[$i]));
-      }
-
-      return $result === 0;
-    }
+    return hash_equals($known_string, $user_string);
   }
 
   /**
diff --git a/core/lib/Drupal/Component/Utility/Unicode.php b/core/lib/Drupal/Component/Utility/Unicode.php
index 7cf2351603d317540404da0721e52778467daa69..f77bdc12c7d619aa518c1e29c37e9a4c98d3fc2e 100644
--- a/core/lib/Drupal/Component/Utility/Unicode.php
+++ b/core/lib/Drupal/Component/Utility/Unicode.php
@@ -162,16 +162,6 @@ public static function check() {
     if (ini_get('mbstring.encoding_translation') != 0) {
       return 'mbstring.encoding_translation';
     }
-    // mbstring.http_input and mbstring.http_output are deprecated and empty by
-    // default in PHP 5.6.
-    if (version_compare(PHP_VERSION, '5.6.0') == -1) {
-      if (ini_get('mbstring.http_input') != 'pass') {
-        return 'mbstring.http_input';
-      }
-      if (ini_get('mbstring.http_output') != 'pass') {
-        return 'mbstring.http_output';
-      }
-    }
 
     return '';
   }
diff --git a/core/lib/Drupal/Component/Utility/UrlHelper.php b/core/lib/Drupal/Component/Utility/UrlHelper.php
index 9e2365c1aef5c1de8b311a3f1d50f807b3b37972..bd550460f916837342c6694a7ed0f6126fb32666 100644
--- a/core/lib/Drupal/Component/Utility/UrlHelper.php
+++ b/core/lib/Drupal/Component/Utility/UrlHelper.php
@@ -27,7 +27,7 @@ class UrlHelper {
    * not valid as a "URL" in HTML5.
    *
    * @todo Remove this function once PHP 5.4 is required as we can use just
-   *   http_build_query() directly.
+   *   http_build_query() directly. https://www.drupal.org/node/2322059
    *
    * @param array $query
    *   The query parameter array to be processed; for instance,
diff --git a/core/lib/Drupal/Component/Utility/composer.json b/core/lib/Drupal/Component/Utility/composer.json
index b89e81390383cb36f6a3ae015e13f8e34c46d3ae..dcbc5c47163f34c3a91f70dab588b0d97fecdf85 100644
--- a/core/lib/Drupal/Component/Utility/composer.json
+++ b/core/lib/Drupal/Component/Utility/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "paragonie/random_compat": "^1.0|^2.0",
     "drupal/core-render": "^8.2",
     "symfony/polyfill-iconv": "~1.0",
diff --git a/core/lib/Drupal/Component/Uuid/composer.json b/core/lib/Drupal/Component/Uuid/composer.json
index fb78d9e0e8b3d0416afd028d7de23b57c9159920..b63bf96f8eab0d2e743cfbc202d04ff12c3b0c15 100644
--- a/core/lib/Drupal/Component/Uuid/composer.json
+++ b/core/lib/Drupal/Component/Uuid/composer.json
@@ -9,7 +9,7 @@
     "source": "https://www.drupal.org/project/drupal/git-instructions"
   },
   "require": {
-    "php": ">=5.5.9",
+    "php": ">=7.0.8",
     "drupal/core-utility": "^8.2"
   },
   "autoload": {
diff --git a/core/lib/Drupal/Component/Version/composer.json b/core/lib/Drupal/Component/Version/composer.json
index 146cbe3aed352d2a44bec364328701e2e659cb81..3532e94be26434bb8795011fd9ebde26dc8f8bfb 100644
--- a/core/lib/Drupal/Component/Version/composer.json
+++ b/core/lib/Drupal/Component/Version/composer.json
@@ -5,7 +5,7 @@
   "homepage": "https://www.drupal.org/project/drupal",
   "license": "GPL-2.0-or-later",
   "require": {
-    "php": ">=5.5.9"
+    "php": ">=7.0.8"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Core/Controller/FormController.php b/core/lib/Drupal/Core/Controller/FormController.php
index acbcaf6c67db85e824485ef22b2f854d8e44b065..b6ad3f05831d2a9ab257f3a7a31e94c5a890c62c 100644
--- a/core/lib/Drupal/Core/Controller/FormController.php
+++ b/core/lib/Drupal/Core/Controller/FormController.php
@@ -12,7 +12,7 @@
 /**
  * Common base class for form interstitial controllers.
  *
- * @todo Make this a trait in PHP 5.4.
+ * @todo Make this a trait in PHP 5.4. https://www.drupal.org/node/3054053
  */
 abstract class FormController {
   use DependencySerializationTrait;
diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
index 99537dd356fc7e5ae649ca6c2f0d4d06545312f9..04abdd43753ea2784864a65c394d7137bc050366 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
@@ -409,12 +409,9 @@ public static function open(array &$connection_options = []) {
       \PDO::MYSQL_ATTR_FOUND_ROWS => TRUE,
       // Because MySQL's prepared statements skip the query cache, because it's dumb.
       \PDO::ATTR_EMULATE_PREPARES => TRUE,
+      // Limit SQL to a single statement like mysqli.
+      \PDO::MYSQL_ATTR_MULTI_STATEMENTS => FALSE,
     ];
-    if (defined('\PDO::MYSQL_ATTR_MULTI_STATEMENTS')) {
-      // An added connection option in PHP 5.5.21 to optionally limit SQL to a
-      // single statement like mysqli.
-      $connection_options['pdo'] += [\PDO::MYSQL_ATTR_MULTI_STATEMENTS => FALSE];
-    }
 
     try {
       $pdo = new \PDO($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 7c9fb6c8ef4adf12922000d48d8709921ba779de..e3607d237b8aebec9182c00b78092078b17fa4ea 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -907,16 +907,6 @@ protected function initializeContainer() {
     // If there is no container and no cached container definition, build a new
     // one from scratch.
     if (!isset($container) && !isset($container_definition)) {
-      // Building the container creates 1000s of objects. Garbage collection of
-      // these objects is expensive. This appears to be causing random
-      // segmentation faults in PHP 5.6 due to
-      // https://bugs.php.net/bug.php?id=72286. Once the container is rebuilt,
-      // garbage collection is re-enabled.
-      $disable_gc = version_compare(PHP_VERSION, '7', '<') && gc_enabled();
-      if ($disable_gc) {
-        gc_collect_cycles();
-        gc_disable();
-      }
       $container = $this->compileContainer();
 
       // Only dump the container if dumping is allowed. This is useful for
@@ -926,11 +916,6 @@ protected function initializeContainer() {
         $dumper = new $this->phpArrayDumperClass($container);
         $container_definition = $dumper->getArray();
       }
-      // If garbage collection was disabled prior to rebuilding container,
-      // re-enable it.
-      if ($disable_gc) {
-        gc_enable();
-      }
     }
 
     // The container was rebuilt successfully.
@@ -1043,8 +1028,6 @@ public static function bootEnvironment($app_root = NULL) {
 
         // Web tests are to be conducted with runtime assertions active.
         assert_options(ASSERT_ACTIVE, TRUE);
-        // Now synchronize PHP 5 and 7's handling of assertions as much as
-        // possible.
         Handle::register();
 
         // Log fatal errors to the test site directory.
diff --git a/core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php b/core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php
index ac69f01a0caeffbb0ba795672368fbd83aea1b14..deba59bf1196f3e67e764ff2d9af3193cf6c521c 100644
--- a/core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php
+++ b/core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php
@@ -27,6 +27,7 @@
  *
  * @todo Use RecursiveCallbackFilterIterator instead of the $acceptTests
  *   parameter forwarding once PHP 5.4 is available.
+ *   https://www.drupal.org/node/2532228
  */
 class RecursiveExtensionFilterIterator extends \RecursiveFilterIterator {
 
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
index abb4edde32b177ba4c2603455bf4ec895042c45c..c87191a894eb8893940425e3d9e27fb27108e1f0 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
@@ -310,7 +310,7 @@ public function invokeAllDeprecated($description, $hook, array $args = []);
    *   $this->alter('mymodule_data', $alterable1, $alterable2, $context);
    * @endcode
    *
-   * Note that objects are always passed by reference in PHP5. If it is absolutely
+   * Note that objects are always passed by reference. If it is absolutely
    * required that no implementation alters a passed object in $context, then an
    * object needs to be cloned:
    * @code
diff --git a/core/lib/Drupal/Core/Field/FieldConfigBase.php b/core/lib/Drupal/Core/Field/FieldConfigBase.php
index ac6596f82ac94c015569a83169c0e8b9d59d21d0..44e415ace7703755e36301740b91ba2ed8e72bc3 100644
--- a/core/lib/Drupal/Core/Field/FieldConfigBase.php
+++ b/core/lib/Drupal/Core/Field/FieldConfigBase.php
@@ -440,7 +440,7 @@ public function setDefaultValueCallback($callback) {
    *
    * Using the Serialize interface and serialize() / unserialize() methods
    * breaks entity forms in PHP 5.4.
-   * @todo Investigate in https://www.drupal.org/node/2074253.
+   * @todo Investigate in https://www.drupal.org/node/1977206.
    */
   public function __sleep() {
     // Only serialize necessary properties, excluding those that can be
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
index 5550ede34a7d02e285d55f26da45bf320fd96db1..be4887aaa70fea342f345aae587df2d76b9ced0f 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
@@ -64,12 +64,7 @@ public function setValue($values, $notify = TRUE) {
         $values = $values->getValue();
       }
       else {
-        if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
-          $values = unserialize($values, ['allowed_classes' => FALSE]);
-        }
-        else {
-          $values = unserialize($values);
-        }
+        $values = unserialize($values, ['allowed_classes' => FALSE]);
       }
     }
 
diff --git a/core/lib/Drupal/Core/Password/PhpassHashedPassword.php b/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
index d7afecd6eee99cfdf5f2c987cb584cad8e8080c9..75083e2b5d5b6219aea92c982ea9dfe182ba5b61 100644
--- a/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
+++ b/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
@@ -182,7 +182,6 @@ protected function crypt($algo, $password, $setting) {
     // Convert the base 2 logarithm into an integer.
     $count = 1 << $count_log2;
 
-    // We rely on the hash() function being available in PHP 5.2+.
     $hash = hash($algo, $salt . $password, TRUE);
     do {
       $hash = hash($algo, $hash . $password, TRUE);
diff --git a/core/lib/Drupal/Core/Theme/ThemeManagerInterface.php b/core/lib/Drupal/Core/Theme/ThemeManagerInterface.php
index 2af80749c53c166a875a3cc0becca7712e752890..3b1e1e49b9ec964a62ead97d6001aca681c322fb 100644
--- a/core/lib/Drupal/Core/Theme/ThemeManagerInterface.php
+++ b/core/lib/Drupal/Core/Theme/ThemeManagerInterface.php
@@ -87,9 +87,9 @@ public function setActiveTheme(ActiveTheme $active_theme);
    *   $this->alter('mymodule_data', $alterable1, $alterable2, $context);
    * @endcode
    *
-   * Note that objects are always passed by reference in PHP5. If it is
-   * absolutely required that no implementation alters a passed object in
-   * $context, then an object needs to be cloned:
+   * Note that objects are always passed by reference. If it is absolutely
+   * required that no implementation alters a passed object in $context, then an
+   * object needs to be cloned:
    * @code
    *   $context = array(
    *     'unalterable_object' => clone $object,
diff --git a/core/lib/Drupal/Core/TypedData/TypedData.php b/core/lib/Drupal/Core/TypedData/TypedData.php
index bc1702a70812f4e9dc624b1e49ff1009c3adb09b..1ec09e89766933608d1a5ced6ef3ba24a84a55f9 100644
--- a/core/lib/Drupal/Core/TypedData/TypedData.php
+++ b/core/lib/Drupal/Core/TypedData/TypedData.php
@@ -3,6 +3,7 @@
 namespace Drupal\Core\TypedData;
 
 use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 
 /**
@@ -14,7 +15,7 @@
  * @ingroup typed_data
  */
 abstract class TypedData implements TypedDataInterface, PluginInspectionInterface {
-
+  use DependencySerializationTrait;
   use StringTranslationTrait;
   use TypedDataTrait;
 
@@ -191,22 +192,4 @@ public function getParent() {
     return $this->parent;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function __sleep() {
-    $vars = get_object_vars($this);
-    // Prevent services from being serialized. static::getStringTranslation()
-    // and static::getTypedDataManager() lazy-load them after $this has been
-    // unserialized.
-    // @todo Replace this with
-    //   \Drupal\Core\DependencyInjection\DependencySerializationTrait before
-    //   Drupal 9.0.0. We cannot use that now, because child classes already use
-    //   it and PHP 5 would consider that conflicts.
-    unset($vars['stringTranslation']);
-    unset($vars['typedDataManager']);
-
-    return array_keys($vars);
-  }
-
 }
diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php
index 2c02eebf442df62eaa65cb551a9f8b67a20a0ec1..91c619087b30c86db546c6486017a2b474ad3129 100644
--- a/core/modules/field/src/Entity/FieldStorageConfig.php
+++ b/core/modules/field/src/Entity/FieldStorageConfig.php
@@ -715,7 +715,7 @@ public function hasData() {
    *
    * Using the Serialize interface and serialize() / unserialize() methods
    * breaks entity forms in PHP 5.4.
-   * @todo Investigate in https://www.drupal.org/node/2074253.
+   * @todo Investigate in https://www.drupal.org/node/1977206.
    */
   public function __sleep() {
     // Only serialize necessary properties, excluding those that can be
diff --git a/core/modules/field_layout/src/Entity/FieldLayoutEntityFormDisplay.php b/core/modules/field_layout/src/Entity/FieldLayoutEntityFormDisplay.php
index c58938e0a43d2b082757570401d5c63d95b83a79..b85485424af57d9c37d1cf1cc09a2d1b40882bfe 100644
--- a/core/modules/field_layout/src/Entity/FieldLayoutEntityFormDisplay.php
+++ b/core/modules/field_layout/src/Entity/FieldLayoutEntityFormDisplay.php
@@ -18,6 +18,7 @@ class FieldLayoutEntityFormDisplay extends EntityFormDisplay implements EntityDi
   public function getDefaultRegion() {
     // This cannot be provided by the trait due to
     // https://bugs.php.net/bug.php?id=71414 which is fixed in PHP 7.0.6.
+    // @todo Move to trait. https://www.drupal.org/node/3054317
     return $this->getLayoutDefinition($this->getLayoutId())->getDefaultRegion();
   }
 
diff --git a/core/modules/field_layout/src/Entity/FieldLayoutEntityViewDisplay.php b/core/modules/field_layout/src/Entity/FieldLayoutEntityViewDisplay.php
index 4f0c27402f6efc864ef47c2bfffc3a4de5bbc75a..0fe564b1fb2da9d86fecdff437efe609b4b79b84 100644
--- a/core/modules/field_layout/src/Entity/FieldLayoutEntityViewDisplay.php
+++ b/core/modules/field_layout/src/Entity/FieldLayoutEntityViewDisplay.php
@@ -18,6 +18,7 @@ class FieldLayoutEntityViewDisplay extends EntityViewDisplay implements EntityDi
   public function getDefaultRegion() {
     // This cannot be provided by the trait due to
     // https://bugs.php.net/bug.php?id=71414 which is fixed in PHP 7.0.6.
+    // @todo Move to trait. https://www.drupal.org/node/3054317
     return $this->getLayoutDefinition($this->getLayoutId())->getDefaultRegion();
   }
 
diff --git a/core/modules/file/file.install b/core/modules/file/file.install
index 5140a2ef4994c258a9fdcc330365d55fab177726..cd49acbabcba35dafd46d55b7a28f2db74579c7f 100644
--- a/core/modules/file/file.install
+++ b/core/modules/file/file.install
@@ -102,10 +102,6 @@ function file_requirements($phase) {
       $value = t('Not enabled');
       $description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the <a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress library</a>.');
     }
-    elseif ($implementation == 'apc') {
-      $value = t('Enabled (<a href="http://php.net/manual/apcu.configuration.php#ini.apcu.rfc1867">APC RFC1867</a>)');
-      $description = t('Your server is capable of displaying file upload progress using APC RFC1867. Note that only one upload at a time is supported. It is recommended to use the <a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress library</a> if possible.');
-    }
     elseif ($implementation == 'uploadprogress') {
       $value = t('Enabled (<a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress</a>)');
     }
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 93b277f3e4c2c109b2bdcceb5a8810813fad0e68..03e69c62b88a09406e6653b17f12ca61da65bda4 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -1138,9 +1138,6 @@ function file_progress_implementation() {
     if (extension_loaded('uploadprogress')) {
       $implementation = 'uploadprogress';
     }
-    elseif (version_compare(PHP_VERSION, '7', '<') && extension_loaded('apc') && ini_get('apc.rfc1867')) {
-      $implementation = 'apc';
-    }
   }
   return $implementation;
 }
diff --git a/core/modules/file/src/Controller/FileWidgetAjaxController.php b/core/modules/file/src/Controller/FileWidgetAjaxController.php
index c958750443078d68f59232c052c5b581e3cee4c9..474beb0dda97d913549774e3c4cb94615fed47c5 100644
--- a/core/modules/file/src/Controller/FileWidgetAjaxController.php
+++ b/core/modules/file/src/Controller/FileWidgetAjaxController.php
@@ -32,13 +32,6 @@ public function progress($key) {
         $progress['percentage'] = round(100 * $status['bytes_uploaded'] / $status['bytes_total']);
       }
     }
-    elseif ($implementation == 'apc') {
-      $status = apcu_fetch('upload_' . $key);
-      if (isset($status['current']) && !empty($status['total'])) {
-        $progress['message'] = t('Uploading... (@current of @total)', ['@current' => format_size($status['current']), '@total' => format_size($status['total'])]);
-        $progress['percentage'] = round(100 * $status['current'] / $status['total']);
-      }
-    }
 
     return new JsonResponse($progress);
   }
diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php
index b26118916e577f991ea0cfecbd40d34d66018205..1d3f252fed2f5223921d9fde1d7d5844b977b934 100644
--- a/core/modules/file/src/Element/ManagedFile.php
+++ b/core/modules/file/src/Element/ManagedFile.php
@@ -286,16 +286,6 @@ public static function processManagedFile(&$element, FormStateInterface $form_st
           '#weight' => -20,
         ];
       }
-      elseif ($implementation == 'apc') {
-        $element['APC_UPLOAD_PROGRESS'] = [
-          '#type' => 'hidden',
-          '#value' => $upload_progress_key,
-          '#attributes' => ['class' => ['file-progress']],
-          // Uploadprogress extension requires this field to be at the top of
-          // the form.
-          '#weight' => -20,
-        ];
-      }
 
       // Add the upload progress callback.
       $element['upload_button']['#ajax']['progress']['url'] = Url::fromRoute('file.ajax_progress', ['key' => $upload_progress_key]);
diff --git a/core/modules/file/tests/src/Functional/DownloadTest.php b/core/modules/file/tests/src/Functional/DownloadTest.php
index bf25a44cad35680cf66a222cc14f05b5402f5dc5..68ef66c2110c2e9fb27d17aaec68e9d5bce2a7da 100644
--- a/core/modules/file/tests/src/Functional/DownloadTest.php
+++ b/core/modules/file/tests/src/Functional/DownloadTest.php
@@ -92,17 +92,13 @@ protected function doPrivateFileTransferTest() {
    * Test file_create_url().
    */
   public function testFileCreateUrl() {
-
-    // Tilde (~) is excluded from this test because it is encoded by
-    // rawurlencode() in PHP 5.2 but not in PHP 5.3, as per RFC 3986.
-    // @see http://php.net/manual/function.rawurlencode.php#86506
     // "Special" ASCII characters.
-    $basename = " -._!$'\"()*@[]?&+%#,;=:\n\x00" .
+    $basename = " -._~!$'\"()*@[]?&+%#,;=:\n\x00" .
       // Characters that look like a percent-escaped string.
       "%23%25%26%2B%2F%3F" .
       // Characters from various non-ASCII alphabets.
       "éøïвβ中國書۞";
-    $basename_encoded = '%20-._%21%24%27%22%28%29%2A%40%5B%5D%3F%26%2B%25%23%2C%3B%3D%3A__' .
+    $basename_encoded = '%20-._~%21%24%27%22%28%29%2A%40%5B%5D%3F%26%2B%25%23%2C%3B%3D%3A__' .
       '%2523%2525%2526%252B%252F%253F' .
       '%C3%A9%C3%B8%C3%AF%D0%B2%CE%B2%E4%B8%AD%E5%9C%8B%E6%9B%B8%DB%9E';
 
diff --git a/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php b/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php
index 61b5827fd9025fe435eb4098763ea300347c561c..3382244520d52e20110e4c57b7ce5b4027b84e72 100644
--- a/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php
+++ b/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php
@@ -125,9 +125,7 @@ public function onResponse(FilterResponseEvent $event) {
    * @see self::validateResponse
    */
   public function doValidateResponse(Response $response, Request $request) {
-    if (PHP_MAJOR_VERSION >= 7 || assert_options(ASSERT_ACTIVE)) {
-      assert($this->validateResponse($response, $request), 'A JSON:API response failed validation (see the logs for details). Please report this in the issue queue on drupal.org');
-    }
+    assert($this->validateResponse($response, $request), 'A JSON:API response failed validation (see the logs for details). Please report this in the issue queue on drupal.org');
   }
 
   /**
diff --git a/core/modules/jsonapi/tests/src/Functional/CommentTest.php b/core/modules/jsonapi/tests/src/Functional/CommentTest.php
index 01941776336678e7560bcd1197af1b5a0bef284c..d9fc52ae9f7530af3503959a6e591d30408dc95c 100644
--- a/core/modules/jsonapi/tests/src/Functional/CommentTest.php
+++ b/core/modules/jsonapi/tests/src/Functional/CommentTest.php
@@ -323,12 +323,7 @@ public function testPostIndividualDxWithoutCriticalBaseFields() {
       $this->assertResourceErrorResponse(422, 'entity_id: This value should not be null.', NULL, $response, '/data/attributes/entity_id');
     }
     catch (\Exception $e) {
-      if (version_compare(phpversion(), '7.0') >= 0) {
-        $this->assertSame("Error: Call to a member function get() on null\nDrupal\\comment\\Plugin\\Validation\\Constraint\\CommentNameConstraintValidator->getAnonymousContactDetailsSetting()() (Line: 96)\n", $e->getMessage());
-      }
-      else {
-        $this->assertSame(500, $response->getStatusCode());
-      }
+      $this->assertSame("Error: Call to a member function get() on null\nDrupal\\comment\\Plugin\\Validation\\Constraint\\CommentNameConstraintValidator->getAnonymousContactDetailsSetting()() (Line: 96)\n", $e->getMessage());
     }
 
     // DX: 422 when missing 'field_name' field.
diff --git a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
index ee688dd75d5b83a97f32bc5a697772ff6125c504..373c3f03adeba4e7ecb913716d13ac9d9f805e86 100644
--- a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
@@ -190,12 +190,7 @@ public function setValue($values, $notify = TRUE) {
     // this, options must not be passed as a string anymore.
     if (is_string($values['options'])) {
       @trigger_error('Support for passing options as a serialized string is deprecated in 8.7.0 and will be removed before Drupal 9.0.0. Pass them as an array instead. See https://www.drupal.org/node/2961643.', E_USER_DEPRECATED);
-      if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
-        $values['options'] = unserialize($values['options'], ['allowed_classes' => FALSE]);
-      }
-      else {
-        $values['options'] = unserialize($values['options']);
-      }
+      $values['options'] = unserialize($values['options'], ['allowed_classes' => FALSE]);
     }
     parent::setValue($values, $notify);
   }
diff --git a/core/modules/rest/rest.install b/core/modules/rest/rest.install
index 754c27f4642a178d73a87cbdde0b981e6cc78250..5fdb5cc9e28130e6c5a74fbb63157f95f9d5837b 100644
--- a/core/modules/rest/rest.install
+++ b/core/modules/rest/rest.install
@@ -8,23 +8,6 @@
 use Drupal\Core\Config\Entity\ConfigEntityType;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 
-/**
- * Implements hook_requirements().
- */
-function rest_requirements($phase) {
-  $requirements = [];
-
-  if ($phase == 'runtime' && PHP_SAPI !== 'cli' && version_compare(PHP_VERSION, '5.6.0', '>=') && version_compare(PHP_VERSION, '7', '<') && ini_get('always_populate_raw_post_data') != -1) {
-    $requirements['always_populate_raw_post_data'] = [
-      'title' => t('always_populate_raw_post_data PHP setting'),
-      'value' => t('Not set to -1.'),
-      'severity' => REQUIREMENT_ERROR,
-      'description' => t('The always_populate_raw_post_data PHP setting should be set to -1 in PHP version 5.6. Please check the <a href="https://php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data">PHP manual</a> for information on how to correct this.'),
-    ];
-  }
-  return $requirements;
-}
-
 /**
  * Install the REST config entity type and fix old settings-based config.
  *
diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php
index 8cb5644f305fc56d3cd962a4ce09a86cd5cef5ee..ef886c07688b429d7d7f2a6e536543a1684f43b7 100644
--- a/core/modules/simpletest/src/TestBase.php
+++ b/core/modules/simpletest/src/TestBase.php
@@ -923,8 +923,7 @@ public function run(array $methods = []) {
       $this->httpAuthCredentials = $username . ':' . $password;
     }
 
-    // Force assertion failures to be thrown as AssertionError for PHP 5 & 7
-    // compatibility.
+    // Force assertion failures to be thrown as exceptions.
     Handle::register();
 
     set_error_handler([$this, 'errorHandler']);
diff --git a/core/modules/system/src/SystemRequirements.php b/core/modules/system/src/SystemRequirements.php
index 969350bfcf3395f4e463099f85c5a2af22e1b2c7..225a8b819f8c67d7fae14cc642d6553663cf6b81 100644
--- a/core/modules/system/src/SystemRequirements.php
+++ b/core/modules/system/src/SystemRequirements.php
@@ -4,6 +4,8 @@
 
 /**
  * Class for helper methods used for the system requirements.
+ *
+ * @todo Deprecate this class. https://www.drupal.org/node/3054060
  */
 class SystemRequirements {
 
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index b7f99d9bf983b41b2522950b4dd05afc39983723..c6d1678834cf0fc3006e3b822149f1453831e46a 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -952,12 +952,7 @@ function system_requirements($phase) {
 
   // Warning for httpoxy on IIS with affected PHP versions
   // @see https://www.drupal.org/node/2783079
-  if (strpos($software, 'Microsoft-IIS') !== FALSE
-    && (
-    version_compare(PHP_VERSION, '5.5.38', '<')
-    || (version_compare(PHP_VERSION, '5.6.0', '>=') && version_compare(PHP_VERSION, '5.6.24', '<'))
-    || (version_compare(PHP_VERSION, '7.0.0', '>=') && version_compare(PHP_VERSION, '7.0.9', '<'))
-    )) {
+  if (strpos($software, 'Microsoft-IIS') !== FALSE && version_compare(PHP_VERSION, '7.0.9', '<')) {
     $dom = new \DOMDocument('1.0', 'UTF-8');
     $webconfig = file_get_contents('web.config');
     // If you are here the web.config file must - of course - be well formed.
diff --git a/core/scripts/password-hash.sh b/core/scripts/password-hash.sh
index 18d057abc7c847c46cf3e6d16bad926d4853510a..767e9489f82cd568900d8a9c2dbceb11bf643cc6 100755
--- a/core/scripts/password-hash.sh
+++ b/core/scripts/password-hash.sh
@@ -7,6 +7,8 @@
  *
  * @param password1 [password2 [password3 ...]]
  *  Plain-text passwords in quotes (or with spaces backslash escaped).
+ *
+ * @todo Port to a console command. https://www.drupal.org/node/2289409
  */
 
 use Drupal\Core\DrupalKernel;
diff --git a/core/tests/Drupal/FunctionalTests/Bootstrap/UncaughtExceptionTest.php b/core/tests/Drupal/FunctionalTests/Bootstrap/UncaughtExceptionTest.php
index 1bc789c92740ef0a904bc1cb4e8e8c4dd37bb291..1a0f19e971d78b3678e6a3b7354556b299b94373 100644
--- a/core/tests/Drupal/FunctionalTests/Bootstrap/UncaughtExceptionTest.php
+++ b/core/tests/Drupal/FunctionalTests/Bootstrap/UncaughtExceptionTest.php
@@ -105,16 +105,10 @@ public function testUncaughtException() {
    */
   public function testUncaughtFatalError() {
     $fatal_error = [
-      '%type' => 'Recoverable fatal error',
-      '@message' => 'Argument 1 passed to Drupal\error_test\Controller\ErrorTestController::Drupal\error_test\Controller\{closure}() must be of the type array, string given, called in ' . \Drupal::root() . '/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php on line 62 and defined',
+      '%type' => 'TypeError',
+      '@message' => 'Argument 1 passed to Drupal\error_test\Controller\ErrorTestController::Drupal\error_test\Controller\{closure}() must be of the type array, string given, called in ' . \Drupal::root() . '/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php on line 62',
       '%function' => 'Drupal\error_test\Controller\ErrorTestController->Drupal\error_test\Controller\{closure}()',
     ];
-    if (version_compare(PHP_VERSION, '7.0.0-dev') >= 0) {
-      // In PHP 7, instead of a recoverable fatal error we get a TypeError.
-      $fatal_error['%type'] = 'TypeError';
-      // The error message also changes in PHP 7.
-      $fatal_error['@message'] = 'Argument 1 passed to Drupal\error_test\Controller\ErrorTestController::Drupal\error_test\Controller\{closure}() must be of the type array, string given, called in ' . \Drupal::root() . '/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php on line 62';
-    }
     $this->drupalGet('error-test/generate-fatals');
     $this->assertResponse(500, 'Received expected HTTP status code.');
     $message = new FormattableMarkup('%type: @message in %function (line ', $fatal_error);
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index 73a2fd400293e4b3287fdbb6b5da7794eb5b9790..de184cb0fa3dc62a88dee40ed0c7c8b7f1164209 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -380,15 +380,6 @@ protected function registerSessions() {}
    * {@inheritdoc}
    */
   protected function setUp() {
-    // Installing Drupal creates 1000s of objects. Garbage collection of these
-    // objects is expensive. This appears to be causing random segmentation
-    // faults in PHP 5.x due to https://bugs.php.net/bug.php?id=72286. Once
-    // Drupal is installed is rebuilt, garbage collection is re-enabled.
-    $disable_gc = version_compare(PHP_VERSION, '7', '<') && gc_enabled();
-    if ($disable_gc) {
-      gc_collect_cycles();
-      gc_disable();
-    }
     parent::setUp();
 
     $this->setupBaseUrl();
@@ -402,11 +393,6 @@ protected function setUp() {
 
     // Set up the browser test output file.
     $this->initBrowserOutputFile();
-    // If garbage collection was disabled prior to rebuilding container,
-    // re-enable it.
-    if ($disable_gc) {
-      gc_enable();
-    }
 
     // Ensure that the test is not marked as risky because of no assertions. In
     // PHPUnit 6 tests that only make assertions using $this->assertSession()
diff --git a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
index 6e7040adf13e0455c8c39df42b14277a006bc934..b29f94647a52c1a173ed51b10fb86ae2f198c70f 100644
--- a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
+++ b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
@@ -329,11 +329,9 @@ public function providerTestDates() {
     if (PHP_INT_SIZE > 4) {
       // Create a date object in the distant past.
       // @see https://www.drupal.org/node/2795489#comment-12127088
-      if (version_compare(PHP_VERSION, '5.6.15', '>=')) {
-        // Note that this date is after the United States standardized its
-        // timezones.
-        $dates[] = ['1883-11-19 10:30', 'America/Chicago', '1883-11-19T10:30:00-06:00'];
-      }
+      // Note that this date is after the United States standardized its
+      // timezones.
+      $dates[] = ['1883-11-19 10:30', 'America/Chicago', '1883-11-19T10:30:00-06:00'];
       // Create a date object in the far future.
       $dates[] = ['2345-01-02 02:04', 'UTC', '2345-01-02T02:04:00+00:00'];
     }
@@ -367,11 +365,9 @@ public function providerTestDateArrays() {
     if (PHP_INT_SIZE > 4) {
       // Create a date object in the distant past.
       // @see https://www.drupal.org/node/2795489#comment-12127088
-      if (version_compare(PHP_VERSION, '5.6.15', '>=')) {
-        // Note that this date is after the United States standardized its
-        // timezones.
-        $dates[] = [['year' => 1883, 'month' => 11, 'day' => 19], 'America/Chicago', '1883-11-19T00:00:00-06:00'];
-      }
+      // Note that this date is after the United States standardized its
+      // timezones.
+      $dates[] = [['year' => 1883, 'month' => 11, 'day' => 19], 'America/Chicago', '1883-11-19T00:00:00-06:00'];
       // Create a date object in the far future.
       $dates[] = [['year' => 2345, 'month' => 1, 'day' => 2], 'UTC', '2345-01-02T00:00:00+00:00'];
     }
diff --git a/core/tests/Drupal/Tests/Component/Utility/CryptRandomFallbackTest.php b/core/tests/Drupal/Tests/Component/Utility/CryptRandomFallbackTest.php
deleted file mode 100644
index a9f68cbfa6d1ce0a4c2204a08c78b25c88c7654c..0000000000000000000000000000000000000000
--- a/core/tests/Drupal/Tests/Component/Utility/CryptRandomFallbackTest.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-namespace Drupal\Tests\Component\Utility;
-
-use Drupal\Component\Utility\Crypt;
-use PHPUnit\Framework\TestCase;
-
-/**
- * Tests random byte generation fallback exception situations.
- *
- * @group Utility
- *
- * @runTestsInSeparateProcesses
- *
- * @coversDefaultClass \Drupal\Component\Utility\Crypt
- */
-class CryptRandomFallbackTest extends TestCase {
-
-  protected static $functionCalled = 0;
-
-  /**
-   * Allows the test to confirm that the namespaced random_bytes() was called.
-   */
-  public static function functionCalled() {
-    static::$functionCalled++;
-  }
-
-  /**
-   * Tests random byte generation using the fallback generator.
-   *
-   * If the call to random_bytes() throws an exception, Crypt::random_bytes()
-   * should still return a useful string of random bytes.
-   *
-   * @covers ::randomBytes
-   *
-   * @see \Drupal\Tests\Component\Utility\CryptTest::testRandomBytes()
-   */
-  public function testRandomBytesFallback() {
-    // This loop is a copy of
-    // \Drupal\Tests\Component\Utility\CryptTest::testRandomBytes().
-    for ($i = 0; $i < 10; $i++) {
-      $count = rand(10, 10000);
-      // Check that different values are being generated.
-      $this->assertNotEquals(Crypt::randomBytes($count), Crypt::randomBytes($count));
-      // Check the length.
-      $this->assertEquals($count, strlen(Crypt::randomBytes($count)));
-    }
-    $this->assertEquals(30, static::$functionCalled, 'The namespaced function was called the expected number of times.');
-  }
-
-}
-
-namespace Drupal\Component\Utility;
-
-use Drupal\Tests\Component\Utility\CryptRandomFallbackTest;
-
-/**
- * Defines a function in same namespace as Drupal\Component\Utility\Crypt.
- *
- * Forces throwing an exception in this test environment because the function
- * in the namespace is used in preference to the global function.
- *
- * @param int $count
- *   Matches the global function definition.
- *
- * @throws \Exception
- */
-function random_bytes($count) {
-  CryptRandomFallbackTest::functionCalled();
-  throw new \Exception($count);
-}
diff --git a/core/tests/Drupal/Tests/ComposerIntegrationTest.php b/core/tests/Drupal/Tests/ComposerIntegrationTest.php
index 98bc5658bc86ee7e7b022273e49211fdc87f91da..4bed30bcc9284e04250412068fb23c9b4bd67b11 100644
--- a/core/tests/Drupal/Tests/ComposerIntegrationTest.php
+++ b/core/tests/Drupal/Tests/ComposerIntegrationTest.php
@@ -23,14 +23,11 @@ protected function getErrorMessages() {
       JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
       JSON_ERROR_SYNTAX => 'Syntax error',
       JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded',
+      JSON_ERROR_RECURSION => 'One or more recursive references in the value to be encoded',
+      JSON_ERROR_INF_OR_NAN => 'One or more NAN or INF values in the value to be encoded',
+      JSON_ERROR_UNSUPPORTED_TYPE => 'A value of a type that cannot be encoded was given',
     ];
 
-    if (version_compare(phpversion(), '5.5.0', '>=')) {
-      $messages[JSON_ERROR_RECURSION] = 'One or more recursive references in the value to be encoded';
-      $messages[JSON_ERROR_INF_OR_NAN] = 'One or more NAN or INF values in the value to be encoded';
-      $messages[JSON_ERROR_UNSUPPORTED_TYPE] = 'A value of a type that cannot be encoded was given';
-    }
-
     return $messages;
   }
 
diff --git a/core/tests/Drupal/Tests/Core/TypedData/TypedDataTest.php b/core/tests/Drupal/Tests/Core/TypedData/TypedDataTest.php
deleted file mode 100644
index 6a9da9f1de2efb607147da1aaccd9c2cb3184793..0000000000000000000000000000000000000000
--- a/core/tests/Drupal/Tests/Core/TypedData/TypedDataTest.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-
-namespace Drupal\Tests\Core\TypedData;
-
-use Drupal\Core\TypedData\DataDefinitionInterface;
-use Drupal\Core\TypedData\TypedData;
-use Drupal\Core\TypedData\TypedDataManagerInterface;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\Core\TypedData\TypedData
- *
- * @group TypedData
- */
-class TypedDataTest extends UnitTestCase {
-
-  /**
-   * @covers ::__sleep
-   */
-  public function testSleep() {
-    $data_definition = $this->getMock(DataDefinitionInterface::class);
-    /** @var \Drupal\Core\TypedData\TypedData $typed_data */
-    $typed_data = $this->getMockForAbstractClass(TypedData::class, [$data_definition]);
-    $string_translation = $this->getStringTranslationStub();
-    $typed_data->setStringTranslation($string_translation);
-    $typed_data_manager = $this->getMock(TypedDataManagerInterface::class);
-    $typed_data->setTypedDataManager($typed_data_manager);
-    $serialized_typed_data = serialize($typed_data);
-    $this->assertNotContains(get_class($string_translation), $serialized_typed_data);
-    $this->assertNotContains(get_class($typed_data_manager), $serialized_typed_data);
-  }
-
-}
diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php
index 82a1830547b3d8a9724f3f25787236d03169107d..3dad6142e25126bba3f3a2033498c9e126c70a77 100644
--- a/core/tests/bootstrap.php
+++ b/core/tests/bootstrap.php
@@ -182,9 +182,9 @@ function drupal_phpunit_populate_class_loader() {
 date_default_timezone_set('Australia/Sydney');
 
 // Runtime assertions. PHPUnit follows the php.ini assert.active setting for
-// runtime assertions. By default this setting is on. Here we make a call to
-// make PHP 5 and 7 handle assertion failures the same way, but this call does
-// not turn runtime assertions on if they weren't on already.
+// runtime assertions. By default this setting is on. Ensure exceptions are
+// thrown if an assert fails, but this call does not turn runtime assertions on
+// if they weren't on already.
 Handle::register();
 
 // PHPUnit 4 to PHPUnit 6 bridge. Tests written for PHPUnit 4 need to work on