diff --git a/.gitignore b/.gitignore
index 71cf213fbfaf..988be09b1948 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,7 +61,7 @@ writable/uploads/*
 !writable/uploads/index.html
 
 writable/debugbar/*
-!writable/debugbar/.gitkeep
+!writable/debugbar/index.html
 
 writable/**/*.db
 writable/**/*.sqlite
@@ -125,7 +125,5 @@ nb-configuration.xml
 
 /results/
 /phpunit*.xml
-/.phpunit.*.cache
-/.phpunit.cache
 
 /.php-cs-fixer.php
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 807cd0078e7d..b47b4d6480c9 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -21,7 +21,6 @@
     ->files()
     ->in([
         __DIR__ . '/system',
-        __DIR__ . '/tests',
         __DIR__ . '/utils',
     ])
     ->exclude([
@@ -30,14 +29,12 @@
         'Validation/Views',
     ])
     ->notPath([
-        '_support/View/Cells/multiplier.php',
-        '_support/View/Cells/colors.php',
-        '_support/View/Cells/addition.php',
     ])
     ->notName('#Foobar.php$#')
     ->append([
         __FILE__,
         __DIR__ . '/.php-cs-fixer.no-header.php',
+        __DIR__ . '/.php-cs-fixer.tests.php',
         __DIR__ . '/.php-cs-fixer.user-guide.php',
         __DIR__ . '/rector.php',
         __DIR__ . '/spark',
diff --git a/.php-cs-fixer.tests.php b/.php-cs-fixer.tests.php
new file mode 100644
index 000000000000..c6b13a135a7c
--- /dev/null
+++ b/.php-cs-fixer.tests.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of CodeIgniter 4 framework.
+ *
+ * (c) CodeIgniter Foundation <admin@codeigniter.com>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+use CodeIgniter\CodingStandard\CodeIgniter4;
+use Nexus\CsConfig\Factory;
+use Nexus\CsConfig\Fixer\Comment\NoCodeSeparatorCommentFixer;
+use Nexus\CsConfig\FixerGenerator;
+use PhpCsFixer\Finder;
+
+$finder = Finder::create()
+    ->files()
+    ->in([
+        __DIR__ . '/tests',
+    ])
+    ->exclude([
+    ])
+    ->notPath([
+        '_support/View/Cells/multiplier.php',
+        '_support/View/Cells/colors.php',
+        '_support/View/Cells/addition.php',
+    ])
+    ->notName('#Foobar.php$#')
+    ->append([
+    ]);
+
+$overrides = [
+    'void_return' => true,
+];
+
+$options = [
+    'cacheFile' => 'build/.php-cs-fixer.tests.cache',
+    'finder'    => $finder,
+];
+
+$config = Factory::create(new CodeIgniter4(), $overrides, $options)->forLibrary(
+    'CodeIgniter 4 framework',
+    'CodeIgniter Foundation',
+    'admin@codeigniter.com'
+);
+
+$config
+    ->registerCustomFixers(FixerGenerator::create('vendor/nexusphp/cs-config/src/Fixer', 'Nexus\\CsConfig\\Fixer'))
+    ->setRules(array_merge($config->getRules(), [
+        NoCodeSeparatorCommentFixer::name() => true,
+    ]));
+
+return $config;
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 60950f4cf0f0..5148b0faad05 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,34 @@
 # Changelog
 
+## [v4.5.1](https://github.com/codeigniter4/CodeIgniter4/tree/v4.5.1) (2024-04-14)
+[Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.5.0...v4.5.1)
+
+### Fixed Bugs
+
+* fix: TypeError in form() by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8736
+* fix: [DebugBar] TypeError in Toolbar by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8727
+* fix: TypeError when Time is passed to Model by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8738
+* docs: added Config\Feature::$oldFilterOrder to app/Config/Feature.php… by @mullernato in https://github.com/codeigniter4/CodeIgniter4/pull/8749
+* fix: Factories::get() cannot get defined classes by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8744
+* fix: `BaseConnection::escape()` does not accept Stringable by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8756
+* fix: [CURLRequest] `getHeaderLine('Content-Type')` causes InvalidArgumentException by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8760
+* fix: [CURLRequest] construct param $config is not used by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8761
+* fix: [FileLocator] Cannot declare class XXX, because the name is already in use by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8745
+* fix: [DebugBar] Toolbar display may be broken by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8772
+* fix: Cannot declare class CodeIgniter\Config\Services, because the name is already in use by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8776
+* docs: fix Postgre DSN sample by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8774
+
+### Refactoring
+
+* test: refactor Config/Registrar.php by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8731
+* test: add return void by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8746
+* refactor: system/CLI/BaseCommand.php by @mcsaygili in https://github.com/codeigniter4/CodeIgniter4/pull/8741
+* refactor: system/View/Plugins.php by @mcsaygili in https://github.com/codeigniter4/CodeIgniter4/pull/8742
+* refactor: fix method name `ValidationErrors` in View\Plugins by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8758
+* refactor: system/Debug/Toolbar/Collectors/Routes.php by @mcsaygili in https://github.com/codeigniter4/CodeIgniter4/pull/8751
+* refactor: improve error message in BaseExceptionHandler by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8766
+* refactor: FabricatorModel by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8770
+
 ## [v4.5.0](https://github.com/codeigniter4/CodeIgniter4/tree/v4.5.0) (2024-04-07)
 [Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.4.8...v4.5.0)
 
diff --git a/admin/RELEASE.md b/admin/RELEASE.md
index 37173c4e97b0..8c5f463355fb 100644
--- a/admin/RELEASE.md
+++ b/admin/RELEASE.md
@@ -2,7 +2,7 @@
 
 > Documentation guide based on the releases of `4.0.5` and `4.1.0` on January 31, 2021.
 >
-> Updated for `4.4.3` on October 27, 2023.
+> Updated for `4.5.0` on April 7, 2024.
 >
 > -MGatner, kenjis
 
@@ -25,10 +25,10 @@ git push upstream HEAD
 If you release a new minor version.
 
 * [ ] Create PR to merge `4.x` into `develop` and merge it
-* [ ] Rename the current minor version (e.g., `4.4`) in Setting > Branches >
-  "Branch protection rules" to the next minor version. E.g. `4.4` → `4.5`
+* [ ] Rename the current minor version (e.g., `4.5`) in Setting > Branches >
+  "Branch protection rules" to the next minor version. E.g. `4.5` → `4.6`
 * [ ] Delete the merged `4.x` branch (This closes all PRs to the branch)
-* [ ] Do the regular release process. Go to the next "Changelog" section
+* Do the regular release process. Go to the next "Changelog" section
 
 ## Changelog
 
@@ -91,10 +91,11 @@ Work off direct clones of the repos so the release branches persist for a time.
 * [ ] Update **user_guide_src/source/changelogs/v4.x.x.rst**
   * Remove the section titles that have no items
 * [ ] Update **user_guide_src/source/installation/upgrade_{ver}.rst**
-  * fill in the "All Changes" section, and add it to **upgrading.rst**
-    * git diff --name-status origin/master -- . ':!system'
-  * Remove the section titles that have no items
-  * [Minor version only] Update the "from" version in the title. E.g., `from 4.3.x` → `from 4.3.8`
+  * [ ] fill in the "All Changes" section, and add it to **upgrading.rst**
+    * git diff --name-status origin/master -- . ':!system' ':!tests' ':!user_guide_src'
+    * Note: `tests/` is not used for distribution repos. See `admin/starter/tests/`
+  * [ ] Remove the section titles that have no items
+  * [ ] [Minor version only] Update the "from" version in the title. E.g., `from 4.3.x` → `from 4.3.8`
 * [ ] Run `php admin/prepare-release.php 4.x.x` and push to origin
   * The above command does the following:
     * Create a new branch `release-4.x.x`
diff --git a/admin/create-new-changelog.php b/admin/create-new-changelog.php
index ff371345d166..ff333f42693f 100644
--- a/admin/create-new-changelog.php
+++ b/admin/create-new-changelog.php
@@ -29,7 +29,9 @@ function replace_file_content(string $path, string $pattern, string $replace): v
 $isMinorUpdate       = ($minorCurrent !== $minor);
 
 // Creates a branch for release.
-system('git switch develop');
+if (! $isMinorUpdate) {
+    system('git switch develop');
+}
 system('git switch -c docs-changelog-' . $version);
 system('git switch docs-changelog-' . $version);
 
diff --git a/admin/css/debug-toolbar/README.md b/admin/css/debug-toolbar/README.md
new file mode 100644
index 000000000000..2c70e8147eae
--- /dev/null
+++ b/admin/css/debug-toolbar/README.md
@@ -0,0 +1 @@
+See [contributing/css.md](../../../contributing/css.md).
diff --git a/admin/css/debug-toolbar/toolbar.scss b/admin/css/debug-toolbar/toolbar.scss
index e129a4b1c5b6..97a92690b937 100644
--- a/admin/css/debug-toolbar/toolbar.scss
+++ b/admin/css/debug-toolbar/toolbar.scss
@@ -28,8 +28,8 @@
     width: 36px;
 
     // Spacing
-    margin: 0px;
-    padding: 0px;
+    margin: 0;
+    padding: 0;
 
     // Content
     clear: both;
@@ -85,6 +85,8 @@
         display: flex;
         font-weight: normal;
         margin: 0 0 0 auto;
+        padding: 0;
+        font-family: $base-font;
 
         svg {
             width: 16px;
diff --git a/admin/framework/.gitignore b/admin/framework/.gitignore
index 696da9cb0a91..8071bd3d07f8 100644
--- a/admin/framework/.gitignore
+++ b/admin/framework/.gitignore
@@ -124,5 +124,3 @@ nb-configuration.xml
 
 /results/
 /phpunit*.xml
-/.phpunit.*.cache
-
diff --git a/admin/framework/phpunit.xml.dist b/admin/framework/phpunit.xml.dist
index 0235b8a739c1..dea940878617 100644
--- a/admin/framework/phpunit.xml.dist
+++ b/admin/framework/phpunit.xml.dist
@@ -1,48 +1,63 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="system/Test/bootstrap.php" backupGlobals="false" colors="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache">
-  <coverage includeUncoveredFiles="true">
-    <report>
-      <clover outputFile="build/logs/clover.xml"/>
-      <html outputDirectory="build/logs/html"/>
-      <php outputFile="build/logs/coverage.serialized"/>
-      <text outputFile="php://stdout" showUncoveredFiles="false"/>
-    </report>
-  </coverage>
-  <testsuites>
-    <testsuite name="App">
-      <directory>./tests</directory>
-    </testsuite>
-  </testsuites>
-  <logging>
-    <testdoxHtml outputFile="build/logs/testdox.html"/>
-    <testdoxText outputFile="build/logs/testdox.txt"/>
-    <junit outputFile="build/logs/logfile.xml"/>
-  </logging>
-  <php>
-    <server name="app.baseURL" value="http://example.com/"/>
-    <!-- Directory containing phpunit.xml -->
-    <const name="HOMEPATH" value="./"/>
-    <!-- Directory containing the Paths config file -->
-    <const name="CONFIGPATH" value="./app/Config/"/>
-    <!-- Directory containing the front controller (index.php) -->
-    <const name="PUBLICPATH" value="./public/"/>
-    <!-- Database configuration -->
-    <!-- Uncomment to provide your own database for testing
-		<env name="database.tests.hostname" value="localhost"/>
-		<env name="database.tests.database" value="tests"/>
-		<env name="database.tests.username" value="tests_user"/>
-		<env name="database.tests.password" value=""/>
-		<env name="database.tests.DBDriver" value="MySQLi"/>
-		<env name="database.tests.DBPrefix" value="tests_"/>
-		-->
-  </php>
-  <source>
-    <include>
-      <directory suffix=".php">./app</directory>
-    </include>
-    <exclude>
-      <directory suffix=".php">./app/Views</directory>
-      <file>./app/Config/Routes.php</file>
-    </exclude>
-  </source>
+<phpunit
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
+    bootstrap="system/Test/bootstrap.php"
+    backupGlobals="false"
+    beStrictAboutOutputDuringTests="true"
+    colors="true"
+    columns="max"
+    failOnRisky="true"
+    failOnWarning="true"
+    cacheDirectory="build/.phpunit.cache">
+    <coverage
+        includeUncoveredFiles="true"
+        pathCoverage="false"
+        ignoreDeprecatedCodeUnits="true"
+        disableCodeCoverageIgnore="true">
+        <report>
+            <clover outputFile="build/logs/clover.xml"/>
+            <html outputDirectory="build/logs/html"/>
+            <php outputFile="build/logs/coverage.serialized"/>
+            <text outputFile="php://stdout" showUncoveredFiles="false"/>
+        </report>
+    </coverage>
+    <testsuites>
+        <testsuite name="App">
+            <directory>./tests</directory>
+        </testsuite>
+    </testsuites>
+    <logging>
+        <testdoxHtml outputFile="build/logs/testdox.html"/>
+        <testdoxText outputFile="build/logs/testdox.txt"/>
+        <junit outputFile="build/logs/logfile.xml"/>
+    </logging>
+    <source>
+        <include>
+            <directory suffix=".php">./app</directory>
+        </include>
+        <exclude>
+            <directory suffix=".php">./app/Views</directory>
+            <file>./app/Config/Routes.php</file>
+        </exclude>
+    </source>
+    <php>
+        <server name="app.baseURL" value="http://example.com/"/>
+        <server name="CODEIGNITER_SCREAM_DEPRECATIONS" value="0"/>
+        <!-- Directory containing phpunit.xml -->
+        <const name="HOMEPATH" value="./"/>
+        <!-- Directory containing the Paths config file -->
+        <const name="CONFIGPATH" value="./app/Config/"/>
+        <!-- Directory containing the front controller (index.php) -->
+        <const name="PUBLICPATH" value="./public/"/>
+        <!-- Database configuration -->
+        <!-- Uncomment to provide your own database for testing
+            <env name="database.tests.hostname" value="localhost"/>
+            <env name="database.tests.database" value="tests"/>
+            <env name="database.tests.username" value="tests_user"/>
+            <env name="database.tests.password" value=""/>
+            <env name="database.tests.DBDriver" value="MySQLi"/>
+            <env name="database.tests.DBPrefix" value="tests_"/>
+            -->
+    </php>
 </phpunit>
diff --git a/admin/starter/.gitignore b/admin/starter/.gitignore
index 696da9cb0a91..8071bd3d07f8 100644
--- a/admin/starter/.gitignore
+++ b/admin/starter/.gitignore
@@ -124,5 +124,3 @@ nb-configuration.xml
 
 /results/
 /phpunit*.xml
-/.phpunit.*.cache
-
diff --git a/admin/starter/phpunit.xml.dist b/admin/starter/phpunit.xml.dist
index 7cd6d3af600a..dea940878617 100644
--- a/admin/starter/phpunit.xml.dist
+++ b/admin/starter/phpunit.xml.dist
@@ -1,48 +1,63 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/codeigniter4/framework/system/Test/bootstrap.php" backupGlobals="false" colors="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache">
-  <coverage includeUncoveredFiles="true">
-    <report>
-      <clover outputFile="build/logs/clover.xml"/>
-      <html outputDirectory="build/logs/html"/>
-      <php outputFile="build/logs/coverage.serialized"/>
-      <text outputFile="php://stdout" showUncoveredFiles="false"/>
-    </report>
-  </coverage>
-  <testsuites>
-    <testsuite name="App">
-      <directory>./tests</directory>
-    </testsuite>
-  </testsuites>
-  <logging>
-    <testdoxHtml outputFile="build/logs/testdox.html"/>
-    <testdoxText outputFile="build/logs/testdox.txt"/>
-    <junit outputFile="build/logs/logfile.xml"/>
-  </logging>
-  <php>
-    <server name="app.baseURL" value="http://example.com/"/>
-    <!-- Directory containing phpunit.xml -->
-    <const name="HOMEPATH" value="./"/>
-    <!-- Directory containing the Paths config file -->
-    <const name="CONFIGPATH" value="./app/Config/"/>
-    <!-- Directory containing the front controller (index.php) -->
-    <const name="PUBLICPATH" value="./public/"/>
-    <!-- Database configuration -->
-    <!-- Uncomment to provide your own database for testing
-        <env name="database.tests.hostname" value="localhost"/>
-        <env name="database.tests.database" value="tests"/>
-        <env name="database.tests.username" value="tests_user"/>
-        <env name="database.tests.password" value=""/>
-        <env name="database.tests.DBDriver" value="MySQLi"/>
-        <env name="database.tests.DBPrefix" value="tests_"/>
-        -->
-  </php>
-  <source>
-    <include>
-      <directory suffix=".php">./app</directory>
-    </include>
-    <exclude>
-      <directory suffix=".php">./app/Views</directory>
-      <file>./app/Config/Routes.php</file>
-    </exclude>
-  </source>
+<phpunit
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
+    bootstrap="system/Test/bootstrap.php"
+    backupGlobals="false"
+    beStrictAboutOutputDuringTests="true"
+    colors="true"
+    columns="max"
+    failOnRisky="true"
+    failOnWarning="true"
+    cacheDirectory="build/.phpunit.cache">
+    <coverage
+        includeUncoveredFiles="true"
+        pathCoverage="false"
+        ignoreDeprecatedCodeUnits="true"
+        disableCodeCoverageIgnore="true">
+        <report>
+            <clover outputFile="build/logs/clover.xml"/>
+            <html outputDirectory="build/logs/html"/>
+            <php outputFile="build/logs/coverage.serialized"/>
+            <text outputFile="php://stdout" showUncoveredFiles="false"/>
+        </report>
+    </coverage>
+    <testsuites>
+        <testsuite name="App">
+            <directory>./tests</directory>
+        </testsuite>
+    </testsuites>
+    <logging>
+        <testdoxHtml outputFile="build/logs/testdox.html"/>
+        <testdoxText outputFile="build/logs/testdox.txt"/>
+        <junit outputFile="build/logs/logfile.xml"/>
+    </logging>
+    <source>
+        <include>
+            <directory suffix=".php">./app</directory>
+        </include>
+        <exclude>
+            <directory suffix=".php">./app/Views</directory>
+            <file>./app/Config/Routes.php</file>
+        </exclude>
+    </source>
+    <php>
+        <server name="app.baseURL" value="http://example.com/"/>
+        <server name="CODEIGNITER_SCREAM_DEPRECATIONS" value="0"/>
+        <!-- Directory containing phpunit.xml -->
+        <const name="HOMEPATH" value="./"/>
+        <!-- Directory containing the Paths config file -->
+        <const name="CONFIGPATH" value="./app/Config/"/>
+        <!-- Directory containing the front controller (index.php) -->
+        <const name="PUBLICPATH" value="./public/"/>
+        <!-- Database configuration -->
+        <!-- Uncomment to provide your own database for testing
+            <env name="database.tests.hostname" value="localhost"/>
+            <env name="database.tests.database" value="tests"/>
+            <env name="database.tests.username" value="tests_user"/>
+            <env name="database.tests.password" value=""/>
+            <env name="database.tests.DBDriver" value="MySQLi"/>
+            <env name="database.tests.DBPrefix" value="tests_"/>
+            -->
+    </php>
 </phpunit>
diff --git a/admin/starter/tests/.htaccess b/admin/starter/tests/.htaccess
new file mode 100755
index 000000000000..3462048add78
--- /dev/null
+++ b/admin/starter/tests/.htaccess
@@ -0,0 +1,6 @@
+<IfModule authz_core_module>
+	Require all denied
+</IfModule>
+<IfModule !authz_core_module>
+	Deny from all
+</IfModule>
diff --git a/admin/starter/tests/index.html b/admin/starter/tests/index.html
new file mode 100755
index 000000000000..b702fbc3967b
--- /dev/null
+++ b/admin/starter/tests/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
diff --git a/composer.json b/composer.json
index 9c17f59ded32..bed54690aa96 100644
--- a/composer.json
+++ b/composer.json
@@ -101,12 +101,14 @@
             "Composer\\Config::disableProcessTimeout",
             "php-cs-fixer fix --ansi --verbose --dry-run --diff --config=.php-cs-fixer.user-guide.php",
             "php-cs-fixer fix --ansi --verbose --dry-run --diff --config=.php-cs-fixer.no-header.php",
+            "php-cs-fixer fix --ansi --verbose --dry-run --diff --config=.php-cs-fixer.tests.php",
             "php-cs-fixer fix --ansi --verbose --dry-run --diff"
         ],
         "cs-fix": [
             "Composer\\Config::disableProcessTimeout",
             "php-cs-fixer fix --ansi --verbose --diff --config=.php-cs-fixer.user-guide.php",
             "php-cs-fixer fix --ansi --verbose --diff --config=.php-cs-fixer.no-header.php",
+            "php-cs-fixer fix --ansi --verbose --diff --config=.php-cs-fixer.tests.php",
             "php-cs-fixer fix --ansi --verbose --diff"
         ],
         "metrics": "tools/phpmetrics/vendor/bin/phpmetrics --config=phpmetrics.json",
diff --git a/contributing/css.md b/contributing/css.md
index 267d4f7a5609..4de86e069973 100644
--- a/contributing/css.md
+++ b/contributing/css.md
@@ -10,7 +10,7 @@ Open your terminal, and navigate to CodeIgniter's root folder. To
 generate the CSS file, use the following command:
 
 ```console
-sass --no-source-map admin/css/debug-toolbar/toolbar.scss system/Debug/Toolbar/Views/toolbar.css`
+sass --no-source-map admin/css/debug-toolbar/toolbar.scss system/Debug/Toolbar/Views/toolbar.css
 ```
 
 Details:
diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml
index b93122ac193f..546630d3f446 100644
--- a/phpdoc.dist.xml
+++ b/phpdoc.dist.xml
@@ -10,7 +10,7 @@
         <output>api/build/</output>
         <cache>api/cache/</cache>
     </paths>
-    <version number="4.5.0">
+    <version number="4.5.1">
         <api format="php">
             <source dsn=".">
                 <path>system</path>
diff --git a/phpstan-baseline.php b/phpstan-baseline.php
index ffe358b48943..cfee07815e8a 100644
--- a/phpstan-baseline.php
+++ b/phpstan-baseline.php
@@ -261,26 +261,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/system/BaseModel.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
-	'count' => 2,
-	'path' => __DIR__ . '/system/CLI/BaseCommand.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\CLI\\\\BaseCommand\\:\\:__get\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/CLI/BaseCommand.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\CLI\\\\BaseCommand\\:\\:call\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/CLI/BaseCommand.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\CLI\\\\BaseCommand\\:\\:getPad\\(\\) has parameter \\$array with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/CLI/BaseCommand.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Accessing offset \'ANSICON\' directly on \\$_SERVER is discouraged\\.$#',
 	'count' => 1,
@@ -4141,11 +4121,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/system/Database/Seeder.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/Debug/BaseExceptionHandler.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Debug\\\\BaseExceptionHandler\\:\\:collectVars\\(\\) return type has no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -4466,11 +4441,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Logs.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\\\Collectors\\\\Routes\\:\\:display\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Routes.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\\\Collectors\\\\Timers\\:\\:formatTimelineData\\(\\) return type has no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -5356,16 +5326,6 @@
 	'count' => 10,
 	'path' => __DIR__ . '/system/HTTP/CURLRequest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Constructor of class CodeIgniter\\\\HTTP\\\\CURLRequest has an unused parameter \\$config\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/HTTP/CURLRequest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:__construct\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/HTTP/CURLRequest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:applyBody\\(\\) has parameter \\$curlOptions with no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -7431,11 +7391,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/system/Model.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Property CodeIgniter\\\\Model\\:\\:\\$tempData type has no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/Model.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Return type \\(array\\|bool\\|float\\|int\\|object\\|string\\|null\\) of method CodeIgniter\\\\Model\\:\\:__call\\(\\) should be covariant with return type \\(\\$this\\(CodeIgniter\\\\BaseModel\\)\\|null\\) of method CodeIgniter\\\\BaseModel\\:\\:__call\\(\\)$#',
 	'count' => 1,
@@ -8646,16 +8601,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/system/Test/Fabricator.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Test\\\\Interfaces\\\\FabricatorModel\\:\\:find\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/Test/Interfaces/FabricatorModel.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Test\\\\Interfaces\\\\FabricatorModel\\:\\:insert\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/Test/Interfaces/FabricatorModel.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Property CodeIgniter\\\\Test\\\\Mock\\\\MockBuilder\\:\\:\\$supportedIgnoreStatements type has no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -9756,36 +9701,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/system/View/Parser.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\View\\\\Plugins\\:\\:ValidationErrors\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/View/Plugins.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\View\\\\Plugins\\:\\:lang\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/View/Plugins.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\View\\\\Plugins\\:\\:mailto\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/View/Plugins.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\View\\\\Plugins\\:\\:route\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/View/Plugins.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\View\\\\Plugins\\:\\:safeMailto\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/View/Plugins.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\View\\\\Plugins\\:\\:siteURL\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/system/View/Plugins.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\View\\\\RendererInterface\\:\\:render\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -10046,26 +9961,6 @@
 	'count' => 2,
 	'path' => __DIR__ . '/tests/_support/Config/Filters.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Config/Registrar.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Tests\\\\Support\\\\Config\\\\Registrar\\:\\:Database\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Config/Registrar.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Tests\\\\Support\\\\Config\\\\Registrar\\:\\:Publisher\\(\\) return type has no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Config/Registrar.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Property Tests\\\\Support\\\\Config\\\\Registrar\\:\\:\\$dbConfig type has no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Config/Registrar.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Variable \\$routes might not be defined\\.$#',
 	'count' => 5,
@@ -10481,11 +10376,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/_support/Models/EventModel.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method Tests\\\\Support\\\\Models\\\\FabricatorModel\\:\\:fake\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Models/FabricatorModel.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Property Tests\\\\Support\\\\Models\\\\JobModel\\:\\:\\$description has no type specified\\.$#',
 	'count' => 1,
@@ -10511,26 +10401,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/_support/Models/UserModel.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method Tests\\\\Support\\\\Services\\\\Translation\\\\Nested\\\\TranslationFour\\:\\:list\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Services/Translation/TranslationNested/TranslationFour.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Tests\\\\Support\\\\Services\\\\Translation\\\\TranslationOne\\:\\:list\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Services/Translation/TranslationOne.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Tests\\\\Support\\\\Services\\\\Translation\\\\TranslationThree\\:\\:list\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Services/Translation/TranslationThree.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Tests\\\\Support\\\\Services\\\\Translation\\\\TranslationTwo\\:\\:list\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/_support/Services/Translation/TranslationTwo.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Property Tests\\\\Support\\\\SomeEntity\\:\\:\\$attributes type has no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -11086,11 +10956,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Autoloader/FileLocatorCachedTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Autoloader\\\\FileLocatorCachedTest\\:\\:testDeleteCache\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Autoloader/FileLocatorCachedTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Assigning 3 directly on offset \'argc\' of \\$_SERVER is discouraged\\.$#',
 	'count' => 1,
@@ -11176,26 +11041,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\FactoriesCacheFileVarExportHandlerTest\\:\\:testDelete\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\FactoriesCacheFileVarExportHandlerTest\\:\\:testInstantiate\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\FactoriesCacheFileVarExportHandlerTest\\:\\:testLoad\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\FactoriesCacheFileVarExportHandlerTest\\:\\:testSave\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\BaseHandlerTest\\:\\:provideValidateKeyInvalidType\\(\\) return type has no value type specified in iterable type iterable\\.$#',
 	'count' => 1,
@@ -11286,36 +11131,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Cache/ResponseCacheTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\ResponseCacheTest\\:\\:testCachePageCLIRequest\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/ResponseCacheTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\ResponseCacheTest\\:\\:testCachePageIncomingRequest\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/ResponseCacheTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\ResponseCacheTest\\:\\:testCachePageIncomingRequestWithCacheQueryString\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/ResponseCacheTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\ResponseCacheTest\\:\\:testCachePageIncomingRequestWithHttpMethods\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/ResponseCacheTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\ResponseCacheTest\\:\\:testInvalidCacheError\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/ResponseCacheTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Cache\\\\ResponseCacheTest\\:\\:testUnserializeError\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Cache/ResponseCacheTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Re\\-assigning arrays to \\$_GET directly is discouraged\\.$#',
 	'count' => 3,
@@ -11451,11 +11266,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/CodeIgniterTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\CodeIgniterTest\\:\\:testOutputBufferingControl\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/CodeIgniterTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\CodeIgniterTest\\:\\:testPageCacheWithCacheQueryString\\(\\) has parameter \\$cacheQueryStringValue with no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -11466,11 +11276,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/CodeIgniterTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\CodeIgniterTest\\:\\:testRegisterSameFilterTwiceWithDifferentArgument\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/CodeIgniterTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#2 \\$to of method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:add\\(\\) expects array\\|\\(Closure\\(mixed \\.\\.\\.\\)\\: \\(CodeIgniter\\\\HTTP\\\\ResponseInterface\\|string\\|void\\)\\)\\|string, Closure\\(mixed\\)\\: \\(CodeIgniter\\\\HTTP\\\\DownloadResponse\\|null\\) given\\.$#',
 	'count' => 1,
@@ -11571,16 +11376,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Commands/RoutesTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Commands\\\\RoutesTest\\:\\:testRoutesCommandHostHostname\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Commands/RoutesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Commands\\\\RoutesTest\\:\\:testRoutesCommandHostSubdomain\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Commands/RoutesTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#2 \\$mock of static method CodeIgniter\\\\Config\\\\BaseService\\:\\:injectMock\\(\\) expects object, null given\\.$#',
 	'count' => 4,
@@ -11611,16 +11406,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Commands/Utilities/ConfigCheckTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Commands\\\\Utilities\\\\ConfigCheckTest\\:\\:testGetKintD\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Commands/Utilities/ConfigCheckTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Commands\\\\Utilities\\\\ConfigCheckTest\\:\\:testGetVarDump\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Commands/Utilities/ConfigCheckTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Commands\\\\Utilities\\\\NamespacesTest\\:\\:getBuffer\\(\\) has no return type specified\\.$#',
 	'count' => 1,
@@ -11666,16 +11451,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Commands/Utilities/Routes/FilterFinderTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Commands\\\\Utilities\\\\Routes\\\\FilterFinderTest\\:\\:testFilterOrder\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Commands/Utilities/Routes/FilterFinderTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Commands\\\\Utilities\\\\Routes\\\\FilterFinderTest\\:\\:testFilterOrderWithOldFilterOrder\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Commands/Utilities/Routes/FilterFinderTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Property CodeIgniter\\\\Commands\\\\Utilities\\\\Routes\\\\FilterFinderTest\\:\\:\\$response \\(CodeIgniter\\\\HTTP\\\\Response\\) does not accept CodeIgniter\\\\HTTP\\\\ResponseInterface\\.$#',
 	'count' => 1,
@@ -11716,16 +11491,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/CommonFunctionsTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\CommonFunctionsTest\\:\\:disableHtml5\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/CommonFunctionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\CommonFunctionsTest\\:\\:enableHtml5\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/CommonFunctionsTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\CommonFunctionsTest\\:\\:provideCleanPathActuallyCleaningThePaths\\(\\) return type has no value type specified in iterable type iterable\\.$#',
 	'count' => 1,
@@ -11866,71 +11631,11 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testCanLoadSharedConfigWithDifferentAlias\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testCanLoadTwoCellsWithSameShortName\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testDefineAfterLoading\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testDefineAndLoad\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testDefineNonExistentClass\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testDefineSameAliasAndSameClassTwice\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testDefineSameAliasTwiceWithDifferentClasses\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testFullClassnameIgnoresPreferApp\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testGetComponentInstances\\(\\) has no return type specified\\.$#',
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testGetCreatesConfigInstanceAndFactoriesConfigReturnsIt\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testGetNonexistentClass\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testGetReturnsFactoriesConfigInstance\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testIsUpdated\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testIsUpdated\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -11946,11 +11651,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Config\\\\FactoriesTest\\:\\:testShortnameReturnsConfigInApp\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Config/FactoriesTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#1 \\$expected of method PHPUnit\\\\Framework\\\\Assert\\:\\:assertInstanceOf\\(\\) expects class\\-string\\<Config\\\\TestRegistrar\\>, string given\\.$#',
 	'count' => 1,
@@ -12276,31 +11976,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/DataConverter/DataConverterTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\DataConverter\\\\DataConverterTest\\:\\:testExtract\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/DataConverter/DataConverterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\DataConverter\\\\DataConverterTest\\:\\:testExtractWithClosure\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/DataConverter/DataConverterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\DataConverter\\\\DataConverterTest\\:\\:testExtractWithExtractMethod\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/DataConverter/DataConverterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\DataConverter\\\\DataConverterTest\\:\\:testReconstructObjectWithClosure\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/DataConverter/DataConverterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\DataConverter\\\\DataConverterTest\\:\\:testReconstructObjectWithReconstructMethod\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/DataConverter/DataConverterTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Access to an undefined property CodeIgniter\\\\Test\\\\Mock\\\\MockConnection\\:\\:\\$foobar\\.$#',
 	'count' => 1,
@@ -12466,11 +12141,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Database/Live/FabricatorLiveTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Database\\\\Live\\\\ForgeTest\\:\\:testAddColumnNull\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Database/Live/ForgeTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#1 \\$fields of method CodeIgniter\\\\Database\\\\Forge\\:\\:addField\\(\\) expects array\\<string, array\\|string\\>\\|string, array\\<int, string\\> given\\.$#',
 	'count' => 2,
@@ -12547,39 +12217,19 @@
 	'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Database\\\\Live\\\\MySQLi\\\\NumberNativeTest\\:\\:testDisableNumberNative\\(\\) has no return type specified\\.$#',
+	'message' => '#^Property CodeIgniter\\\\Database\\\\Live\\\\MySQLi\\\\NumberNativeTest\\:\\:\\$tests has no type specified\\.$#',
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Database\\\\Live\\\\MySQLi\\\\NumberNativeTest\\:\\:testEnableNumberNative\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
+	'message' => '#^Class stdClass referenced with incorrect case\\: stdclass\\.$#',
+	'count' => 9,
+	'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/RawSqlTest.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Database\\\\Live\\\\MySQLi\\\\NumberNativeTest\\:\\:testQueryDataAfterDisableNumberNative\\(\\) has no return type specified\\.$#',
+	'message' => '#^Call to an undefined method CodeIgniter\\\\Database\\\\BaseConnection\\:\\:getCursor\\(\\)\\.$#',
 	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Database\\\\Live\\\\MySQLi\\\\NumberNativeTest\\:\\:testQueryDataAfterEnableNumberNative\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Property CodeIgniter\\\\Database\\\\Live\\\\MySQLi\\\\NumberNativeTest\\:\\:\\$tests has no type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Class stdClass referenced with incorrect case\\: stdclass\\.$#',
-	'count' => 9,
-	'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/RawSqlTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Call to an undefined method CodeIgniter\\\\Database\\\\BaseConnection\\:\\:getCursor\\(\\)\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Database/Live/OCI8/CallStoredProcedureTest.php',
+	'path' => __DIR__ . '/tests/system/Database/Live/OCI8/CallStoredProcedureTest.php',
 ];
 $ignoreErrors[] = [
 	'message' => '#^Call to an undefined method CodeIgniter\\\\Database\\\\BaseConnection\\:\\:storedProcedure\\(\\)\\.$#',
@@ -12851,21 +12501,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Entity/EntityTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Entity\\\\EntityTest\\:\\:testNewGetterSetters\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Entity/EntityTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Entity\\\\EntityTest\\:\\:testSetArrayToPropertyNamedAttributes\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Entity/EntityTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Entity\\\\EntityTest\\:\\:testSetStringToPropertyNamedAttributes\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Entity/EntityTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method class@anonymous/tests/system/Entity/EntityTest\\.php\\:1078\\:\\:getBar\\(\\) has no return type specified\\.$#',
 	'count' => 1,
@@ -13081,21 +12716,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Filters/FiltersTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Filters\\\\FiltersTest\\:\\:testFilterWithArgumentsIsDefined\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Filters/FiltersTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Filters\\\\FiltersTest\\:\\:testFilterWithoutArgumentsIsDefined\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Filters/FiltersTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Filters\\\\FiltersTest\\:\\:testFiltersWithArguments\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Filters/FiltersTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Filters\\\\FiltersTest\\:\\:testProcessMethodProcessGlobalsWithExcept\\(\\) has parameter \\$except with no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -13221,56 +12841,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/CLIRequestTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Access to an undefined property CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:\\$curl_options\\.$#',
-	'count' => 39,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Assigning \'10\' directly on offset \'HTTP_CONTENT_LENGTH\' of \\$_SERVER is discouraged\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Assigning \'en\\-US\' directly on offset \'HTTP_ACCEPT_LANGUAGE\' of \\$_SERVER is discouraged\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Assigning \'gzip, deflate, br\' directly on offset \'HTTP_ACCEPT_ENCODING\' of \\$_SERVER is discouraged\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Assigning \'site1\\.com\' directly on offset \'HTTP_HOST\' of \\$_SERVER is discouraged\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Call to an undefined method CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:setOutput\\(\\)\\.$#',
-	'count' => 3,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequestDoNotShareOptionsTest\\:\\:getRequest\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequestDoNotShareOptionsTest\\:\\:getRequest\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequestDoNotShareOptionsTest\\:\\:testProxyuOption\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Access to an undefined property CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:\\$curl_options\\.$#',
-	'count' => 39,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Assigning \'10\' directly on offset \'HTTP_CONTENT_LENGTH\' of \\$_SERVER is discouraged\\.$#',
 	'count' => 1,
@@ -13291,26 +12861,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Call to an undefined method CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:setOutput\\(\\)\\.$#',
-	'count' => 4,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequestTest\\:\\:getRequest\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequestTest\\:\\:getRequest\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequestTest\\:\\:testProxyuOption\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/CURLRequestTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\HTTP\\\\ContentSecurityPolicyTest\\:\\:work\\(\\) has no return type specified\\.$#',
 	'count' => 1,
@@ -13331,16 +12881,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/Files/FileCollectionTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\Files\\\\FileCollectionTest\\:\\:testClientPathReturnsNullWhenFullPathIsNull\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/Files/FileCollectionTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\Files\\\\FileCollectionTest\\:\\:testClientPathReturnsValidFullPath\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/Files/FileCollectionTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Function CodeIgniter\\\\HTTP\\\\Files\\\\is_uploaded_file\\(\\) has no return type specified\\.$#',
 	'count' => 1,
@@ -13681,11 +13221,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/IncomingRequestTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\IncomingRequestTest\\:\\:testSetValidLocales\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/IncomingRequestTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Property Config\\\\App\\:\\:\\$proxyIPs \\(array\\<string, string\\>\\) does not accept array\\<int, string\\>\\.$#',
 	'count' => 1,
@@ -14011,101 +13546,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testDefault\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testDefaultEmpty\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testExtensionPHP\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testPathInfoSubfolder\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testPathInfoUnset\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testQueryString\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testQueryStringEmpty\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testQueryStringWithQueryString\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURI\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURIGetPath\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURINested\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURINginx\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURINginxRedirecting\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURINoIndex\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURIPathIsNeverRediscovered\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURIPathIsRelative\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURIStoresDetectedPath\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURISubfolder\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryDetectRoutePathTest\\:\\:testRequestURISuppressed\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Re\\-assigning arrays to \\$_GET directly is discouraged\\.$#',
 	'count' => 1,
@@ -14156,26 +13596,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryTest\\:\\:testCreateFromGlobals\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryTest\\:\\:testCreateFromGlobalsAllowedHost\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryTest\\:\\:testCreateFromStringWithIndexPage\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURIFactoryTest\\:\\:testCreateFromStringWithoutIndexPage\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURIFactoryTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Re\\-assigning arrays to \\$_GET directly is discouraged\\.$#',
 	'count' => 1,
@@ -14196,116 +13616,16 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testConstructor\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testConstructor\\(\\) has parameter \\$expectedSegments with no value type specified in iterable type array\\.$#',
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testConstructorEmptyScheme\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testConstructorForceGlobalSecureRequests\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testConstructorHost\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testConstructorInvalidBaseURL\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testConstructorScheme\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testGetBaseURL\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testGetRoutePath\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testGetSegmentOutOfRange\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testGetSegmentZero\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testGetSegments\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testGetTotalSegments\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetBaseURI\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetPath\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetPath\\(\\) has parameter \\$expectedSegments with no value type specified in iterable type array\\.$#',
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetSegment\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetSegmentOutOfRange\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetSegmentSilentOutOfRange\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetSegmentSubfolder\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetSegmentZero\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\SiteURITest\\:\\:testSetURI\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/SiteURITest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#4 \\$scheme of class CodeIgniter\\\\HTTP\\\\SiteURI constructor expects \'http\'\\|\'https\'\\|null, \'\' given\\.$#',
 	'count' => 1,
@@ -14381,21 +13701,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/HTTP/URITest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\URITest\\:\\:testWithScheme\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/URITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\URITest\\:\\:testWithSchemeSetsEmpty\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/URITest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HTTP\\\\URITest\\:\\:testWithSchemeSetsHttps\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HTTP/URITest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Accessing offset \'HTTP_REFERER\' directly on \\$_SERVER is discouraged\\.$#',
 	'count' => 1,
@@ -14571,31 +13876,11 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Helpers/FilesystemHelperTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Helpers\\\\FormHelperTest\\:\\:disableHtml5\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Helpers/FormHelperTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Helpers\\\\FormHelperTest\\:\\:enableHtml5\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Helpers/FormHelperTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#2 \\$value of function form_hidden expects array\\|string, null given\\.$#',
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Helpers/FormHelperTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Helpers\\\\HTMLHelperTest\\:\\:disableHtml5\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Helpers/HTMLHelperTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Helpers\\\\HTMLHelperTest\\:\\:enableHtml5\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Helpers/HTMLHelperTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Property CodeIgniter\\\\Helpers\\\\HTMLHelperTest\\:\\:\\$tracks type has no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -14956,31 +14241,6 @@
 	'count' => 3,
 	'path' => __DIR__ . '/tests/system/Honeypot/HoneypotTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HotReloader\\\\DirectoryHasherTest\\:\\:testHash\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HotReloader/DirectoryHasherTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HotReloader\\\\DirectoryHasherTest\\:\\:testHashApp\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HotReloader/DirectoryHasherTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HotReloader\\\\DirectoryHasherTest\\:\\:testHashDirectoryInvalid\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HotReloader/DirectoryHasherTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HotReloader\\\\DirectoryHasherTest\\:\\:testRepeatableHashes\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HotReloader/DirectoryHasherTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\HotReloader\\\\DirectoryHasherTest\\:\\:testUniqueHashes\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/HotReloader/DirectoryHasherTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Access to an undefined property CodeIgniter\\\\I18n\\\\TimeDifference\\:\\:\\$nonsense\\.$#',
 	'count' => 2,
@@ -15041,11 +14301,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/I18n/TimeLegacyTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\I18n\\\\TimeLegacyTest\\:\\:testUnserializeTimeObject\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/I18n/TimeLegacyTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Access to an undefined property CodeIgniter\\\\I18n\\\\Time\\:\\:\\$timezoneName\\.$#',
 	'count' => 1,
@@ -15061,11 +14316,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/I18n/TimeTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\I18n\\\\TimeTest\\:\\:testUnserializeTimeObject\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/I18n/TimeTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Call to an undefined method CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:getPathname\\(\\)\\.$#',
 	'count' => 1,
@@ -15991,71 +15241,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testAutoRouteFallbackToDefaultControllerNoParams\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testAutoRouteFallbackToDefaultControllerOneParam\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testAutoRouteFallbackToDefaultControllerTwoParams\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testAutoRouteFallbackToDefaultMethod\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testAutoRouteFindsControllerWithSubSubfolder\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testAutoRouteFindsModuleDefaultControllerAndMethodGet\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testDoesNotTranslateDashInParam\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testPermitsURIWithUnderscoreParam\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testRejectTranslateUriToCamelCase\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testRejectsURIWithUnderscoreController\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testRejectsURIWithUnderscoreFolder\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testRejectsURIWithUnderscoreMethod\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouterImprovedTest\\:\\:testTranslateUriToCamelCase\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/AutoRouterImprovedTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Router\\\\Controllers\\\\BlogController\\:\\:getSomeMethod\\(\\) has parameter \\$first with no type specified\\.$#',
 	'count' => 1,
@@ -16081,11 +15266,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Router/Controllers/SubDir/BlogController.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\Controllers\\\\Subfolder\\\\Home\\:\\:getIndex\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/Controllers/Subfolder/Home.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Router\\\\Controllers\\\\Subfolder\\\\Home\\:\\:getIndex\\(\\) has parameter \\$p1 with no type specified\\.$#',
 	'count' => 1,
@@ -16101,11 +15281,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Router/Controllers/Subfolder/Sub/BlogController.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\Controllers\\\\Subfolder\\\\Sub\\\\Mycontroller\\:\\:getSomemethod\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/Controllers/Subfolder/Sub/Mycontroller.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Router\\\\DefinedRouteCollectorTest\\:\\:createRouteCollection\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -16116,16 +15291,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Router/DefinedRouteCollectorTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\DefinedRouteCollectorTest\\:\\:testCollect\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/DefinedRouteCollectorTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Router\\\\DefinedRouteCollectorTest\\:\\:testCollectSameFromWithDifferentVerb\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Router/DefinedRouteCollectorTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollectionReverseRouteTest\\:\\:getCollector\\(\\) has no return type specified\\.$#',
 	'count' => 1,
@@ -16246,21 +15411,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Router/RouterTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Security\\\\CheckPhpIniTest\\:\\:testCheckIni\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Security/CheckPhpIniTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Security\\\\CheckPhpIniTest\\:\\:testRunCli\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Security/CheckPhpIniTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Security\\\\CheckPhpIniTest\\:\\:testRunWeb\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Security/CheckPhpIniTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Assigning \'POST\' directly on offset \'REQUEST_METHOD\' of \\$_SERVER is discouraged\\.$#',
 	'count' => 1,
@@ -16416,11 +15566,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Session/SessionTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\SuperglobalsTest\\:\\:testSetGet\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/SuperglobalsTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Test\\\\BootstrapFCPATHTest\\:\\:correctFCPATH\\(\\) has no return type specified\\.$#',
 	'count' => 1,
@@ -16466,11 +15611,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Test/ControllerTestTraitTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Test\\\\ControllerTestTraitTest\\:\\:testWithUriUpdatesUriStringAndCurrentUrlValues\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Test/ControllerTestTraitTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#1 \\$config of class CodeIgniter\\\\Log\\\\Logger constructor expects Config\\\\Logger, CodeIgniter\\\\Test\\\\Mock\\\\MockLogger given\\.$#',
 	'count' => 15,
@@ -16691,21 +15831,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Test/FeatureTestTraitTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Test\\\\FeatureTestTraitTest\\:\\:testAutoRoutingLegacy\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Test/FeatureTestTraitTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Test\\\\FeatureTestTraitTest\\:\\:testClosureWithEcho\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Test/FeatureTestTraitTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Test\\\\FeatureTestTraitTest\\:\\:testForceGlobalSecureRequests\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Test/FeatureTestTraitTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method CodeIgniter\\\\Test\\\\FeatureTestTraitTest\\:\\:withHeaders\\(\\) has parameter \\$headers with no value type specified in iterable type array\\.$#',
 	'count' => 1,
@@ -16866,56 +15991,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/Validation/DatabaseRelatedRulesTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunEarlyIndex\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunIgnoresLastWildcard\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunNestedArray\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunNestedNotFound\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunReturnEmptyArray\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunReturnEmptyArrayEmptyIndex\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunReturnEmptyArrayMissingValue\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunReturnOrderedIndices\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunWildcard\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\Validation\\\\DotArrayFilterTest\\:\\:testRunWildcardWithMultipleChoices\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/Validation/DotArrayFilterTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Parameter \\#1 \\$config of class CodeIgniter\\\\Validation\\\\Validation constructor expects Config\\\\Validation, stdClass given\\.$#',
 	'count' => 1,
@@ -17636,11 +16711,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/system/View/TableTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method CodeIgniter\\\\View\\\\ViewTest\\:\\:testRenderSectionSavingData\\(\\) has no return type specified\\.$#',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/system/View/ViewTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Property CodeIgniter\\\\View\\\\ViewTest\\:\\:\\$loader \\(CodeIgniter\\\\Autoloader\\\\FileLocator\\) does not accept CodeIgniter\\\\Autoloader\\\\FileLocatorInterface\\.$#',
 	'count' => 1,
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 45b6b07231c4..7464323e4078 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,11 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.4/phpunit.xsd"
-         bootstrap="system/Test/bootstrap.php" backupGlobals="false"
-         beStrictAboutOutputDuringTests="true" colors="true" columns="max"
-         failOnRisky="true" failOnWarning="true"
-         cacheDirectory=".phpunit.cache">
-    <coverage ignoreDeprecatedCodeUnits="true">
+<phpunit
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
+    bootstrap="system/Test/bootstrap.php"
+    backupGlobals="false"
+    beStrictAboutOutputDuringTests="true"
+    colors="true"
+    columns="max"
+    failOnRisky="true"
+    failOnWarning="true"
+    cacheDirectory="build/.phpunit.cache">
+    <coverage
+        includeUncoveredFiles="true"
+        pathCoverage="false"
+        ignoreDeprecatedCodeUnits="true"
+        disableCodeCoverageIgnore="true">
         <report>
             <clover outputFile="build/logs/clover.xml"/>
             <html outputDirectory="build/coverage/html" highLowerBound="80"/>
diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php
index 97da0fa275eb..14b9a1366ab4 100644
--- a/system/Autoloader/FileLocator.php
+++ b/system/Autoloader/FileLocator.php
@@ -28,6 +28,13 @@ class FileLocator implements FileLocatorInterface
      */
     protected $autoloader;
 
+    /**
+     * List of classnames that did not exist.
+     *
+     * @var list<class-string>
+     */
+    private array $invalidClassnames = [];
+
     public function __construct(Autoloader $autoloader)
     {
         $this->autoloader = $autoloader;
@@ -288,14 +295,20 @@ public function findQualifiedNameFromPath(string $path)
                         ),
                         '\\'
                     );
-
                 // Remove the file extension (.php)
                 $className = mb_substr($className, 0, -4);
 
+                if (in_array($className, $this->invalidClassnames, true)) {
+                    continue;
+                }
+
                 // Check if this exists
                 if (class_exists($className)) {
                     return $className;
                 }
+
+                // If the class does not exist, it is an invalid classname.
+                $this->invalidClassnames[] = $className;
             }
         }
 
diff --git a/system/BaseModel.php b/system/BaseModel.php
index 5d08ec59e04c..9b8bb70ed482 100644
--- a/system/BaseModel.php
+++ b/system/BaseModel.php
@@ -926,6 +926,9 @@ public function insertBatch(?array $set = null, ?bool $escape = null, int $batch
                     $row = (array) $row;
                 }
 
+                // Convert any Time instances to appropriate $dateFormat
+                $row = $this->timeToString($row);
+
                 // Validate every row.
                 if (! $this->skipValidation && ! $this->validate($row)) {
                     // Restore $cleanValidationRules
@@ -1845,8 +1848,6 @@ protected function transformDataToArray($row, string $type): array
                 $row = $this->converter->toDataSource($row);
             } elseif ($row instanceof Entity) {
                 $row = $this->converter->extract($row, $onlyChanged);
-                // Convert any Time instances to appropriate $dateFormat
-                $row = $this->timeToString($row);
             } elseif (is_object($row)) {
                 $row = $this->converter->extract($row, $onlyChanged);
             }
@@ -1870,7 +1871,8 @@ protected function transformDataToArray($row, string $type): array
             throw DataException::forEmptyDataset($type);
         }
 
-        return $row;
+        // Convert any Time instances to appropriate $dateFormat
+        return $this->timeToString($row);
     }
 
     /**
diff --git a/system/CLI/BaseCommand.php b/system/CLI/BaseCommand.php
index 1b273846bd74..86ba504feaa6 100644
--- a/system/CLI/BaseCommand.php
+++ b/system/CLI/BaseCommand.php
@@ -108,6 +108,8 @@ abstract public function run(array $params);
     /**
      * Can be used by a command to run other commands.
      *
+     * @param array<int|string, string|null> $params
+     *
      * @return int|void
      *
      * @throws ReflectionException
@@ -140,7 +142,7 @@ public function showHelp()
     {
         CLI::write(lang('CLI.helpUsage'), 'yellow');
 
-        if (! empty($this->usage)) {
+        if (isset($this->usage)) {
             $usage = $this->usage;
         } else {
             $usage = $this->name;
@@ -152,7 +154,7 @@ public function showHelp()
 
         CLI::write($this->setPad($usage, 0, 0, 2));
 
-        if (! empty($this->description)) {
+        if (isset($this->description)) {
             CLI::newLine();
             CLI::write(lang('CLI.helpDescription'), 'yellow');
             CLI::write($this->setPad($this->description, 0, 0, 2));
@@ -194,6 +196,8 @@ public function setPad(string $item, int $max, int $extra = 2, int $indent = 0):
     /**
      * Get pad for $key => $value array output
      *
+     * @param array<string, string> $array
+     *
      * @deprecated Use setPad() instead.
      *
      * @codeCoverageIgnore
@@ -212,7 +216,7 @@ public function getPad(array $array, int $pad): int
     /**
      * Makes it simple to access our protected properties.
      *
-     * @return array|Commands|LoggerInterface|string|null
+     * @return array<string, string>|Commands|LoggerInterface|string|null
      */
     public function __get(string $key)
     {
diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php
index 7fdade26fb99..1758228076ab 100644
--- a/system/CodeIgniter.php
+++ b/system/CodeIgniter.php
@@ -56,7 +56,7 @@ class CodeIgniter
     /**
      * The current version of CodeIgniter Framework
      */
-    public const CI_VERSION = '4.5.0';
+    public const CI_VERSION = '4.5.1';
 
     /**
      * App startup time.
diff --git a/system/Commands/Housekeeping/ClearDebugbar.php b/system/Commands/Housekeeping/ClearDebugbar.php
index 2a5c9fa4b536..dd49b24a7656 100644
--- a/system/Commands/Housekeeping/ClearDebugbar.php
+++ b/system/Commands/Housekeeping/ClearDebugbar.php
@@ -57,7 +57,7 @@ public function run(array $params)
     {
         helper('filesystem');
 
-        if (! delete_files(WRITEPATH . 'debugbar')) {
+        if (! delete_files(WRITEPATH . 'debugbar', false, true)) {
             // @codeCoverageIgnoreStart
             CLI::error('Error deleting the debugbar JSON files.');
             CLI::newLine();
diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php
index 2f8df2a35420..cd770dc667ed 100644
--- a/system/Config/BaseService.php
+++ b/system/Config/BaseService.php
@@ -389,8 +389,15 @@ protected static function buildServicesCache(): void
                 $locator = static::locator();
                 $files   = $locator->search('Config/Services');
 
+                $systemPath = static::autoloader()->getNamespace('CodeIgniter')[0];
+
                 // Get instances of all service classes and cache them locally.
                 foreach ($files as $file) {
+                    // Does not search `CodeIgniter` namespace to prevent from loading twice.
+                    if (str_starts_with($file, $systemPath)) {
+                        continue;
+                    }
+
                     $classname = $locator->findQualifiedNameFromPath($file);
 
                     if ($classname === false) {
diff --git a/system/Config/Factories.php b/system/Config/Factories.php
index f8102118bc1d..d98664a24a7b 100644
--- a/system/Config/Factories.php
+++ b/system/Config/Factories.php
@@ -180,7 +180,9 @@ public static function get(string $component, string $alias): ?object
         if (isset(self::$aliases[$component][$alias])) {
             $class = self::$aliases[$component][$alias];
 
-            return self::$instances[$component][$class];
+            if (isset(self::$instances[$component][$class])) {
+                return self::$instances[$component][$class];
+            }
         }
 
         return self::__callStatic($component, [$alias]);
diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php
index e0bd7bb51217..b597c6d6cd10 100644
--- a/system/Database/BaseConnection.php
+++ b/system/Database/BaseConnection.php
@@ -17,6 +17,7 @@
 use CodeIgniter\Database\Exceptions\DatabaseException;
 use CodeIgniter\Events\Events;
 use stdClass;
+use Stringable;
 use Throwable;
 
 /**
@@ -1309,12 +1310,15 @@ public function escape($str)
             return array_map($this->escape(...), $str);
         }
 
-        /** @psalm-suppress NoValue I don't know why ERROR. */
-        if (is_string($str) || (is_object($str) && method_exists($str, '__toString'))) {
+        if ($str instanceof Stringable) {
             if ($str instanceof RawSql) {
                 return $str->__toString();
             }
 
+            $str = (string) $str;
+        }
+
+        if (is_string($str)) {
             return "'" . $this->escapeString($str) . "'";
         }
 
@@ -1328,8 +1332,8 @@ public function escape($str)
     /**
      * Escape String
      *
-     * @param list<string>|string $str  Input string
-     * @param bool                $like Whether or not the string will be used in a LIKE condition
+     * @param list<string|Stringable>|string|Stringable $str  Input string
+     * @param bool                                      $like Whether the string will be used in a LIKE condition
      *
      * @return list<string>|string
      */
@@ -1343,6 +1347,14 @@ public function escapeString($str, bool $like = false)
             return $str;
         }
 
+        if ($str instanceof Stringable) {
+            if ($str instanceof RawSql) {
+                return $str->__toString();
+            }
+
+            $str = (string) $str;
+        }
+
         $str = $this->_escapeString($str);
 
         // escape LIKE condition wildcards
@@ -1371,7 +1383,7 @@ public function escapeString($str, bool $like = false)
      * Calls the individual driver for platform
      * specific escaping for LIKE conditions
      *
-     * @param list<string>|string $str
+     * @param list<string|Stringable>|string|Stringable $str
      *
      * @return list<string>|string
      */
diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php
index 45e30eb65365..bce4209c64d2 100644
--- a/system/Database/Postgre/Connection.php
+++ b/system/Database/Postgre/Connection.php
@@ -20,6 +20,7 @@
 use PgSql\Connection as PgSqlConnection;
 use PgSql\Result as PgSqlResult;
 use stdClass;
+use Stringable;
 
 /**
  * Connection for Postgre
@@ -233,12 +234,15 @@ public function escape($str)
             $this->initialize();
         }
 
-        /** @psalm-suppress NoValue I don't know why ERROR. */
-        if (is_string($str) || (is_object($str) && method_exists($str, '__toString'))) {
+        if ($str instanceof Stringable) {
             if ($str instanceof RawSql) {
                 return $str->__toString();
             }
 
+            $str = (string) $str;
+        }
+
+        if (is_string($str)) {
             return pg_escape_literal($this->connID, $str);
         }
 
@@ -246,7 +250,6 @@ public function escape($str)
             return $str ? 'TRUE' : 'FALSE';
         }
 
-        /** @psalm-suppress NoValue I don't know why ERROR. */
         return parent::escape($str);
     }
 
diff --git a/system/Debug/BaseExceptionHandler.php b/system/Debug/BaseExceptionHandler.php
index dbccdcd07790..4305265d2d2c 100644
--- a/system/Debug/BaseExceptionHandler.php
+++ b/system/Debug/BaseExceptionHandler.php
@@ -245,8 +245,14 @@ protected static function highlightFile(string $file, int $lineNumber, int $line
      */
     protected function render(Throwable $exception, int $statusCode, $viewFile = null): void
     {
-        if (empty($viewFile) || ! is_file($viewFile)) {
-            echo 'The error view files were not found. Cannot render exception trace.';
+        if ($viewFile === null) {
+            echo 'The error view file was not specified. Cannot display error view.';
+
+            exit(1);
+        }
+
+        if (! is_file($viewFile)) {
+            echo 'The error view file "' . $viewFile . '" was not found. Cannot display error view.';
 
             exit(1);
         }
diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php
index c631e4162da4..115016225062 100644
--- a/system/Debug/Toolbar.php
+++ b/system/Debug/Toolbar.php
@@ -365,7 +365,7 @@ protected function roundTo(float $number, int $increments = 5): float
     }
 
     /**
-     * Prepare for debugging..
+     * Prepare for debugging.
      *
      * @return void
      */
@@ -378,6 +378,7 @@ public function prepare(?RequestInterface $request = null, ?ResponseInterface $r
             $app = service('codeigniter');
 
             $request ??= service('request');
+            /** @var ResponseInterface $response */
             $response ??= service('response');
 
             // Disable the toolbar for downloads
@@ -433,7 +434,7 @@ public function prepare(?RequestInterface $request = null, ?ResponseInterface $r
                 . $kintScript
                 . PHP_EOL;
 
-            if (str_contains($response->getBody(), '<head>')) {
+            if (str_contains((string) $response->getBody(), '<head>')) {
                 $response->setBody(
                     preg_replace(
                         '/<head>/',
diff --git a/system/Debug/Toolbar/Collectors/Routes.php b/system/Debug/Toolbar/Collectors/Routes.php
index 737c86bff692..b6862dcee73c 100644
--- a/system/Debug/Toolbar/Collectors/Routes.php
+++ b/system/Debug/Toolbar/Collectors/Routes.php
@@ -51,6 +51,25 @@ class Routes extends BaseCollector
     /**
      * Returns the data of this collector to be formatted in the toolbar
      *
+     * @return array{
+     *      matchedRoute: array<array{
+     *          directory: string,
+     *          controller: string,
+     *          method: string,
+     *          paramCount: int,
+     *          truePCount: int,
+     *          params: list<array{
+     *              name: string,
+     *              value: mixed
+     *          }>
+     *      }>,
+     *      routes: list<array{
+     *          method: string,
+     *          route: string,
+     *          handler: string
+     *      }>
+     * }
+     *
      * @throws ReflectionException
      */
     public function display(): array
diff --git a/system/Debug/Toolbar/Views/toolbar.css b/system/Debug/Toolbar/Views/toolbar.css
index 4154f4c5c4ca..2e165b825e99 100644
--- a/system/Debug/Toolbar/Views/toolbar.css
+++ b/system/Debug/Toolbar/Views/toolbar.css
@@ -13,8 +13,8 @@
   z-index: 10000;
   height: 36px;
   width: 36px;
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
   clear: both;
   text-align: center;
   cursor: pointer;
@@ -52,6 +52,8 @@
   display: flex;
   font-weight: normal;
   margin: 0 0 0 auto;
+  padding: 0;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
 }
 #debug-bar h1 svg {
   width: 16px;
diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php
index 725195918209..4b1c9c625399 100644
--- a/system/HTTP/CURLRequest.php
+++ b/system/HTTP/CURLRequest.php
@@ -107,6 +107,8 @@ class CURLRequest extends OutgoingRequest
      *  - baseURI
      *  - timeout
      *  - any other request options to use as defaults.
+     *
+     * @param array<string, mixed> $options
      */
     public function __construct(App $config, URI $uri, ?ResponseInterface $response = null, array $options = [])
     {
@@ -116,7 +118,10 @@ public function __construct(App $config, URI $uri, ?ResponseInterface $response
 
         parent::__construct(Method::GET, $uri);
 
-        $this->responseOrig   = $response ?? new Response(config(App::class));
+        $this->responseOrig = $response ?? new Response($config);
+        // Remove the default Content-Type header.
+        $this->responseOrig->removeHeader('Content-Type');
+
         $this->baseURI        = $uri->useRawQueryString();
         $this->defaultOptions = $options;
 
diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php
index 1e3ea4a9152a..2e5b9f7ca576 100644
--- a/system/Helpers/form_helper.php
+++ b/system/Helpers/form_helper.php
@@ -31,7 +31,7 @@ function form_open(string $action = '', $attributes = [], array $hidden = []): s
     {
         // If no action is provided then set to the current url
         if ($action === '') {
-            $action = current_url(true);
+            $action = (string) current_url(true);
         } // If an action is not a full URL then turn it into one
         elseif (! str_contains($action, '://')) {
             // If an action has {locale}
diff --git a/system/I18n/Time.php b/system/I18n/Time.php
index 2c6f3c4fab70..906479470b17 100644
--- a/system/I18n/Time.php
+++ b/system/I18n/Time.php
@@ -14,6 +14,7 @@
 namespace CodeIgniter\I18n;
 
 use DateTimeImmutable;
+use Stringable;
 
 /**
  * A localized date/time package inspired
@@ -21,26 +22,26 @@
  *
  * Requires the intl PHP extension.
  *
- * @property int    $age         read-only
- * @property string $day         read-only
- * @property string $dayOfWeek   read-only
- * @property string $dayOfYear   read-only
- * @property bool   $dst         read-only
- * @property string $hour        read-only
- * @property bool   $local       read-only
- * @property string $minute      read-only
- * @property string $month       read-only
- * @property string $quarter     read-only
- * @property string $second      read-only
- * @property int    $timestamp   read-only
- * @property bool   $utc         read-only
- * @property string $weekOfMonth read-only
- * @property string $weekOfYear  read-only
- * @property string $year        read-only
+ * @property-read int    $age
+ * @property-read string $day
+ * @property-read string $dayOfWeek
+ * @property-read string $dayOfYear
+ * @property-read bool   $dst
+ * @property-read string $hour
+ * @property-read bool   $local
+ * @property-read string $minute
+ * @property-read string $month
+ * @property-read string $quarter
+ * @property-read string $second
+ * @property-read int    $timestamp
+ * @property-read bool   $utc
+ * @property-read string $weekOfMonth
+ * @property-read string $weekOfYear
+ * @property-read string $year
  *
  * @see \CodeIgniter\I18n\TimeTest
  */
-class Time extends DateTimeImmutable
+class Time extends DateTimeImmutable implements Stringable
 {
     use TimeTrait;
 }
diff --git a/system/Model.php b/system/Model.php
index 61f4350f3117..b3ecfc653943 100644
--- a/system/Model.php
+++ b/system/Model.php
@@ -40,7 +40,7 @@
  *      - allow intermingling calls to the builder
  *      - removes the need to use Result object directly in most cases
  *
- * @property BaseConnection $db
+ * @property-read BaseConnection $db
  *
  * @method $this groupBy($by, ?bool $escape = null)
  * @method $this groupEnd()
@@ -123,7 +123,8 @@ class Model extends BaseModel
      * so that we can capture it (not the builder)
      * and ensure it gets validated first.
      *
-     * @var array
+     * @var         array{escape: array, data: array}|array{}
+     * @phpstan-var array{escape: array<int|string, bool|null>, data: row_array}|array{}
      */
     protected $tempData = [];
 
diff --git a/system/Test/Interfaces/FabricatorModel.php b/system/Test/Interfaces/FabricatorModel.php
index d4a4c270919c..a5860e22fb83 100644
--- a/system/Test/Interfaces/FabricatorModel.php
+++ b/system/Test/Interfaces/FabricatorModel.php
@@ -13,6 +13,7 @@
 
 namespace CodeIgniter\Test\Interfaces;
 
+use CodeIgniter\BaseModel;
 use Faker\Generator;
 use ReflectionException;
 
@@ -27,6 +28,8 @@
  * @property string $returnType
  * @property string $primaryKey
  * @property string $dateFormat
+ *
+ * @phpstan-import-type row_array from BaseModel
  */
 interface FabricatorModel
 {
@@ -34,9 +37,9 @@ interface FabricatorModel
      * Fetches the row of database from $this->table with a primary key
      * matching $id.
      *
-     * @param array|mixed|null $id One primary key or an array of primary keys
+     * @param int|list<int|string>|string|null $id One primary key or an array of primary keys
      *
-     * @return array|object|null The resulting row of data, or null.
+     * @phpstan-return ($id is int|string ? row_array|object|null : list<row_array|object>)
      */
     public function find($id = null);
 
@@ -44,14 +47,15 @@ public function find($id = null);
      * Inserts data into the current table. If an object is provided,
      * it will attempt to convert it to an array.
      *
-     * @param array|object $data
-     * @param bool         $returnID Whether insert ID should be returned or not.
+     * @param         array|object|null     $row
+     * @phpstan-param row_array|object|null $row
+     * @param         bool                  $returnID Whether insert ID should be returned or not.
      *
      * @return bool|int|string
      *
      * @throws ReflectionException
      */
-    public function insert($data = null, bool $returnID = true);
+    public function insert($row = null, bool $returnID = true);
 
     /**
      * The following properties and methods are optional, but if present should
diff --git a/system/View/Plugins.php b/system/View/Plugins.php
index da147d097d06..7142e44c452e 100644
--- a/system/View/Plugins.php
+++ b/system/View/Plugins.php
@@ -42,6 +42,8 @@ public static function previousURL()
 
     /**
      * Wrap helper function to use as view plugin.
+     *
+     * @param array{email?: string, title?: string, attributes?: array<string, string>|object|string} $params
      */
     public static function mailto(array $params = []): string
     {
@@ -54,6 +56,8 @@ public static function mailto(array $params = []): string
 
     /**
      * Wrap helper function to use as view plugin.
+     *
+     * @param array{email?: string, title?: string, attributes?: array<string, string>|object|string} $params
      */
     public static function safeMailto(array $params = []): string
     {
@@ -66,6 +70,8 @@ public static function safeMailto(array $params = []): string
 
     /**
      * Wrap helper function to use as view plugin.
+     *
+     * @param array<int|string, string>|list<string> $params
      */
     public static function lang(array $params = []): string
     {
@@ -76,8 +82,10 @@ public static function lang(array $params = []): string
 
     /**
      * Wrap helper function to use as view plugin.
+     *
+     * @param array{field?: string} $params
      */
-    public static function ValidationErrors(array $params = []): string
+    public static function validationErrors(array $params = []): string
     {
         $validator = service('validation');
         if ($params === []) {
@@ -90,6 +98,8 @@ public static function ValidationErrors(array $params = []): string
     /**
      * Wrap helper function to use as view plugin.
      *
+     * @param list<string> $params
+     *
      * @return false|string
      */
     public static function route(array $params = [])
@@ -99,6 +109,8 @@ public static function route(array $params = [])
 
     /**
      * Wrap helper function to use as view plugin.
+     *
+     * @param list<string> $params
      */
     public static function siteURL(array $params = []): string
     {
diff --git a/tests/_support/Config/Registrar.php b/tests/_support/Config/Registrar.php
index 8889021a2d00..b92c5e24bb16 100644
--- a/tests/_support/Config/Registrar.php
+++ b/tests/_support/Config/Registrar.php
@@ -23,9 +23,9 @@ class Registrar
     /**
      * DB config array for testing purposes.
      *
-     * @var array
+     * @var array<string, array<string, array<string, bool|int|string>|bool|int|string>>
      */
-    protected static $dbConfig = [
+    protected static array $dbConfig = [
         'MySQLi' => [
             'DSN'      => '',
             'hostname' => '127.0.0.1',
@@ -126,15 +126,15 @@ class Registrar
     /**
      * Override database config
      *
-     * @return array
+     * @return array<string, array<string, bool|int|string>|bool|int|string>
      */
-    public static function Database()
+    public static function Database(): array
     {
         $config = [];
 
         // Under GitHub Actions, we can set an ENV var named 'DB'
         // so that we can test against multiple databases.
-        if (($group = getenv('DB')) && ! empty(self::$dbConfig[$group])) {
+        if (($group = getenv('DB')) && isset(self::$dbConfig[$group])) {
             $config['tests'] = self::$dbConfig[$group];
         }
 
@@ -146,9 +146,9 @@ public static function Database()
      *
      * @see PublisherRestrictionsTest::testRegistrarsNotAllowed()
      *
-     * @return array
+     * @return array<string, array<string, string>>
      */
-    public static function Publisher()
+    public static function Publisher(): array
     {
         return [
             'restrictions' => [SUPPORTPATH => '*'],
diff --git a/tests/_support/Models/FabricatorModel.php b/tests/_support/Models/FabricatorModel.php
index 2903b5036402..1cae9394b9a3 100644
--- a/tests/_support/Models/FabricatorModel.php
+++ b/tests/_support/Models/FabricatorModel.php
@@ -28,8 +28,10 @@ class FabricatorModel extends Model
         'description',
     ];
 
-    // Return a faked entity
-    public function fake(Generator &$faker)
+    /**
+     * Return a faked entity
+     */
+    public function fake(Generator &$faker): object
     {
         return (object) [
             'name'        => $faker->ipv4(),
diff --git a/tests/_support/Models/UserCastsTimestampModel.php b/tests/_support/Models/UserCastsTimestampModel.php
index a61bd33472ab..c19353f01319 100644
--- a/tests/_support/Models/UserCastsTimestampModel.php
+++ b/tests/_support/Models/UserCastsTimestampModel.php
@@ -39,7 +39,7 @@ class UserCastsTimestampModel extends Model
     protected $useTimestamps  = true;
     protected $dateFormat     = 'datetime';
 
-    protected function initialize()
+    protected function initialize(): void
     {
         parent::initialize();
 
diff --git a/tests/_support/Services/Translation/TranslationNested/TranslationFour.php b/tests/_support/Services/Translation/TranslationNested/TranslationFour.php
index 68c41c40c6e7..7b88f93c3df5 100644
--- a/tests/_support/Services/Translation/TranslationNested/TranslationFour.php
+++ b/tests/_support/Services/Translation/TranslationNested/TranslationFour.php
@@ -15,7 +15,7 @@
 
 class TranslationFour
 {
-    public function list()
+    public function list(): void
     {
         lang('TranslationOne.title');
         lang('TranslationOne.last_operation_success');
diff --git a/tests/_support/Services/Translation/TranslationOne.php b/tests/_support/Services/Translation/TranslationOne.php
index b913700731b5..6f3c222b9dba 100644
--- a/tests/_support/Services/Translation/TranslationOne.php
+++ b/tests/_support/Services/Translation/TranslationOne.php
@@ -15,7 +15,7 @@
 
 class TranslationOne
 {
-    public function list()
+    public function list(): void
     {
         lang('TranslationOne.title');
         lang('TranslationOne.DESCRIPTION');
diff --git a/tests/_support/Services/Translation/TranslationThree.php b/tests/_support/Services/Translation/TranslationThree.php
index d3ea6c5ec90b..2efc4d40a54f 100644
--- a/tests/_support/Services/Translation/TranslationThree.php
+++ b/tests/_support/Services/Translation/TranslationThree.php
@@ -15,7 +15,7 @@
 
 class TranslationThree
 {
-    public function list()
+    public function list(): void
     {
         lang('TranslationOne.title');
         lang('TranslationOne.DESCRIPTION');
diff --git a/tests/_support/Services/Translation/TranslationTwo.php b/tests/_support/Services/Translation/TranslationTwo.php
index 8272ec6271a8..b2c0289d28f1 100644
--- a/tests/_support/Services/Translation/TranslationTwo.php
+++ b/tests/_support/Services/Translation/TranslationTwo.php
@@ -15,7 +15,7 @@
 
 class TranslationTwo
 {
-    public function list()
+    public function list(): void
     {
         // Error language keys
         lang('TranslationTwo');
diff --git a/tests/system/Autoloader/FileLocatorCachedTest.php b/tests/system/Autoloader/FileLocatorCachedTest.php
index 675eb50f1899..a10f1f30781b 100644
--- a/tests/system/Autoloader/FileLocatorCachedTest.php
+++ b/tests/system/Autoloader/FileLocatorCachedTest.php
@@ -74,7 +74,7 @@ protected function tearDown(): void
         parent::tearDown();
     }
 
-    public function testDeleteCache()
+    public function testDeleteCache(): void
     {
         $this->assertNotSame([], $this->handler->get('FileLocatorCache'));
 
diff --git a/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php b/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php
index ab8fb0f52f56..1566862c2ff9 100644
--- a/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php
+++ b/tests/system/Cache/FactoriesCacheFileVarExportHandlerTest.php
@@ -39,14 +39,14 @@ protected function createFactoriesCache(): void
         $this->cache   = new FactoriesCache($this->handler);
     }
 
-    public function testInstantiate()
+    public function testInstantiate(): void
     {
         $this->createFactoriesCache();
 
         $this->assertInstanceOf(FactoriesCache::class, $this->cache);
     }
 
-    public function testSave()
+    public function testSave(): void
     {
         Factories::reset();
         Factories::config('App');
@@ -62,7 +62,7 @@ public function testSave()
         $this->assertArrayHasKey('App', $cachedData['aliases']);
     }
 
-    public function testLoad()
+    public function testLoad(): void
     {
         Factories::reset();
         /** @var App $appConfig */
@@ -80,7 +80,7 @@ public function testLoad()
         $this->assertSame('http://test.example.jp/this-is-test/', $appConfig->baseURL);
     }
 
-    public function testDelete()
+    public function testDelete(): void
     {
         $this->createFactoriesCache();
 
diff --git a/tests/system/Cache/ResponseCacheTest.php b/tests/system/Cache/ResponseCacheTest.php
index fd2363171ec1..059ad7d8f905 100644
--- a/tests/system/Cache/ResponseCacheTest.php
+++ b/tests/system/Cache/ResponseCacheTest.php
@@ -93,7 +93,7 @@ private function createResponseCache(?CacheConfig $cacheConfig = null): Response
         return (new ResponseCache($cacheConfig, $cache))->setTtl(300);
     }
 
-    public function testCachePageIncomingRequest()
+    public function testCachePageIncomingRequest(): void
     {
         $pageCache = $this->createResponseCache();
 
@@ -131,7 +131,7 @@ public function testCachePageIncomingRequest()
         $this->assertNull($cachedResponse);
     }
 
-    public function testCachePageIncomingRequestWithCacheQueryString()
+    public function testCachePageIncomingRequestWithCacheQueryString(): void
     {
         $cacheConfig                   = new CacheConfig();
         $cacheConfig->cacheQueryString = true;
@@ -169,7 +169,7 @@ public function testCachePageIncomingRequestWithCacheQueryString()
         $this->assertNull($cachedResponse);
     }
 
-    public function testCachePageIncomingRequestWithHttpMethods()
+    public function testCachePageIncomingRequestWithHttpMethods(): void
     {
         $pageCache = $this->createResponseCache();
 
@@ -189,7 +189,7 @@ public function testCachePageIncomingRequestWithHttpMethods()
         $this->assertNull($cachedResponse);
     }
 
-    public function testCachePageCLIRequest()
+    public function testCachePageCLIRequest(): void
     {
         $pageCache = $this->createResponseCache();
 
@@ -217,7 +217,7 @@ public function testCachePageCLIRequest()
         $this->assertNull($cachedResponse);
     }
 
-    public function testUnserializeError()
+    public function testUnserializeError(): void
     {
         $this->expectException(ErrorException::class);
         $this->expectExceptionMessage('unserialize(): Error at offset 0 of 12 bytes');
@@ -243,7 +243,7 @@ public function testUnserializeError()
         $pageCache->get($request, new Response($this->appConfig));
     }
 
-    public function testInvalidCacheError()
+    public function testInvalidCacheError(): void
     {
         $this->expectException(Exception::class);
         $this->expectExceptionMessage('Error unserializing page cache');
diff --git a/tests/system/CodeIgniterTest.php b/tests/system/CodeIgniterTest.php
index d6e93ab7a6d0..fadfe365307a 100644
--- a/tests/system/CodeIgniterTest.php
+++ b/tests/system/CodeIgniterTest.php
@@ -83,7 +83,7 @@ public function testRunEmptyDefaultRoute(): void
         $this->assertStringContainsString('Welcome to CodeIgniter', $output);
     }
 
-    public function testOutputBufferingControl()
+    public function testOutputBufferingControl(): void
     {
         ob_start();
         $this->codeigniter->run();
@@ -310,7 +310,7 @@ public function testRunExecuteFilterByClassName(): void
         $this->resetServices();
     }
 
-    public function testRegisterSameFilterTwiceWithDifferentArgument()
+    public function testRegisterSameFilterTwiceWithDifferentArgument(): void
     {
         $this->expectException(ConfigException::class);
         $this->expectExceptionMessage('"test-customfilter" already has arguments: null');
diff --git a/tests/system/Commands/ClearDebugbarTest.php b/tests/system/Commands/ClearDebugbarTest.php
index d55988996ee8..1e86406f7054 100644
--- a/tests/system/Commands/ClearDebugbarTest.php
+++ b/tests/system/Commands/ClearDebugbarTest.php
@@ -61,7 +61,7 @@ public function testClearDebugbarWorks(): void
         $result = $this->getStreamFilterBuffer();
 
         $this->assertFileDoesNotExist(WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . "debugbar_{$this->time}.json");
-        $this->assertFileExists(WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . '.gitkeep');
+        $this->assertFileExists(WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . 'index.html');
         $this->assertStringContainsString('Debugbar cleared.', $result);
     }
 }
diff --git a/tests/system/Commands/RoutesTest.php b/tests/system/Commands/RoutesTest.php
index b6384858f5fb..634078e98409 100644
--- a/tests/system/Commands/RoutesTest.php
+++ b/tests/system/Commands/RoutesTest.php
@@ -116,7 +116,7 @@ public function testRoutesCommandSortByHandler(): void
         $this->assertStringContainsString($expected, $this->getBuffer());
     }
 
-    public function testRoutesCommandHostHostname()
+    public function testRoutesCommandHostHostname(): void
     {
         Services::injectMock('routes', null);
 
@@ -145,7 +145,7 @@ public function testRoutesCommandHostHostname()
         $this->assertStringContainsString($expected, $this->getBuffer());
     }
 
-    public function testRoutesCommandHostSubdomain()
+    public function testRoutesCommandHostSubdomain(): void
     {
         Services::injectMock('routes', null);
 
diff --git a/tests/system/Commands/Utilities/ConfigCheckTest.php b/tests/system/Commands/Utilities/ConfigCheckTest.php
index 9d2c5fdfd3d3..b7e3890a5e61 100644
--- a/tests/system/Commands/Utilities/ConfigCheckTest.php
+++ b/tests/system/Commands/Utilities/ConfigCheckTest.php
@@ -72,7 +72,7 @@ public function testCommandConfigCheckNonexistentClass(): void
         );
     }
 
-    public function testGetKintD()
+    public function testGetKintD(): void
     {
         $command  = new ConfigCheck(Services::logger(), Services::commands());
         $getKintD = $this->getPrivateMethodInvoker($command, 'getKintD');
@@ -112,7 +112,7 @@ public function testGetKintD()
         );
     }
 
-    public function testGetVarDump()
+    public function testGetVarDump(): void
     {
         $command    = new ConfigCheck(Services::logger(), Services::commands());
         $getVarDump = $this->getPrivateMethodInvoker($command, 'getVarDump');
diff --git a/tests/system/Commands/Utilities/Routes/FilterFinderTest.php b/tests/system/Commands/Utilities/Routes/FilterFinderTest.php
index ad3c638fc42e..495fbb46f31b 100644
--- a/tests/system/Commands/Utilities/Routes/FilterFinderTest.php
+++ b/tests/system/Commands/Utilities/Routes/FilterFinderTest.php
@@ -190,7 +190,7 @@ public function testFindGlobalsAndRouteMultipleFilters(): void
         $this->assertSame($expected, $filters);
     }
 
-    public function testFilterOrder()
+    public function testFilterOrder(): void
     {
         $collection = $this->createRouteCollection([]);
         $collection->get('/', ' Home::index', ['filter' => ['route1', 'route2']]);
@@ -252,7 +252,7 @@ public function testFilterOrder()
         $this->assertSame($expected, $filters);
     }
 
-    public function testFilterOrderWithOldFilterOrder()
+    public function testFilterOrderWithOldFilterOrder(): void
     {
         $feature                 = config(Feature::class);
         $feature->oldFilterOrder = true;
diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php
index 35866f640ee9..7e1e9d27c349 100644
--- a/tests/system/CommonFunctionsTest.php
+++ b/tests/system/CommonFunctionsTest.php
@@ -189,14 +189,14 @@ public function testSolidusElementXHTML(): void
         $this->enableHtml5();
     }
 
-    private function disableHtml5()
+    private function disableHtml5(): void
     {
         $doctypes        = new DocTypes();
         $doctypes->html5 = false;
         _solidus($doctypes);
     }
 
-    private function enableHtml5()
+    private function enableHtml5(): void
     {
         $doctypes = new DocTypes();
         _solidus($doctypes);
diff --git a/tests/system/Config/FactoriesTest.php b/tests/system/Config/FactoriesTest.php
index f40b0968fb74..dfca8511ada5 100644
--- a/tests/system/Config/FactoriesTest.php
+++ b/tests/system/Config/FactoriesTest.php
@@ -259,7 +259,7 @@ class_alias(SomeWidget::class, $class);
         $this->assertInstanceOf(SomeWidget::class, $result);
     }
 
-    public function testShortnameReturnsConfigInApp()
+    public function testShortnameReturnsConfigInApp(): void
     {
         // Create a config class in App
         $file   = APPPATH . 'Config/TestRegistrar.php';
@@ -279,7 +279,7 @@ class TestRegistrar
         unlink($file);
     }
 
-    public function testFullClassnameIgnoresPreferApp()
+    public function testFullClassnameIgnoresPreferApp(): void
     {
         // Create a config class in App
         $file   = APPPATH . 'Config/TestRegistrar.php';
@@ -317,7 +317,7 @@ class_alias(SomeWidget::class, $class);
         $this->assertInstanceOf(OtherWidget::class, $result);
     }
 
-    public function testCanLoadTwoCellsWithSameShortName()
+    public function testCanLoadTwoCellsWithSameShortName(): void
     {
         $cell1 = Factories::cells('\\' . SampleClass::class);
         $cell2 = Factories::cells('\\' . \Tests\Support\View\OtherCells\SampleClass::class);
@@ -325,7 +325,7 @@ public function testCanLoadTwoCellsWithSameShortName()
         $this->assertNotSame($cell1, $cell2);
     }
 
-    public function testCanLoadSharedConfigWithDifferentAlias()
+    public function testCanLoadSharedConfigWithDifferentAlias(): void
     {
         $config1 = Factories::config(App::class);
         $config2 = Factories::config('App');
@@ -333,7 +333,7 @@ public function testCanLoadSharedConfigWithDifferentAlias()
         $this->assertSame($config1, $config2);
     }
 
-    public function testDefineSameAliasTwiceWithDifferentClasses()
+    public function testDefineSameAliasTwiceWithDifferentClasses(): void
     {
         $this->expectException(InvalidArgumentException::class);
         $this->expectExceptionMessage(
@@ -352,7 +352,7 @@ public function testDefineSameAliasTwiceWithDifferentClasses()
         );
     }
 
-    public function testDefineSameAliasAndSameClassTwice()
+    public function testDefineSameAliasAndSameClassTwice(): void
     {
         Factories::define(
             'models',
@@ -370,7 +370,7 @@ public function testDefineSameAliasAndSameClassTwice()
         $this->assertInstanceOf(UserModel::class, $model);
     }
 
-    public function testDefineNonExistentClass()
+    public function testDefineNonExistentClass(): void
     {
         $this->expectException(InvalidArgumentException::class);
         $this->expectExceptionMessage('No such class: App\Models\UserModel');
@@ -382,7 +382,7 @@ public function testDefineNonExistentClass()
         );
     }
 
-    public function testDefineAfterLoading()
+    public function testDefineAfterLoading(): void
     {
         $this->expectException(InvalidArgumentException::class);
         $this->expectExceptionMessage(
@@ -398,7 +398,7 @@ public function testDefineAfterLoading()
         );
     }
 
-    public function testDefineAndLoad()
+    public function testDefineAndLoad(): void
     {
         Factories::define(
             'models',
@@ -411,6 +411,19 @@ public function testDefineAndLoad()
         $this->assertInstanceOf(EntityModel::class, $model);
     }
 
+    public function testDefineAndGet(): void
+    {
+        Factories::define(
+            'models',
+            UserModel::class,
+            EntityModel::class
+        );
+
+        $model = Factories::get('models', UserModel::class);
+
+        $this->assertInstanceOf(EntityModel::class, $model);
+    }
+
     public function testGetComponentInstances()
     {
         Factories::config('App');
@@ -447,7 +460,7 @@ public function testSetComponentInstances(array $data)
     /**
      * @depends testSetComponentInstances
      */
-    public function testIsUpdated(array $data)
+    public function testIsUpdated(array $data): void
     {
         Factories::reset();
 
@@ -466,21 +479,21 @@ public function testIsUpdated(array $data)
         $this->assertFalse(Factories::isUpdated('config'));
     }
 
-    public function testGetReturnsFactoriesConfigInstance()
+    public function testGetReturnsFactoriesConfigInstance(): void
     {
         $config = Factories::config('App');
 
         $this->assertSame($config, Factories::get('config', 'App'));
     }
 
-    public function testGetCreatesConfigInstanceAndFactoriesConfigReturnsIt()
+    public function testGetCreatesConfigInstanceAndFactoriesConfigReturnsIt(): void
     {
         $config = Factories::get('config', 'App');
 
         $this->assertSame($config, Factories::config('App'));
     }
 
-    public function testGetNonexistentClass()
+    public function testGetNonexistentClass(): void
     {
         $config = Factories::get('config', 'NonexistentClass');
 
diff --git a/tests/system/DataConverter/DataConverterTest.php b/tests/system/DataConverter/DataConverterTest.php
index acb31074b3da..e5ae5e7abe90 100644
--- a/tests/system/DataConverter/DataConverterTest.php
+++ b/tests/system/DataConverter/DataConverterTest.php
@@ -538,7 +538,7 @@ private function createDataConverter(
         return new DataConverter($types, $handlers, $helper, $reconstructor, $extractor);
     }
 
-    public function testReconstructObjectWithReconstructMethod()
+    public function testReconstructObjectWithReconstructMethod(): void
     {
         $types = [
             'id'         => 'int',
@@ -565,7 +565,7 @@ public function testReconstructObjectWithReconstructMethod()
         $this->assertInstanceOf(Time::class, $obj->updated_at);
     }
 
-    public function testReconstructObjectWithClosure()
+    public function testReconstructObjectWithClosure(): void
     {
         $types = [
             'id'         => 'int',
@@ -598,7 +598,7 @@ public function testReconstructObjectWithClosure()
         $this->assertInstanceOf(Time::class, $obj->updated_at);
     }
 
-    public function testExtract()
+    public function testExtract(): void
     {
         $types = [
             'id'         => 'int',
@@ -630,7 +630,7 @@ public function testExtract()
         ], $array);
     }
 
-    public function testExtractWithExtractMethod()
+    public function testExtractWithExtractMethod(): void
     {
         $types = [
             'id'         => 'int',
@@ -662,7 +662,7 @@ public function testExtractWithExtractMethod()
         ], $array);
     }
 
-    public function testExtractWithClosure()
+    public function testExtractWithClosure(): void
     {
         $types = [
             'id'         => 'int',
diff --git a/tests/system/Database/Live/EscapeTest.php b/tests/system/Database/Live/EscapeTest.php
index e1b700547c0c..0f931cdbe85c 100644
--- a/tests/system/Database/Live/EscapeTest.php
+++ b/tests/system/Database/Live/EscapeTest.php
@@ -14,6 +14,7 @@
 namespace CodeIgniter\Database\Live;
 
 use CodeIgniter\Database\RawSql;
+use CodeIgniter\I18n\Time;
 use CodeIgniter\Test\CIUnitTestCase;
 use CodeIgniter\Test\DatabaseTestTrait;
 
@@ -54,6 +55,14 @@ public function testEscape(): void
         $this->assertSame($expected, $sql);
     }
 
+    public function testEscapeStringable(): void
+    {
+        $expected = "SELECT * FROM brands WHERE name = '2024-01-01 12:00:00'";
+        $sql      = 'SELECT * FROM brands WHERE name = ' . $this->db->escape(new Time('2024-01-01 12:00:00'));
+
+        $this->assertSame($expected, $sql);
+    }
+
     public function testEscapeString(): void
     {
         $expected = "SELECT * FROM brands WHERE name = 'O" . $this->char . "'Doules'";
@@ -62,6 +71,15 @@ public function testEscapeString(): void
         $this->assertSame($expected, $sql);
     }
 
+    public function testEscapeStringStringable(): void
+    {
+        $expected = "SELECT * FROM brands WHERE name = '2024-01-01 12:00:00'";
+        $sql      = "SELECT * FROM brands WHERE name = '"
+            . $this->db->escapeString(new Time('2024-01-01 12:00:00')) . "'";
+
+        $this->assertSame($expected, $sql);
+    }
+
     public function testEscapeLikeString(): void
     {
         $expected = "SELECT * FROM brands WHERE column LIKE '%10!% more%' ESCAPE '!'";
@@ -70,6 +88,15 @@ public function testEscapeLikeString(): void
         $this->assertSame($expected, $sql);
     }
 
+    public function testEscapeLikeStringStringable(): void
+    {
+        $expected = "SELECT * FROM brands WHERE column LIKE '%2024-01-01 12:00:00%' ESCAPE '!'";
+        $sql      = "SELECT * FROM brands WHERE column LIKE '%"
+            . $this->db->escapeLikeString(new Time('2024-01-01 12:00:00')) . "%' ESCAPE '!'";
+
+        $this->assertSame($expected, $sql);
+    }
+
     public function testEscapeLikeStringDirect(): void
     {
         if ($this->db->DBDriver === 'MySQLi') {
diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php
index 44f143301f9d..8061e80d7241 100644
--- a/tests/system/Database/Live/ForgeTest.php
+++ b/tests/system/Database/Live/ForgeTest.php
@@ -875,7 +875,7 @@ public function testAddColumn(): void
         $this->assertSame('username', $fieldNames[1]);
     }
 
-    public function testAddColumnNull()
+    public function testAddColumnNull(): void
     {
         $this->forge->dropTable('forge_test_table', true);
 
diff --git a/tests/system/Database/Live/MySQLi/NumberNativeTest.php b/tests/system/Database/Live/MySQLi/NumberNativeTest.php
index 81ec7a01fd40..5ba37eaf804e 100644
--- a/tests/system/Database/Live/MySQLi/NumberNativeTest.php
+++ b/tests/system/Database/Live/MySQLi/NumberNativeTest.php
@@ -40,7 +40,7 @@ protected function setUp(): void
         $this->tests = $config->tests;
     }
 
-    public function testEnableNumberNative()
+    public function testEnableNumberNative(): void
     {
         $this->tests['numberNative'] = true;
 
@@ -53,7 +53,7 @@ public function testEnableNumberNative()
         $this->assertTrue($db1->numberNative);
     }
 
-    public function testDisableNumberNative()
+    public function testDisableNumberNative(): void
     {
         $this->tests['numberNative'] = false;
 
@@ -66,7 +66,7 @@ public function testDisableNumberNative()
         $this->assertFalse($db1->numberNative);
     }
 
-    public function testQueryDataAfterEnableNumberNative()
+    public function testQueryDataAfterEnableNumberNative(): void
     {
         $this->tests['numberNative'] = true;
 
@@ -84,7 +84,7 @@ public function testQueryDataAfterEnableNumberNative()
         $this->assertIsInt($data->type_integer);
     }
 
-    public function testQueryDataAfterDisableNumberNative()
+    public function testQueryDataAfterDisableNumberNative(): void
     {
         $this->tests['numberNative'] = false;
 
diff --git a/tests/system/Entity/EntityTest.php b/tests/system/Entity/EntityTest.php
index 20d846551851..37e65c497e57 100644
--- a/tests/system/Entity/EntityTest.php
+++ b/tests/system/Entity/EntityTest.php
@@ -36,7 +36,7 @@ final class EntityTest extends CIUnitTestCase
 {
     use ReflectionHelper;
 
-    public function testSetStringToPropertyNamedAttributes()
+    public function testSetStringToPropertyNamedAttributes(): void
     {
         $entity = $this->getEntity();
 
@@ -48,7 +48,7 @@ public function testSetStringToPropertyNamedAttributes()
     /**
      * @see https://github.com/codeigniter4/CodeIgniter4/issues
      */
-    public function testSetArrayToPropertyNamedAttributes()
+    public function testSetArrayToPropertyNamedAttributes(): void
     {
         $entity = new Entity();
 
@@ -84,7 +84,7 @@ public function testGetterSetters(): void
         $this->assertSame('bar:thanks:bar', $entity->bar);
     }
 
-    public function testNewGetterSetters()
+    public function testNewGetterSetters(): void
     {
         $entity = $this->getNewSetterGetterEntity();
 
diff --git a/tests/system/Filters/FiltersTest.php b/tests/system/Filters/FiltersTest.php
index 7905cfefdae6..9ce2c1b28985 100644
--- a/tests/system/Filters/FiltersTest.php
+++ b/tests/system/Filters/FiltersTest.php
@@ -842,7 +842,7 @@ public function testEnableFilter(): void
         $this->assertContains('google', $filters['before']);
     }
 
-    public function testFiltersWithArguments()
+    public function testFiltersWithArguments(): void
     {
         $_SERVER['REQUEST_METHOD'] = 'GET';
 
@@ -876,7 +876,7 @@ public function testFiltersWithArguments()
         $this->assertSame('admin;super', $response->getBody());
     }
 
-    public function testFilterWithArgumentsIsDefined()
+    public function testFilterWithArgumentsIsDefined(): void
     {
         $this->expectException(ConfigException::class);
         $this->expectExceptionMessage('"role" already has arguments: admin,super');
@@ -901,7 +901,7 @@ public function testFilterWithArgumentsIsDefined()
         $filters->initialize('admin/user/bar');
     }
 
-    public function testFilterWithoutArgumentsIsDefined()
+    public function testFilterWithoutArgumentsIsDefined(): void
     {
         $_SERVER['REQUEST_METHOD'] = 'GET';
 
diff --git a/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php b/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php
deleted file mode 100644
index f6e06a882191..000000000000
--- a/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php
+++ /dev/null
@@ -1,1144 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/**
- * This file is part of CodeIgniter 4 framework.
- *
- * (c) CodeIgniter Foundation <admin@codeigniter.com>
- *
- * For the full copyright and license information, please view
- * the LICENSE file that was distributed with this source code.
- */
-
-namespace CodeIgniter\HTTP;
-
-use CodeIgniter\Config\Factories;
-use CodeIgniter\Config\Services;
-use CodeIgniter\HTTP\Exceptions\HTTPException;
-use CodeIgniter\Test\CIUnitTestCase;
-use CodeIgniter\Test\Mock\MockCURLRequest;
-use Config\App;
-use Config\CURLRequest as ConfigCURLRequest;
-use CURLFile;
-
-/**
- * @internal
- *
- * @group Others
- */
-final class CURLRequestDoNotShareOptionsTest extends CIUnitTestCase
-{
-    private CURLRequest $request;
-
-    protected function setUp(): void
-    {
-        parent::setUp();
-
-        Services::reset();
-        $this->request = $this->getRequest();
-    }
-
-    protected function getRequest(array $options = [])
-    {
-        $uri = isset($options['base_uri']) ? new URI($options['base_uri']) : new URI();
-        $app = new App();
-
-        $config               = new ConfigCURLRequest();
-        $config->shareOptions = false;
-        Factories::injectMock('config', 'CURLRequest', $config);
-
-        return new MockCURLRequest(($app), $uri, new Response($app), $options);
-    }
-
-    /**
-     * @see https://github.com/codeigniter4/CodeIgniter4/issues/4707
-     */
-    public function testPrepareURLIgnoresAppConfig(): void
-    {
-        config('App')->baseURL = 'http://example.com/fruit/';
-
-        $request = $this->getRequest(['base_uri' => 'http://example.com/v1/']);
-
-        $method = $this->getPrivateMethodInvoker($request, 'prepareURL');
-
-        $this->assertSame('http://example.com/v1/bananas', $method('bananas'));
-    }
-
-    /**
-     * @see https://github.com/codeigniter4/CodeIgniter4/issues/1029
-     */
-    public function testGetRemembersBaseURI(): void
-    {
-        $request = $this->getRequest(['base_uri' => 'http://www.foo.com/api/v1/']);
-
-        $request->get('products');
-
-        $options = $request->curl_options;
-
-        $this->assertSame('http://www.foo.com/api/v1/products', $options[CURLOPT_URL]);
-    }
-
-    /**
-     * @see https://github.com/codeigniter4/CodeIgniter4/issues/1029
-     */
-    public function testGetRemembersBaseURIWithHelperMethod(): void
-    {
-        $request = Services::curlrequest(['base_uri' => 'http://www.foo.com/api/v1/']);
-
-        $uri = $this->getPrivateProperty($request, 'baseURI');
-        $this->assertSame('www.foo.com', $uri->getHost());
-        $this->assertSame('/api/v1/', $uri->getPath());
-    }
-
-    public function testSendReturnsResponse(): void
-    {
-        $output = 'Howdy Stranger.';
-
-        $response = $this->request->setOutput($output)->send('get', 'http://example.com');
-
-        $this->assertInstanceOf(Response::class, $response);
-        $this->assertSame($output, $response->getBody());
-    }
-
-    public function testGetSetsCorrectMethod(): void
-    {
-        $this->request->get('http://example.com');
-
-        $this->assertSame('GET', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('GET', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testDeleteSetsCorrectMethod(): void
-    {
-        $this->request->delete('http://example.com');
-
-        $this->assertSame('DELETE', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('DELETE', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testHeadSetsCorrectMethod(): void
-    {
-        $this->request->head('http://example.com');
-
-        $this->assertSame('HEAD', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('HEAD', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testOptionsSetsCorrectMethod(): void
-    {
-        $this->request->options('http://example.com');
-
-        $this->assertSame('OPTIONS', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('OPTIONS', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testOptionsBaseURIOption(): void
-    {
-        $options = ['base_uri' => 'http://www.foo.com/api/v1/'];
-        $request = $this->getRequest($options);
-
-        $this->assertSame('http://www.foo.com/api/v1/', $request->getBaseURI()->__toString());
-    }
-
-    public function testOptionsBaseURIOverride(): void
-    {
-        $options = [
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'baseURI'  => 'http://bogus/com',
-        ];
-        $request = $this->getRequest($options);
-
-        $this->assertSame('http://bogus/com', $request->getBaseURI()->__toString());
-    }
-
-    public function testOptionsHeaders(): void
-    {
-        $options = [
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'headers'  => ['fruit' => 'apple'],
-        ];
-        $request = $this->getRequest();
-        $this->assertNull($request->header('fruit'));
-
-        $request = $this->getRequest($options);
-        $this->assertSame('apple', $request->header('fruit')->getValue());
-    }
-
-    /**
-     * @backupGlobals enabled
-     */
-    public function testOptionsHeadersNotUsingPopulate(): void
-    {
-        $_SERVER['HTTP_HOST']            = 'site1.com';
-        $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en-US';
-        $_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip, deflate, br';
-
-        $options = [
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'headers'  => [
-                'Host'            => 'www.foo.com',
-                'Accept-Encoding' => '',
-            ],
-        ];
-        $request = $this->getRequest($options);
-        $request->get('example');
-        // if headers for the request are defined we use them
-        $this->assertNull($request->header('Accept-Language'));
-        $this->assertSame('www.foo.com', $request->header('Host')->getValue());
-        $this->assertSame('', $request->header('Accept-Encoding')->getValue());
-    }
-
-    public function testDefaultOptionsAreSharedBetweenRequests(): void
-    {
-        $options = [
-            'form_params' => ['studio' => 1],
-            'user_agent'  => 'CodeIgniter Framework v4',
-        ];
-        $request = $this->getRequest($options);
-
-        $request->request('POST', 'https://realestate1.example.com');
-
-        $this->assertSame('https://realestate1.example.com', $request->curl_options[CURLOPT_URL]);
-        $this->assertSame('studio=1', $request->curl_options[CURLOPT_POSTFIELDS]);
-        $this->assertSame('CodeIgniter Framework v4', $request->curl_options[CURLOPT_USERAGENT]);
-
-        $request->request('POST', 'https://realestate2.example.com');
-
-        $this->assertSame('https://realestate2.example.com', $request->curl_options[CURLOPT_URL]);
-        $this->assertSame('studio=1', $request->curl_options[CURLOPT_POSTFIELDS]);
-        $this->assertSame('CodeIgniter Framework v4', $request->curl_options[CURLOPT_USERAGENT]);
-    }
-
-    public function testHeaderContentLengthNotSharedBetweenRequests(): void
-    {
-        $options = [
-            'base_uri' => 'http://www.foo.com/api/v1/',
-        ];
-        $request = $this->getRequest($options);
-
-        $request->post('example', [
-            'form_params' => [
-                'q' => 'keyword',
-            ],
-        ]);
-        $request->get('example');
-
-        $this->assertNull($request->header('Content-Length'));
-    }
-
-    /**
-     * @backupGlobals enabled
-     */
-    public function testHeaderContentLengthNotSharedBetweenClients(): void
-    {
-        $_SERVER['HTTP_CONTENT_LENGTH'] = '10';
-
-        $options = [
-            'base_uri' => 'http://www.foo.com/api/v1/',
-        ];
-        $request = $this->getRequest($options);
-        $request->post('example', [
-            'form_params' => [
-                'q' => 'keyword',
-            ],
-        ]);
-
-        $request = $this->getRequest($options);
-        $request->get('example');
-
-        $this->assertNull($request->header('Content-Length'));
-    }
-
-    public function testOptionsDelay(): void
-    {
-        $request = $this->getRequest();
-        $this->assertEqualsWithDelta(0.0, $request->getDelay(), PHP_FLOAT_EPSILON);
-
-        $options = [
-            'delay'   => 2000,
-            'headers' => ['fruit' => 'apple'],
-        ];
-        $request = $this->getRequest($options);
-        $this->assertEqualsWithDelta(2.0, $request->getDelay(), PHP_FLOAT_EPSILON);
-    }
-
-    public function testPatchSetsCorrectMethod(): void
-    {
-        $this->request->patch('http://example.com');
-
-        $this->assertSame('PATCH', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('PATCH', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testPostSetsCorrectMethod(): void
-    {
-        $this->request->post('http://example.com');
-
-        $this->assertSame('POST', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('POST', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testPutSetsCorrectMethod(): void
-    {
-        $this->request->put('http://example.com');
-
-        $this->assertSame('PUT', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('PUT', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testCustomMethodSetsCorrectMethod(): void
-    {
-        $this->request->request('custom', 'http://example.com');
-
-        $this->assertSame('custom', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('custom', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testRequestMethodGetsSanitized(): void
-    {
-        $this->request->request('<script>Custom</script>', 'http://example.com');
-
-        $this->assertSame('Custom', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CUSTOMREQUEST, $options);
-        $this->assertSame('Custom', $options[CURLOPT_CUSTOMREQUEST]);
-    }
-
-    public function testRequestSetsBasicCurlOptions(): void
-    {
-        $this->request->request('get', 'http://example.com');
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_URL, $options);
-        $this->assertSame('http://example.com', $options[CURLOPT_URL]);
-
-        $this->assertArrayHasKey(CURLOPT_RETURNTRANSFER, $options);
-        $this->assertTrue($options[CURLOPT_RETURNTRANSFER]);
-
-        $this->assertArrayHasKey(CURLOPT_HEADER, $options);
-        $this->assertTrue($options[CURLOPT_HEADER]);
-
-        $this->assertArrayHasKey(CURLOPT_FRESH_CONNECT, $options);
-        $this->assertTrue($options[CURLOPT_FRESH_CONNECT]);
-
-        $this->assertArrayHasKey(CURLOPT_TIMEOUT_MS, $options);
-        $this->assertEqualsWithDelta(0.0, $options[CURLOPT_TIMEOUT_MS], PHP_FLOAT_EPSILON);
-
-        $this->assertArrayHasKey(CURLOPT_CONNECTTIMEOUT_MS, $options);
-        $this->assertEqualsWithDelta(150000.0, $options[CURLOPT_CONNECTTIMEOUT_MS], PHP_FLOAT_EPSILON);
-    }
-
-    public function testAuthBasicOption(): void
-    {
-        $this->request->request('get', 'http://example.com', [
-            'auth' => [
-                'username',
-                'password',
-            ],
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_USERPWD, $options);
-        $this->assertSame('username:password', $options[CURLOPT_USERPWD]);
-
-        $this->assertArrayHasKey(CURLOPT_HTTPAUTH, $options);
-        $this->assertSame(CURLAUTH_BASIC, $options[CURLOPT_HTTPAUTH]);
-    }
-
-    public function testAuthBasicOptionExplicit(): void
-    {
-        $this->request->request('get', 'http://example.com', [
-            'auth' => [
-                'username',
-                'password',
-                'basic',
-            ],
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_USERPWD, $options);
-        $this->assertSame('username:password', $options[CURLOPT_USERPWD]);
-
-        $this->assertArrayHasKey(CURLOPT_HTTPAUTH, $options);
-        $this->assertSame(CURLAUTH_BASIC, $options[CURLOPT_HTTPAUTH]);
-    }
-
-    public function testAuthDigestOption(): void
-    {
-        $output = "HTTP/1.1 401 Unauthorized
-		Server: ddos-guard
-		Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-		WWW-Authenticate: Digest\x0d\x0a\x0d\x0aHTTP/1.1 200 OK
-		Server: ddos-guard
-		Connection: keep-alive
-		Keep-Alive: timeout=60
-		Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-		Date: Tue, 07 Jul 2020 15:13:14 GMT
-		Expires: Thu, 19 Nov 1981 08:52:00 GMT
-		Cache-Control: no-store, no-cache, must-revalidate
-		Pragma: no-cache
-		Set-Cookie: PHPSESSID=80pd3hlg38mvjnelpvokp9lad0; path=/
-		Content-Type: application/xml; charset=utf-8
-		Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Update success! config</title>";
-
-        $this->request->setOutput($output);
-
-        $response = $this->request->request('get', 'http://example.com', [
-            'auth' => [
-                'username',
-                'password',
-                'digest',
-            ],
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertSame('<title>Update success! config</title>', $response->getBody());
-        $this->assertSame(200, $response->getStatusCode());
-
-        $this->assertArrayHasKey(CURLOPT_USERPWD, $options);
-        $this->assertSame('username:password', $options[CURLOPT_USERPWD]);
-
-        $this->assertArrayHasKey(CURLOPT_HTTPAUTH, $options);
-        $this->assertSame(CURLAUTH_DIGEST, $options[CURLOPT_HTTPAUTH]);
-    }
-
-    public function testSetAuthBasic(): void
-    {
-        $this->request->setAuth('username', 'password')->get('http://example.com');
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_USERPWD, $options);
-        $this->assertSame('username:password', $options[CURLOPT_USERPWD]);
-
-        $this->assertArrayHasKey(CURLOPT_HTTPAUTH, $options);
-        $this->assertSame(CURLAUTH_BASIC, $options[CURLOPT_HTTPAUTH]);
-    }
-
-    public function testSetAuthDigest(): void
-    {
-        $output = "HTTP/1.1 401 Unauthorized
-		Server: ddos-guard
-		Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-		WWW-Authenticate: Digest\x0d\x0a\x0d\x0aHTTP/1.1 200 OK
-		Server: ddos-guard
-		Connection: keep-alive
-		Keep-Alive: timeout=60
-		Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-		Date: Tue, 07 Jul 2020 15:13:14 GMT
-		Expires: Thu, 19 Nov 1981 08:52:00 GMT
-		Cache-Control: no-store, no-cache, must-revalidate
-		Pragma: no-cache
-		Set-Cookie: PHPSESSID=80pd3hlg38mvjnelpvokp9lad0; path=/
-		Content-Type: application/xml; charset=utf-8
-		Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Update success! config</title>";
-
-        $this->request->setOutput($output);
-
-        $response = $this->request->setAuth('username', 'password', 'digest')->get('http://example.com');
-
-        $options = $this->request->curl_options;
-
-        $this->assertSame('<title>Update success! config</title>', $response->getBody());
-        $this->assertSame(200, $response->getStatusCode());
-
-        $this->assertArrayHasKey(CURLOPT_USERPWD, $options);
-        $this->assertSame('username:password', $options[CURLOPT_USERPWD]);
-
-        $this->assertArrayHasKey(CURLOPT_HTTPAUTH, $options);
-        $this->assertSame(CURLAUTH_DIGEST, $options[CURLOPT_HTTPAUTH]);
-    }
-
-    public function testCertOption(): void
-    {
-        $file = __FILE__;
-
-        $this->request->request('get', 'http://example.com', [
-            'cert' => $file,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_SSLCERT, $options);
-        $this->assertSame($file, $options[CURLOPT_SSLCERT]);
-    }
-
-    public function testCertOptionWithPassword(): void
-    {
-        $file = __FILE__;
-
-        $this->request->request('get', 'http://example.com', [
-            'cert' => [
-                $file,
-                'password',
-            ],
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_SSLCERT, $options);
-        $this->assertSame($file, $options[CURLOPT_SSLCERT]);
-
-        $this->assertArrayHasKey(CURLOPT_SSLCERTPASSWD, $options);
-        $this->assertSame('password', $options[CURLOPT_SSLCERTPASSWD]);
-    }
-
-    public function testMissingCertOption(): void
-    {
-        $file = 'something_obviously_bogus';
-        $this->expectException(HTTPException::class);
-
-        $this->request->request('get', 'http://example.com', [
-            'cert' => $file,
-        ]);
-    }
-
-    public function testSSLVerification(): void
-    {
-        $file = __FILE__;
-
-        $this->request->request('get', 'http://example.com', [
-            'verify' => $file,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_CAINFO, $options);
-        $this->assertSame($file, $options[CURLOPT_CAINFO]);
-
-        $this->assertArrayHasKey(CURLOPT_SSL_VERIFYPEER, $options);
-        $this->assertTrue($options[CURLOPT_SSL_VERIFYPEER]);
-
-        $this->assertArrayHasKey(CURLOPT_SSL_VERIFYHOST, $options);
-        $this->assertSame(2, $options[CURLOPT_SSL_VERIFYHOST]);
-    }
-
-    public function testSSLWithBadKey(): void
-    {
-        $file = 'something_obviously_bogus';
-        $this->expectException(HTTPException::class);
-
-        $this->request->request('get', 'http://example.com', [
-            'verify' => $file,
-        ]);
-    }
-
-    public function testProxyuOption()
-    {
-        $this->request->request('get', 'http://example.com', [
-            'proxy' => 'http://localhost:3128',
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_PROXY, $options);
-        $this->assertSame('http://localhost:3128', $options[CURLOPT_PROXY]);
-        $this->assertArrayHasKey(CURLOPT_HTTPPROXYTUNNEL, $options);
-        $this->assertTrue($options[CURLOPT_HTTPPROXYTUNNEL]);
-    }
-
-    public function testDebugOptionTrue(): void
-    {
-        $this->request->request('get', 'http://example.com', [
-            'debug' => true,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_VERBOSE, $options);
-        $this->assertSame(1, $options[CURLOPT_VERBOSE]);
-
-        $this->assertArrayHasKey(CURLOPT_STDERR, $options);
-        $this->assertIsResource($options[CURLOPT_STDERR]);
-    }
-
-    public function testDebugOptionFalse(): void
-    {
-        $this->request->request('get', 'http://example.com', [
-            'debug' => false,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayNotHasKey(CURLOPT_VERBOSE, $options);
-        $this->assertArrayNotHasKey(CURLOPT_STDERR, $options);
-    }
-
-    public function testDebugOptionFile(): void
-    {
-        $file = SUPPORTPATH . 'Files/baker/banana.php';
-
-        $this->request->request('get', 'http://example.com', [
-            'debug' => $file,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_VERBOSE, $options);
-        $this->assertSame(1, $options[CURLOPT_VERBOSE]);
-
-        $this->assertArrayHasKey(CURLOPT_STDERR, $options);
-        $this->assertIsResource($options[CURLOPT_STDERR]);
-    }
-
-    public function testDecodeContent(): void
-    {
-        $this->request->setHeader('Accept-Encoding', 'cobol');
-        $this->request->request('get', 'http://example.com', [
-            'decode_content' => true,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_ENCODING, $options);
-        $this->assertSame('cobol', $options[CURLOPT_ENCODING]);
-    }
-
-    public function testDecodeContentWithoutAccept(): void
-    {
-        //      $this->request->setHeader('Accept-Encoding', 'cobol');
-        $this->request->request('get', 'http://example.com', [
-            'decode_content' => true,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_ENCODING, $options);
-        $this->assertSame('', $options[CURLOPT_ENCODING]);
-        $this->assertArrayHasKey(CURLOPT_HTTPHEADER, $options);
-        $this->assertSame('Accept-Encoding', $options[CURLOPT_HTTPHEADER]);
-    }
-
-    public function testAllowRedirectsOptionFalse(): void
-    {
-        $this->request->request('get', 'http://example.com', [
-            'allow_redirects' => false,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_FOLLOWLOCATION, $options);
-        $this->assertSame(0, $options[CURLOPT_FOLLOWLOCATION]);
-
-        $this->assertArrayNotHasKey(CURLOPT_MAXREDIRS, $options);
-        $this->assertArrayNotHasKey(CURLOPT_REDIR_PROTOCOLS, $options);
-    }
-
-    public function testAllowRedirectsOptionTrue(): void
-    {
-        $this->request->request('get', 'http://example.com', [
-            'allow_redirects' => true,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_FOLLOWLOCATION, $options);
-        $this->assertSame(1, $options[CURLOPT_FOLLOWLOCATION]);
-
-        $this->assertArrayHasKey(CURLOPT_MAXREDIRS, $options);
-        $this->assertSame(5, $options[CURLOPT_MAXREDIRS]);
-        $this->assertArrayHasKey(CURLOPT_REDIR_PROTOCOLS, $options);
-        $this->assertSame(CURLPROTO_HTTP | CURLPROTO_HTTPS, $options[CURLOPT_REDIR_PROTOCOLS]);
-    }
-
-    public function testAllowRedirectsOptionDefaults(): void
-    {
-        $this->request->request('get', 'http://example.com', [
-            'allow_redirects' => true,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_FOLLOWLOCATION, $options);
-        $this->assertSame(1, $options[CURLOPT_FOLLOWLOCATION]);
-
-        $this->assertArrayHasKey(CURLOPT_MAXREDIRS, $options);
-        $this->assertArrayHasKey(CURLOPT_REDIR_PROTOCOLS, $options);
-    }
-
-    public function testAllowRedirectsArray(): void
-    {
-        $this->request->request('get', 'http://example.com', [
-            'allow_redirects' => ['max' => 2],
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_FOLLOWLOCATION, $options);
-        $this->assertSame(1, $options[CURLOPT_FOLLOWLOCATION]);
-
-        $this->assertArrayHasKey(CURLOPT_MAXREDIRS, $options);
-        $this->assertSame(2, $options[CURLOPT_MAXREDIRS]);
-    }
-
-    public function testSendWithQuery(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'query'    => [
-                'name' => 'Henry',
-                'd.t'  => 'value',
-            ],
-        ]);
-
-        $request->get('products');
-
-        $options = $request->curl_options;
-
-        $this->assertSame('http://www.foo.com/api/v1/products?name=Henry&d.t=value', $options[CURLOPT_URL]);
-    }
-
-    public function testSendWithDelay(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-
-        $request->get('products');
-
-        // we still need to check the code coverage to make sure this was done
-        $this->assertEqualsWithDelta(0.1, $request->getDelay(), PHP_FLOAT_EPSILON);
-    }
-
-    public function testSendContinued(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-
-        $request->setOutput("HTTP/1.1 100 Continue\x0d\x0a\x0d\x0aHi there");
-        $response = $request->get('answer');
-        $this->assertSame('Hi there', $response->getBody());
-    }
-
-    /**
-     * See: https://github.com/codeigniter4/CodeIgniter4/issues/3261
-     */
-    public function testSendContinuedWithManyHeaders(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-
-        $output = "HTTP/1.1 100 Continue
-Server: ddos-guard
-Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT\x0d\x0a\x0d\x0aHTTP/1.1 200 OK
-Server: ddos-guard
-Connection: keep-alive
-Keep-Alive: timeout=60
-Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-Date: Tue, 07 Jul 2020 15:13:14 GMT
-Expires: Thu, 19 Nov 1981 08:52:00 GMT
-Cache-Control: no-store, no-cache, must-revalidate
-Pragma: no-cache
-Set-Cookie: PHPSESSID=80pd3hlg38mvjnelpvokp9lad0; path=/
-Content-Type: application/xml; charset=utf-8
-Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Update success! config</title>";
-        $request->setOutput($output);
-
-        $response = $request->get('answer');
-
-        $this->assertSame('<title>Update success! config</title>', $response->getBody());
-
-        $responseHeaderKeys = [
-            'Cache-Control',
-            'Content-Type',
-            'Server',
-            'Connection',
-            'Keep-Alive',
-            'Set-Cookie',
-            'Date',
-            'Expires',
-            'Pragma',
-            'Transfer-Encoding',
-        ];
-        $this->assertSame($responseHeaderKeys, array_keys($response->headers()));
-
-        $this->assertSame(200, $response->getStatusCode());
-    }
-
-    /**
-     * See: https://github.com/codeigniter4/CodeIgniter4/issues/7394
-     */
-    public function testResponseHeadersWithMultipleRequests(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-        ]);
-
-        $output = "HTTP/2.0 200 OK
-Server: ddos-guard
-Expires: Thu, 19 Nov 1981 08:52:00 GMT
-Cache-Control: no-store, no-cache, must-revalidate
-Pragma: no-cache
-Content-Type: application/xml; charset=utf-8
-Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Hello1</title>";
-        $request->setOutput($output);
-
-        $response = $request->get('answer1');
-
-        $this->assertSame('<title>Hello1</title>', $response->getBody());
-
-        $responseHeaderKeys = [
-            'Cache-Control',
-            'Content-Type',
-            'Server',
-            'Expires',
-            'Pragma',
-            'Transfer-Encoding',
-        ];
-        $this->assertSame($responseHeaderKeys, array_keys($response->headers()));
-
-        $this->assertSame(200, $response->getStatusCode());
-
-        $output = "HTTP/2.0 200 OK
-Expires: Thu, 19 Nov 1982 08:52:00 GMT
-Cache-Control: no-store, no-cache, must-revalidate
-Content-Type: application/xml; charset=utf-8
-Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Hello2</title>";
-        $request->setOutput($output);
-
-        $response = $request->get('answer2');
-
-        $this->assertSame('<title>Hello2</title>', $response->getBody());
-
-        $responseHeaderKeys = [
-            'Cache-Control',
-            'Content-Type',
-            'Expires',
-            'Transfer-Encoding',
-        ];
-        $this->assertSame($responseHeaderKeys, array_keys($response->headers()));
-
-        $this->assertSame(200, $response->getStatusCode());
-    }
-
-    public function testResponseHeadersWithMultipleSetCookies(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'https://github.com/',
-        ]);
-
-        $output = "HTTP/2 200
-server: GitHub.com
-date: Sat, 11 Nov 2023 02:26:55 GMT
-content-type: text/html; charset=utf-8
-set-cookie: _gh_sess=PlRlha1YumlLhLuo5MuNbIWJRO9RRuR%2FHfYsWRh5B0mkalFIZstlAbTmSstl8q%2FAC57IsWMVuFHWQc6L4qDHQJrwhuYVO5ZaigPCUjAStnhh%2FieZQVqIf92Al7vusuzx2o8XH%2Fv6nd9qzMTAWc2%2FkRsl8jxPQYGNaWeuUBY2w3%2FDORSikN4c0vHOyedhU7Xcv3Ryz5xD3DNxK9R8xKNZ6OSXLJ6bjX8iIT6LxvroVIf2HjvowW9cQsq0kN08mS6KtTnH0mD3ANWqsVVWeMzFNA%3D%3D--Jx830Q9Nmkfz9OGA--kEcPtNphvjNMopYqFDxUbw%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
-set-cookie: _octo=GH1.1.599292127.1699669625; Path=/; Domain=github.com; Expires=Mon, 11 Nov 2024 02:27:05 GMT; Secure; SameSite=Lax
-set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Mon, 11 Nov 2024 02:27:05 GMT; HttpOnly; Secure; SameSite=Lax
-accept-ranges: bytes\x0d\x0a\x0d\x0a";
-        $request->setOutput($output);
-
-        $response = $request->get('/');
-
-        $setCookieHeaders = $response->header('set-cookie');
-
-        $this->assertCount(3, $setCookieHeaders);
-        $this->assertSame(
-            'logged_in=no; Path=/; Domain=github.com; Expires=Mon, 11 Nov 2024 02:27:05 GMT; HttpOnly; Secure; SameSite=Lax',
-            $setCookieHeaders[2]->getValue()
-        );
-
-        $this->assertSame(
-            '_octo=GH1.1.599292127.1699669625; Path=/; Domain=github.com; Expires=Mon, 11 Nov 2024 02:27:05 GMT; Secure; SameSite=Lax',
-            $setCookieHeaders[1]->getValueLine()
-        );
-    }
-
-    public function testSplitResponse(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-
-        $request->setOutput("Accept: text/html\x0d\x0a\x0d\x0aHi there");
-        $response = $request->get('answer');
-        $this->assertSame('Hi there', $response->getBody());
-    }
-
-    public function testApplyBody(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-
-        $request->setBody('name=George');
-        $request->setOutput('Hi there');
-        $response = $request->post('answer');
-
-        $this->assertSame('Hi there', $response->getBody());
-        $this->assertSame('name=George', $request->curl_options[CURLOPT_POSTFIELDS]);
-    }
-
-    public function testApplyBodyByOptions(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-
-        $request->setOutput('Hi there');
-        $response = $request->post('answer', [
-            'body' => 'name=George',
-        ]);
-
-        $this->assertSame('Hi there', $response->getBody());
-        $this->assertSame('name=George', $request->curl_options[CURLOPT_POSTFIELDS]);
-    }
-
-    public function testBodyIsResetOnSecondRequest(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-        $request->setBody('name=George');
-        $request->setOutput('Hi there');
-
-        $request->post('answer');
-        $request->post('answer');
-
-        $this->assertArrayNotHasKey(CURLOPT_POSTFIELDS, $request->curl_options);
-    }
-
-    public function testResponseHeaders(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-
-        $request->setOutput("HTTP/2.0 234 Ohoh\x0d\x0aAccept: text/html\x0d\x0a\x0d\x0aHi there");
-        $response = $request->get('bogus');
-
-        $this->assertSame('2.0', $response->getProtocolVersion());
-        $this->assertSame(234, $response->getStatusCode());
-    }
-
-    public function testResponseHeadersShortProtocol(): void
-    {
-        $request = $this->getRequest([
-            'base_uri' => 'http://www.foo.com/api/v1/',
-            'delay'    => 100,
-        ]);
-
-        $request->setOutput("HTTP/2 235 Ohoh\x0d\x0aAccept: text/html\x0d\x0a\x0d\x0aHi there shortie");
-        $response = $request->get('bogus');
-
-        $this->assertSame('2.0', $response->getProtocolVersion());
-        $this->assertSame(235, $response->getStatusCode());
-    }
-
-    public function testPostFormEncoded(): void
-    {
-        $params = [
-            'foo' => 'bar',
-            'baz' => [
-                'hi',
-                'there',
-            ],
-        ];
-        $this->request->request('POST', '/post', [
-            'form_params' => $params,
-        ]);
-
-        $this->assertSame('POST', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $expected = http_build_query($params);
-        $this->assertArrayHasKey(CURLOPT_POSTFIELDS, $options);
-        $this->assertSame($expected, $options[CURLOPT_POSTFIELDS]);
-    }
-
-    public function testPostFormMultipart(): void
-    {
-        $params = [
-            'foo' => 'bar',
-            'baz' => [
-                'hi',
-                'there',
-            ],
-            'afile' => new CURLFile(__FILE__),
-        ];
-        $this->request->request('POST', '/post', [
-            'multipart' => $params,
-        ]);
-
-        $this->assertSame('POST', $this->request->getMethod());
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_POSTFIELDS, $options);
-        $this->assertSame($params, $options[CURLOPT_POSTFIELDS]);
-    }
-
-    public function testSetForm(): void
-    {
-        $params = [
-            'foo' => 'bar',
-            'baz' => [
-                'hi',
-                'there',
-            ],
-        ];
-
-        $this->request->setForm($params)->post('/post');
-
-        $this->assertSame(
-            http_build_query($params),
-            $this->request->curl_options[CURLOPT_POSTFIELDS]
-        );
-
-        $params['afile'] = new CURLFile(__FILE__);
-
-        $this->request->setForm($params, true)->post('/post');
-
-        $this->assertSame(
-            $params,
-            $this->request->curl_options[CURLOPT_POSTFIELDS]
-        );
-    }
-
-    public function testJSONData(): void
-    {
-        $params = [
-            'foo' => 'bar',
-            'baz' => [
-                'hi',
-                'there',
-            ],
-        ];
-        $this->request->request('POST', '/post', [
-            'json' => $params,
-        ]);
-
-        $this->assertSame('POST', $this->request->getMethod());
-
-        $expected = json_encode($params);
-        $this->assertSame(
-            $expected,
-            $this->request->curl_options[CURLOPT_POSTFIELDS]
-        );
-    }
-
-    public function testSetJSON(): void
-    {
-        $params = [
-            'foo' => 'bar',
-            'baz' => [
-                'hi',
-                'there',
-            ],
-        ];
-        $this->request->setJSON($params)->post('/post');
-
-        $expected = json_encode($params);
-        $this->assertSame(
-            $expected,
-            $this->request->curl_options[CURLOPT_POSTFIELDS]
-        );
-
-        $this->assertSame(
-            'Content-Type: application/json',
-            $this->request->curl_options[CURLOPT_HTTPHEADER][0]
-        );
-    }
-
-    public function testHTTPv1(): void
-    {
-        $this->request->request('POST', '/post', [
-            'version' => 1.0,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_HTTP_VERSION, $options);
-        $this->assertSame(CURL_HTTP_VERSION_1_0, $options[CURLOPT_HTTP_VERSION]);
-    }
-
-    public function testHTTPv11(): void
-    {
-        $this->request->request('POST', '/post', [
-            'version' => 1.1,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_HTTP_VERSION, $options);
-        $this->assertSame(CURL_HTTP_VERSION_1_1, $options[CURLOPT_HTTP_VERSION]);
-    }
-
-    public function testCookieOption(): void
-    {
-        $holder = SUPPORTPATH . 'HTTP/Files/CookiesHolder.txt';
-        $this->request->request('POST', '/post', [
-            'cookie' => $holder,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_COOKIEJAR, $options);
-        $this->assertSame($holder, $options[CURLOPT_COOKIEJAR]);
-        $this->assertArrayHasKey(CURLOPT_COOKIEFILE, $options);
-        $this->assertSame($holder, $options[CURLOPT_COOKIEFILE]);
-    }
-
-    public function testUserAgentOption(): void
-    {
-        $agent = 'CodeIgniter Framework';
-
-        $this->request->request('POST', '/post', [
-            'user_agent' => $agent,
-        ]);
-
-        $options = $this->request->curl_options;
-
-        $this->assertArrayHasKey(CURLOPT_USERAGENT, $options);
-        $this->assertSame($agent, $options[CURLOPT_USERAGENT]);
-    }
-}
diff --git a/tests/system/HTTP/CURLRequestShareOptionsTest.php b/tests/system/HTTP/CURLRequestShareOptionsTest.php
new file mode 100644
index 000000000000..bb0216466787
--- /dev/null
+++ b/tests/system/HTTP/CURLRequestShareOptionsTest.php
@@ -0,0 +1,76 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of CodeIgniter 4 framework.
+ *
+ * (c) CodeIgniter Foundation <admin@codeigniter.com>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace CodeIgniter\HTTP;
+
+use CodeIgniter\Config\Factories;
+use CodeIgniter\Test\Mock\MockCURLRequest;
+use Config\App;
+use Config\CURLRequest as ConfigCURLRequest;
+
+/**
+ * This test case is for the case where shareOptions is true.
+ * The shareOptions should be set to false.
+ *
+ * @internal
+ *
+ * @group Others
+ */
+final class CURLRequestShareOptionsTest extends CURLRequestTest
+{
+    protected function getRequest(array $options = []): MockCURLRequest
+    {
+        $uri = isset($options['base_uri']) ? new URI($options['base_uri']) : new URI();
+        $app = new App();
+
+        $config               = new ConfigCURLRequest();
+        $config->shareOptions = true;
+        Factories::injectMock('config', 'CURLRequest', $config);
+
+        return new MockCURLRequest(($app), $uri, new Response($app), $options);
+    }
+
+    public function testHeaderContentLengthNotSharedBetweenRequests(): void
+    {
+        $options = [
+            'base_uri' => 'http://www.foo.com/api/v1/',
+        ];
+        $request = $this->getRequest($options);
+
+        $request->post('example', [
+            'form_params' => [
+                'q' => 'keyword',
+            ],
+        ]);
+        $request->get('example');
+
+        // The Content-Length header is shared!
+        $this->assertSame('9', $request->header('Content-Length')->getValue());
+    }
+
+    public function testBodyIsResetOnSecondRequest(): void
+    {
+        $request = $this->getRequest([
+            'base_uri' => 'http://www.foo.com/api/v1/',
+            'delay'    => 100,
+        ]);
+        $request->setBody('name=George');
+        $request->setOutput('Hi there');
+
+        $request->post('answer');
+        $request->post('answer');
+
+        // The body is not reset!
+        $this->assertArrayHasKey(CURLOPT_POSTFIELDS, $request->curl_options);
+    }
+}
diff --git a/tests/system/HTTP/CURLRequestTest.php b/tests/system/HTTP/CURLRequestTest.php
index 6b51b4d585f4..1f53a57a8465 100644
--- a/tests/system/HTTP/CURLRequestTest.php
+++ b/tests/system/HTTP/CURLRequestTest.php
@@ -26,10 +26,12 @@
  * @internal
  *
  * @group Others
+ *
+ * @no-final
  */
-final class CURLRequestTest extends CIUnitTestCase
+class CURLRequestTest extends CIUnitTestCase
 {
-    private CURLRequest $request;
+    protected MockCURLRequest $request;
 
     protected function setUp(): void
     {
@@ -39,13 +41,16 @@ protected function setUp(): void
         $this->request = $this->getRequest();
     }
 
-    protected function getRequest(array $options = [])
+    /**
+     * @param array<string, mixed> $options
+     */
+    protected function getRequest(array $options = []): MockCURLRequest
     {
         $uri = isset($options['base_uri']) ? new URI($options['base_uri']) : new URI();
         $app = new App();
 
         $config               = new ConfigCURLRequest();
-        $config->shareOptions = true;
+        $config->shareOptions = false;
         Factories::injectMock('config', 'CURLRequest', $config);
 
         return new MockCURLRequest(($app), $uri, new Response($app), $options);
@@ -205,7 +210,7 @@ public function testOptionsHeadersNotUsingPopulate(): void
         $this->assertSame('', $request->header('Accept-Encoding')->getValue());
     }
 
-    public function testOptionsAreSharedBetweenRequests(): void
+    public function testDefaultOptionsAreSharedBetweenRequests(): void
     {
         $options = [
             'form_params' => ['studio' => 1],
@@ -226,6 +231,23 @@ public function testOptionsAreSharedBetweenRequests(): void
         $this->assertSame('CodeIgniter Framework v4', $request->curl_options[CURLOPT_USERAGENT]);
     }
 
+    public function testHeaderContentLengthNotSharedBetweenRequests(): void
+    {
+        $options = [
+            'base_uri' => 'http://www.foo.com/api/v1/',
+        ];
+        $request = $this->getRequest($options);
+
+        $request->post('example', [
+            'form_params' => [
+                'q' => 'keyword',
+            ],
+        ]);
+        $request->get('example');
+
+        $this->assertNull($request->header('Content-Length'));
+    }
+
     /**
      * @backupGlobals enabled
      */
@@ -387,20 +409,20 @@ public function testAuthBasicOptionExplicit(): void
     public function testAuthDigestOption(): void
     {
         $output = "HTTP/1.1 401 Unauthorized
-		Server: ddos-guard
-		Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-		WWW-Authenticate: Digest\x0d\x0a\x0d\x0aHTTP/1.1 200 OK
-		Server: ddos-guard
-		Connection: keep-alive
-		Keep-Alive: timeout=60
-		Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-		Date: Tue, 07 Jul 2020 15:13:14 GMT
-		Expires: Thu, 19 Nov 1981 08:52:00 GMT
-		Cache-Control: no-store, no-cache, must-revalidate
-		Pragma: no-cache
-		Set-Cookie: PHPSESSID=80pd3hlg38mvjnelpvokp9lad0; path=/
-		Content-Type: application/xml; charset=utf-8
-		Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Update success! config</title>";
+Server: ddos-guard
+Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
+WWW-Authenticate: Digest\x0d\x0a\x0d\x0aHTTP/1.1 200 OK
+Server: ddos-guard
+Connection: keep-alive
+Keep-Alive: timeout=60
+Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
+Date: Tue, 07 Jul 2020 15:13:14 GMT
+Expires: Thu, 19 Nov 1981 08:52:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Pragma: no-cache
+Set-Cookie: PHPSESSID=80pd3hlg38mvjnelpvokp9lad0; path=/
+Content-Type: application/xml; charset=utf-8
+Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Update success! config</title>";
 
         $this->request->setOutput($output);
 
@@ -440,20 +462,20 @@ public function testSetAuthBasic(): void
     public function testSetAuthDigest(): void
     {
         $output = "HTTP/1.1 401 Unauthorized
-		Server: ddos-guard
-		Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-		WWW-Authenticate: Digest\x0d\x0a\x0d\x0aHTTP/1.1 200 OK
-		Server: ddos-guard
-		Connection: keep-alive
-		Keep-Alive: timeout=60
-		Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
-		Date: Tue, 07 Jul 2020 15:13:14 GMT
-		Expires: Thu, 19 Nov 1981 08:52:00 GMT
-		Cache-Control: no-store, no-cache, must-revalidate
-		Pragma: no-cache
-		Set-Cookie: PHPSESSID=80pd3hlg38mvjnelpvokp9lad0; path=/
-		Content-Type: application/xml; charset=utf-8
-		Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Update success! config</title>";
+Server: ddos-guard
+Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
+WWW-Authenticate: Digest\x0d\x0a\x0d\x0aHTTP/1.1 200 OK
+Server: ddos-guard
+Connection: keep-alive
+Keep-Alive: timeout=60
+Set-Cookie: __ddg1=z177j4mLtqzC07v0zviU; Domain=.site.ru; HttpOnly; Path=/; Expires=Wed, 07-Jul-2021 15:13:14 GMT
+Date: Tue, 07 Jul 2020 15:13:14 GMT
+Expires: Thu, 19 Nov 1981 08:52:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Pragma: no-cache
+Set-Cookie: PHPSESSID=80pd3hlg38mvjnelpvokp9lad0; path=/
+Content-Type: application/xml; charset=utf-8
+Transfer-Encoding: chunked\x0d\x0a\x0d\x0a<title>Update success! config</title>";
 
         $this->request->setOutput($output);
 
@@ -560,7 +582,7 @@ public function testSSLWithBadKey(): void
         ]);
     }
 
-    public function testProxyuOption()
+    public function testProxyuOption(): void
     {
         $this->request->request('get', 'http://example.com', [
             'proxy' => 'http://localhost:3128',
@@ -782,7 +804,6 @@ public function testSendContinuedWithManyHeaders(): void
 
         $responseHeaderKeys = [
             'Cache-Control',
-            'Content-Type',
             'Server',
             'Connection',
             'Keep-Alive',
@@ -790,6 +811,7 @@ public function testSendContinuedWithManyHeaders(): void
             'Date',
             'Expires',
             'Pragma',
+            'Content-Type',
             'Transfer-Encoding',
         ];
         $this->assertSame($responseHeaderKeys, array_keys($response->headers()));
@@ -836,10 +858,10 @@ public function testResponseHeadersWithMultipleRequests(): void
 
         $responseHeaderKeys = [
             'Cache-Control',
-            'Content-Type',
             'Server',
             'Expires',
             'Pragma',
+            'Content-Type',
             'Transfer-Encoding',
         ];
         $this->assertSame($responseHeaderKeys, array_keys($response->headers()));
@@ -859,8 +881,8 @@ public function testResponseHeadersWithMultipleRequests(): void
 
         $responseHeaderKeys = [
             'Cache-Control',
-            'Content-Type',
             'Expires',
+            'Content-Type',
             'Transfer-Encoding',
         ];
         $this->assertSame($responseHeaderKeys, array_keys($response->headers()));
@@ -868,6 +890,38 @@ public function testResponseHeadersWithMultipleRequests(): void
         $this->assertSame(200, $response->getStatusCode());
     }
 
+    public function testResponseHeadersWithMultipleSetCookies(): void
+    {
+        $request = $this->getRequest([
+            'base_uri' => 'https://github.com/',
+        ]);
+
+        $output = "HTTP/2 200
+server: GitHub.com
+date: Sat, 11 Nov 2023 02:26:55 GMT
+content-type: text/html; charset=utf-8
+set-cookie: _gh_sess=PlRlha1YumlLhLuo5MuNbIWJRO9RRuR%2FHfYsWRh5B0mkalFIZstlAbTmSstl8q%2FAC57IsWMVuFHWQc6L4qDHQJrwhuYVO5ZaigPCUjAStnhh%2FieZQVqIf92Al7vusuzx2o8XH%2Fv6nd9qzMTAWc2%2FkRsl8jxPQYGNaWeuUBY2w3%2FDORSikN4c0vHOyedhU7Xcv3Ryz5xD3DNxK9R8xKNZ6OSXLJ6bjX8iIT6LxvroVIf2HjvowW9cQsq0kN08mS6KtTnH0mD3ANWqsVVWeMzFNA%3D%3D--Jx830Q9Nmkfz9OGA--kEcPtNphvjNMopYqFDxUbw%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
+set-cookie: _octo=GH1.1.599292127.1699669625; Path=/; Domain=github.com; Expires=Mon, 11 Nov 2024 02:27:05 GMT; Secure; SameSite=Lax
+set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Mon, 11 Nov 2024 02:27:05 GMT; HttpOnly; Secure; SameSite=Lax
+accept-ranges: bytes\x0d\x0a\x0d\x0a";
+        $request->setOutput($output);
+
+        $response = $request->get('/');
+
+        $setCookieHeaders = $response->header('set-cookie');
+
+        $this->assertCount(3, $setCookieHeaders);
+        $this->assertSame(
+            'logged_in=no; Path=/; Domain=github.com; Expires=Mon, 11 Nov 2024 02:27:05 GMT; HttpOnly; Secure; SameSite=Lax',
+            $setCookieHeaders[2]->getValue()
+        );
+
+        $this->assertSame(
+            '_octo=GH1.1.599292127.1699669625; Path=/; Domain=github.com; Expires=Mon, 11 Nov 2024 02:27:05 GMT; Secure; SameSite=Lax',
+            $setCookieHeaders[1]->getValueLine()
+        );
+    }
+
     public function testSplitResponse(): void
     {
         $request = $this->getRequest([
@@ -911,6 +965,21 @@ public function testApplyBodyByOptions(): void
         $this->assertSame('name=George', $request->curl_options[CURLOPT_POSTFIELDS]);
     }
 
+    public function testBodyIsResetOnSecondRequest(): void
+    {
+        $request = $this->getRequest([
+            'base_uri' => 'http://www.foo.com/api/v1/',
+            'delay'    => 100,
+        ]);
+        $request->setBody('name=George');
+        $request->setOutput('Hi there');
+
+        $request->post('answer');
+        $request->post('answer');
+
+        $this->assertArrayNotHasKey(CURLOPT_POSTFIELDS, $request->curl_options);
+    }
+
     public function testResponseHeaders(): void
     {
         $request = $this->getRequest([
@@ -1026,7 +1095,10 @@ public function testJSONData(): void
         $this->assertSame('POST', $this->request->getMethod());
 
         $expected = json_encode($params);
-        $this->assertSame($expected, $this->request->getBody());
+        $this->assertSame(
+            $expected,
+            $this->request->curl_options[CURLOPT_POSTFIELDS]
+        );
     }
 
     public function testSetJSON(): void
@@ -1040,7 +1112,11 @@ public function testSetJSON(): void
         ];
         $this->request->setJSON($params)->post('/post');
 
-        $this->assertSame(json_encode($params), $this->request->getBody());
+        $expected = json_encode($params);
+        $this->assertSame(
+            $expected,
+            $this->request->curl_options[CURLOPT_POSTFIELDS]
+        );
         $this->assertSame(
             'Content-Type: application/json',
             $this->request->curl_options[CURLOPT_HTTPHEADER][0]
@@ -1137,4 +1213,21 @@ public function testMultipleHTTP100(): void
 
         $this->assertSame(200, $response->getStatusCode());
     }
+
+    public function testGetHeaderLineContentType(): void
+    {
+        $output = 'HTTP/2 200
+date: Thu, 11 Apr 2024 07:26:00 GMT
+content-type: text/html; charset=UTF-8
+cache-control: no-store, max-age=0, no-cache
+server: cloudflare
+content-encoding: br
+alt-svc: h3=":443"; ma=86400' . "\x0d\x0a\x0d\x0aResponse Body";
+
+        $this->request->setOutput($output);
+
+        $response = $this->request->request('get', 'http://example.com');
+
+        $this->assertSame('text/html; charset=UTF-8', $response->getHeaderLine('Content-Type'));
+    }
 }
diff --git a/tests/system/HTTP/Files/FileCollectionTest.php b/tests/system/HTTP/Files/FileCollectionTest.php
index d2bd760b0cab..3b565156aa6b 100644
--- a/tests/system/HTTP/Files/FileCollectionTest.php
+++ b/tests/system/HTTP/Files/FileCollectionTest.php
@@ -455,7 +455,7 @@ public function testErrorWithNoError(): void
         $this->assertSame(UPLOAD_ERR_OK, $file->getError());
     }
 
-    public function testClientPathReturnsValidFullPath()
+    public function testClientPathReturnsValidFullPath(): void
     {
         $_FILES = [
             'userfile' => [
@@ -473,7 +473,7 @@ public function testClientPathReturnsValidFullPath()
         $this->assertSame('someDir/someFile.txt', $file->getClientPath());
     }
 
-    public function testClientPathReturnsNullWhenFullPathIsNull()
+    public function testClientPathReturnsNullWhenFullPathIsNull(): void
     {
         $_FILES = [
             'userfile' => [
diff --git a/tests/system/HTTP/IncomingRequestTest.php b/tests/system/HTTP/IncomingRequestTest.php
index 7060af62f31f..e0d827523405 100644
--- a/tests/system/HTTP/IncomingRequestTest.php
+++ b/tests/system/HTTP/IncomingRequestTest.php
@@ -223,7 +223,7 @@ public function testSetBadLocale(): void
         $this->assertSame('es', $request->getLocale());
     }
 
-    public function testSetValidLocales()
+    public function testSetValidLocales(): void
     {
         $config                   = new App();
         $config->supportedLocales = ['en', 'es'];
diff --git a/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php b/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php
index b5f1b4d1099d..f6386b858165 100644
--- a/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php
+++ b/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php
@@ -43,7 +43,7 @@ private function createSiteURIFactory(array $server, ?App $appConfig = null): Si
         return new SiteURIFactory($appConfig, $superglobals);
     }
 
-    public function testDefault()
+    public function testDefault(): void
     {
         // /index.php/woot?code=good#pos
         $_SERVER['REQUEST_URI'] = '/index.php/woot';
@@ -55,7 +55,7 @@ public function testDefault()
         $this->assertSame($expected, $factory->detectRoutePath());
     }
 
-    public function testDefaultEmpty()
+    public function testDefaultEmpty(): void
     {
         // /
         $_SERVER['REQUEST_URI'] = '/';
@@ -67,7 +67,7 @@ public function testDefaultEmpty()
         $this->assertSame($expected, $factory->detectRoutePath());
     }
 
-    public function testRequestURI()
+    public function testRequestURI(): void
     {
         // /index.php/woot?code=good#pos
         $_SERVER['REQUEST_URI'] = '/index.php/woot';
@@ -79,7 +79,7 @@ public function testRequestURI()
         $this->assertSame($expected, $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURINested()
+    public function testRequestURINested(): void
     {
         // I'm not sure but this is a case of Apache config making such SERVER
         // values?
@@ -99,7 +99,7 @@ public function testRequestURINested()
         $this->assertSame($expected, $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURISubfolder()
+    public function testRequestURISubfolder(): void
     {
         // /ci/index.php/popcorn/woot?code=good#pos
         $_SERVER['REQUEST_URI'] = '/ci/index.php/popcorn/woot';
@@ -111,7 +111,7 @@ public function testRequestURISubfolder()
         $this->assertSame($expected, $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURINoIndex()
+    public function testRequestURINoIndex(): void
     {
         // /sub/example
         $_SERVER['REQUEST_URI'] = '/sub/example';
@@ -123,7 +123,7 @@ public function testRequestURINoIndex()
         $this->assertSame($expected, $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURINginx()
+    public function testRequestURINginx(): void
     {
         // /ci/index.php/woot?code=good#pos
         $_SERVER['REQUEST_URI'] = '/index.php/woot?code=good';
@@ -135,7 +135,7 @@ public function testRequestURINginx()
         $this->assertSame($expected, $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURINginxRedirecting()
+    public function testRequestURINginxRedirecting(): void
     {
         // /?/ci/index.php/woot
         $_SERVER['REQUEST_URI'] = '/?/ci/woot';
@@ -147,7 +147,7 @@ public function testRequestURINginxRedirecting()
         $this->assertSame($expected, $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURISuppressed()
+    public function testRequestURISuppressed(): void
     {
         // /woot?code=good#pos
         $_SERVER['REQUEST_URI'] = '/woot';
@@ -159,7 +159,7 @@ public function testRequestURISuppressed()
         $this->assertSame($expected, $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURIGetPath()
+    public function testRequestURIGetPath(): void
     {
         // /index.php/fruits/banana
         $_SERVER['REQUEST_URI'] = '/index.php/fruits/banana';
@@ -170,7 +170,7 @@ public function testRequestURIGetPath()
         $this->assertSame('fruits/banana', $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURIPathIsRelative()
+    public function testRequestURIPathIsRelative(): void
     {
         // /sub/folder/index.php/fruits/banana
         $_SERVER['REQUEST_URI'] = '/sub/folder/index.php/fruits/banana';
@@ -181,7 +181,7 @@ public function testRequestURIPathIsRelative()
         $this->assertSame('fruits/banana', $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURIStoresDetectedPath()
+    public function testRequestURIStoresDetectedPath(): void
     {
         // /fruits/banana
         $_SERVER['REQUEST_URI'] = '/fruits/banana';
@@ -194,7 +194,7 @@ public function testRequestURIStoresDetectedPath()
         $this->assertSame('fruits/banana', $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testRequestURIPathIsNeverRediscovered()
+    public function testRequestURIPathIsNeverRediscovered(): void
     {
         $_SERVER['REQUEST_URI'] = '/fruits/banana';
         $_SERVER['SCRIPT_NAME'] = '/index.php';
@@ -207,7 +207,7 @@ public function testRequestURIPathIsNeverRediscovered()
         $this->assertSame('fruits/banana', $factory->detectRoutePath('REQUEST_URI'));
     }
 
-    public function testQueryString()
+    public function testQueryString(): void
     {
         // /index.php?/ci/woot
         $_SERVER['REQUEST_URI']  = '/index.php?/ci/woot';
@@ -222,7 +222,7 @@ public function testQueryString()
         $this->assertSame($expected, $factory->detectRoutePath('QUERY_STRING'));
     }
 
-    public function testQueryStringWithQueryString()
+    public function testQueryStringWithQueryString(): void
     {
         // /index.php?/ci/woot?code=good#pos
         $_SERVER['REQUEST_URI']  = '/index.php?/ci/woot?code=good';
@@ -239,7 +239,7 @@ public function testQueryStringWithQueryString()
         $this->assertSame(['code' => 'good'], $_GET);
     }
 
-    public function testQueryStringEmpty()
+    public function testQueryStringEmpty(): void
     {
         // /index.php?
         $_SERVER['REQUEST_URI'] = '/index.php?';
@@ -251,7 +251,7 @@ public function testQueryStringEmpty()
         $this->assertSame($expected, $factory->detectRoutePath('QUERY_STRING'));
     }
 
-    public function testPathInfoUnset()
+    public function testPathInfoUnset(): void
     {
         // /index.php/woot?code=good#pos
         $_SERVER['REQUEST_URI'] = '/index.php/woot';
@@ -263,7 +263,7 @@ public function testPathInfoUnset()
         $this->assertSame($expected, $factory->detectRoutePath('PATH_INFO'));
     }
 
-    public function testPathInfoSubfolder()
+    public function testPathInfoSubfolder(): void
     {
         $appConfig          = new App();
         $appConfig->baseURL = 'http://localhost:8888/ci431/public/';
@@ -285,7 +285,7 @@ public function testPathInfoSubfolder()
      * @param string $path
      * @param string $detectPath
      */
-    public function testExtensionPHP($path, $detectPath)
+    public function testExtensionPHP($path, $detectPath): void
     {
         $config          = new App();
         $config->baseURL = 'http://example.com/';
diff --git a/tests/system/HTTP/SiteURIFactoryTest.php b/tests/system/HTTP/SiteURIFactoryTest.php
index 594ce63d08ec..9b0a55d20b5f 100644
--- a/tests/system/HTTP/SiteURIFactoryTest.php
+++ b/tests/system/HTTP/SiteURIFactoryTest.php
@@ -41,7 +41,7 @@ private function createSiteURIFactory(?App $config = null, ?Superglobals $superg
         return new SiteURIFactory($config, $superglobals);
     }
 
-    public function testCreateFromGlobals()
+    public function testCreateFromGlobals(): void
     {
         // http://localhost:8080/index.php/woot?code=good#pos
         $_SERVER['REQUEST_URI']  = '/index.php/woot?code=good';
@@ -62,7 +62,7 @@ public function testCreateFromGlobals()
         $this->assertSame('woot', $uri->getRoutePath());
     }
 
-    public function testCreateFromGlobalsAllowedHost()
+    public function testCreateFromGlobalsAllowedHost(): void
     {
         // http://users.example.jp/index.php/woot?code=good#pos
         $_SERVER['REQUEST_URI']  = '/index.php/woot?code=good';
@@ -95,7 +95,7 @@ public function testCreateFromStringWithIndexPage(
         string $expectUriString,
         string $expectedPath,
         string $expectedRoutePath
-    ) {
+    ): void {
         $factory = $this->createSiteURIFactory();
 
         $uri = $factory->createFromString($uriString);
@@ -138,7 +138,7 @@ public function testCreateFromStringWithoutIndexPage(
         string $expectUriString,
         string $expectedPath,
         string $expectedRoutePath
-    ) {
+    ): void {
         $config            = new App();
         $config->indexPage = '';
         $factory           = $this->createSiteURIFactory($config);
diff --git a/tests/system/HTTP/SiteURITest.php b/tests/system/HTTP/SiteURITest.php
index 26a3102e1fea..80deeddc2879 100644
--- a/tests/system/HTTP/SiteURITest.php
+++ b/tests/system/HTTP/SiteURITest.php
@@ -42,7 +42,7 @@ public function testConstructor(
         string $expectedFragment,
         array $expectedSegments,
         int $expectedTotalSegments
-    ) {
+    ): void {
         $config            = new App();
         $config->indexPage = $indexPage;
         $config->baseURL   = $baseURL;
@@ -270,7 +270,7 @@ public static function provideRelativePathWithQueryOrFragment(): iterable
         ];
     }
 
-    public function testConstructorHost()
+    public function testConstructorHost(): void
     {
         $config                   = new App();
         $config->allowedHostnames = ['sub.example.com'];
@@ -284,7 +284,7 @@ public function testConstructorHost()
         $this->assertSame('http://sub.example.com/', $uri->getBaseURL());
     }
 
-    public function testConstructorScheme()
+    public function testConstructorScheme(): void
     {
         $config = new App();
 
@@ -295,7 +295,7 @@ public function testConstructorScheme()
         $this->assertSame('https://example.com/', $uri->getBaseURL());
     }
 
-    public function testConstructorEmptyScheme()
+    public function testConstructorEmptyScheme(): void
     {
         $config = new App();
 
@@ -306,7 +306,7 @@ public function testConstructorEmptyScheme()
         $this->assertSame('http://example.com/', $uri->getBaseURL());
     }
 
-    public function testConstructorForceGlobalSecureRequests()
+    public function testConstructorForceGlobalSecureRequests(): void
     {
         $config                            = new App();
         $config->forceGlobalSecureRequests = true;
@@ -317,7 +317,7 @@ public function testConstructorForceGlobalSecureRequests()
         $this->assertSame('https://example.com/', $uri->getBaseURL());
     }
 
-    public function testConstructorInvalidBaseURL()
+    public function testConstructorInvalidBaseURL(): void
     {
         $this->expectException(ConfigException::class);
 
@@ -341,7 +341,7 @@ public function testSetPath(
         string $expectedFragment,
         array $expectedSegments,
         int $expectedTotalSegments
-    ) {
+    ): void {
         $config            = new App();
         $config->indexPage = $indexPage;
         $config->baseURL   = $baseURL;
@@ -361,7 +361,7 @@ public function testSetPath(
         $this->assertSame($expectedTotalSegments, $uri->getTotalSegments());
     }
 
-    public function testSetSegment()
+    public function testSetSegment(): void
     {
         $config = new App();
 
@@ -378,7 +378,7 @@ public function testSetSegment()
         $this->assertSame(2, $uri->getTotalSegments());
     }
 
-    public function testSetSegmentOutOfRange()
+    public function testSetSegmentOutOfRange(): void
     {
         $this->expectException(HTTPException::class);
 
@@ -389,7 +389,7 @@ public function testSetSegmentOutOfRange()
         $uri->setSegment(4, 'four');
     }
 
-    public function testSetSegmentSilentOutOfRange()
+    public function testSetSegmentSilentOutOfRange(): void
     {
         $config = new App();
         $uri    = new SiteURI($config);
@@ -400,7 +400,7 @@ public function testSetSegmentSilentOutOfRange()
         $this->assertSame(['one', 'method'], $uri->getSegments());
     }
 
-    public function testSetSegmentZero()
+    public function testSetSegmentZero(): void
     {
         $this->expectException(HTTPException::class);
 
@@ -411,7 +411,7 @@ public function testSetSegmentZero()
         $uri->setSegment(0, 'four');
     }
 
-    public function testSetSegmentSubfolder()
+    public function testSetSegmentSubfolder(): void
     {
         $config          = new App();
         $config->baseURL = 'http://example.com/ci4/';
@@ -429,7 +429,7 @@ public function testSetSegmentSubfolder()
         $this->assertSame(2, $uri->getTotalSegments());
     }
 
-    public function testGetRoutePath()
+    public function testGetRoutePath(): void
     {
         $config = new App();
         $uri    = new SiteURI($config);
@@ -437,7 +437,7 @@ public function testGetRoutePath()
         $this->assertSame('', $uri->getRoutePath());
     }
 
-    public function testGetSegments()
+    public function testGetSegments(): void
     {
         $config = new App();
         $uri    = new SiteURI($config);
@@ -445,7 +445,7 @@ public function testGetSegments()
         $this->assertSame([], $uri->getSegments());
     }
 
-    public function testGetSegmentZero()
+    public function testGetSegmentZero(): void
     {
         $this->expectException(HTTPException::class);
 
@@ -456,7 +456,7 @@ public function testGetSegmentZero()
         $uri->getSegment(0);
     }
 
-    public function testGetSegmentOutOfRange()
+    public function testGetSegmentOutOfRange(): void
     {
         $this->expectException(HTTPException::class);
 
@@ -467,7 +467,7 @@ public function testGetSegmentOutOfRange()
         $uri->getSegment(4);
     }
 
-    public function testGetTotalSegments()
+    public function testGetTotalSegments(): void
     {
         $config = new App();
         $uri    = new SiteURI($config);
@@ -475,7 +475,7 @@ public function testGetTotalSegments()
         $this->assertSame(0, $uri->getTotalSegments());
     }
 
-    public function testSetURI()
+    public function testSetURI(): void
     {
         $this->expectException(BadMethodCallException::class);
 
@@ -485,7 +485,7 @@ public function testSetURI()
         $uri->setURI('http://another.site.example.jp/');
     }
 
-    public function testSetBaseURI()
+    public function testSetBaseURI(): void
     {
         $this->expectException(BadMethodCallException::class);
 
@@ -495,7 +495,7 @@ public function testSetBaseURI()
         $uri->setBaseURL('http://another.site.example.jp/');
     }
 
-    public function testGetBaseURL()
+    public function testGetBaseURL(): void
     {
         $config = new App();
         $uri    = new SiteURI($config);
diff --git a/tests/system/HTTP/URITest.php b/tests/system/HTTP/URITest.php
index 41780ebb7ec4..0211d6d2e1f9 100644
--- a/tests/system/HTTP/URITest.php
+++ b/tests/system/HTTP/URITest.php
@@ -242,7 +242,7 @@ public function testSetSchemeSetsValue(): void
         $this->assertSame($expected, (string) $uri);
     }
 
-    public function testWithScheme()
+    public function testWithScheme(): void
     {
         $url = 'example.com';
         $uri = new URI('http://' . $url);
@@ -253,7 +253,7 @@ public function testWithScheme()
         $this->assertSame('http://' . $url, (string) $uri);
     }
 
-    public function testWithSchemeSetsHttps()
+    public function testWithSchemeSetsHttps(): void
     {
         $url = 'http://example.com/path';
         $uri = new URI($url);
@@ -269,7 +269,7 @@ public function testWithSchemeSetsHttps()
         $this->assertSame($expected, (string) $uri);
     }
 
-    public function testWithSchemeSetsEmpty()
+    public function testWithSchemeSetsEmpty(): void
     {
         $url = 'example.com';
         $uri = new URI('http://' . $url);
diff --git a/tests/system/Helpers/FormHelperTest.php b/tests/system/Helpers/FormHelperTest.php
index 2ee32da768fc..b623068943fe 100644
--- a/tests/system/Helpers/FormHelperTest.php
+++ b/tests/system/Helpers/FormHelperTest.php
@@ -52,25 +52,40 @@ private function setRequest(): void
         Services::injectMock('request', $request);
     }
 
+    private function setCsrfFilter(): void
+    {
+        $filters                      = config(Filters::class);
+        $filters->globals['before'][] = 'csrf';
+        service('filters')->initialize();
+    }
+
     public function testFormOpenBasic(): void
     {
         $this->setRequest();
 
-        $before = (new Filters())->globals['before'];
-        if (in_array('csrf', $before, true) || array_key_exists('csrf', $before)) {
-            $Value    = csrf_hash();
-            $Name     = csrf_token();
-            $expected = <<<EOH
-                <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" accept-charset="utf-8">
-                <input type="hidden" name="{$Name}" value="{$Value}" style="display:none;">
+        $expected = <<<'EOH'
+            <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" accept-charset="utf-8">
+
+            EOH;
+        $attributes = [
+            'name'   => 'form',
+            'id'     => 'form',
+            'method' => 'POST',
+        ];
+        $this->assertSame($expected, form_open('foo/bar', $attributes));
+    }
 
-                EOH;
-        } else {
-            $expected = <<<'EOH'
-                <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" accept-charset="utf-8">
+    public function testFormOpenBasicWithCsrf(): void
+    {
+        $this->setRequest();
+        $this->setCsrfFilter();
 
-                EOH;
-        }
+        $value    = csrf_hash();
+        $name     = csrf_token();
+        $expected = <<<EOH
+            <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" accept-charset="utf-8">
+            <input type="hidden" name="{$name}" value="{$value}">
+            EOH;
 
         $attributes = [
             'name'   => 'form',
@@ -101,21 +116,29 @@ public function testFormOpenWithoutAction(): void
     {
         $this->setRequest();
 
-        $before = (new Filters())->globals['before'];
-        if (in_array('csrf', $before, true) || array_key_exists('csrf', $before)) {
-            $Value    = csrf_hash();
-            $Name     = csrf_token();
-            $expected = <<<EOH
-                <form action="http://example.com/index.php" name="form" id="form" method="POST" accept-charset="utf-8">
-                <input type="hidden" name="{$Name}" value="{$Value}" style="display:none;">
-
-                EOH;
-        } else {
-            $expected = <<<'EOH'
-                <form action="http://example.com/index.php" name="form" id="form" method="POST" accept-charset="utf-8">
-
-                EOH;
-        }
+        $expected = <<<'EOH'
+            <form action="http://example.com/index.php" name="form" id="form" method="POST" accept-charset="utf-8">
+
+            EOH;
+        $attributes = [
+            'name'   => 'form',
+            'id'     => 'form',
+            'method' => 'POST',
+        ];
+        $this->assertSame($expected, form_open('', $attributes));
+    }
+
+    public function testFormOpenWithoutActionWithCsrf(): void
+    {
+        $this->setRequest();
+        $this->setCsrfFilter();
+
+        $value    = csrf_hash();
+        $name     = csrf_token();
+        $expected = <<<EOH
+            <form action="http://example.com/index.php" name="form" id="form" method="POST" accept-charset="utf-8">
+            <input type="hidden" name="{$name}" value="{$value}">
+            EOH;
         $attributes = [
             'name'   => 'form',
             'id'     => 'form',
@@ -128,22 +151,29 @@ public function testFormOpenWithoutMethod(): void
     {
         $this->setRequest();
 
-        $before = (new Filters())->globals['before'];
-        if (in_array('csrf', $before, true) || array_key_exists('csrf', $before)) {
-            $Value    = csrf_hash();
-            $Name     = csrf_token();
-            $expected = <<<EOH
-                <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="post" accept-charset="utf-8">
-                <input type="hidden" name="{$Name}" value="{$Value}" style="display:none;">
+        $expected = <<<'EOH'
+            <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="post" accept-charset="utf-8">
 
-                EOH;
-        } else {
-            $expected = <<<'EOH'
-                <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="post" accept-charset="utf-8">
+            EOH;
 
-                EOH;
-        }
+        $attributes = [
+            'name' => 'form',
+            'id'   => 'form',
+        ];
+        $this->assertSame($expected, form_open('foo/bar', $attributes));
+    }
 
+    public function testFormOpenWithoutMethodWithCsrf(): void
+    {
+        $this->setRequest();
+        $this->setCsrfFilter();
+
+        $value    = csrf_hash();
+        $name     = csrf_token();
+        $expected = <<<EOH
+            <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="post" accept-charset="utf-8">
+            <input type="hidden" name="{$name}" value="{$value}">
+            EOH;
         $attributes = [
             'name' => 'form',
             'id'   => 'form',
@@ -155,25 +185,36 @@ public function testFormOpenWithHidden(): void
     {
         $this->setRequest();
 
-        $before = (new Filters())->globals['before'];
-        if (in_array('csrf', $before, true) || array_key_exists('csrf', $before)) {
-            $Value    = csrf_hash();
-            $Name     = csrf_token();
-            $expected = <<<EOH
-                <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" accept-charset="utf-8">
-                <input type="hidden" name="foo" value="bar">
-                <input type="hidden" name="{$Name}" value="{$Value}">
+        $expected = <<<'EOH'
+            <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" accept-charset="utf-8">
 
-                EOH;
-        } else {
-            $expected = <<<'EOH'
-                <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" accept-charset="utf-8">
+            <input type="hidden" name="foo" value="bar">
 
-                <input type="hidden" name="foo" value="bar">
+            EOH;
+        $attributes = [
+            'name'   => 'form',
+            'id'     => 'form',
+            'method' => 'POST',
+        ];
+        $hidden = [
+            'foo' => 'bar',
+        ];
+        $this->assertSame($expected, form_open('foo/bar', $attributes, $hidden));
+    }
 
-                EOH;
-        }
+    public function testFormOpenWithHiddenWithCsrf(): void
+    {
+        $this->setRequest();
+        $this->setCsrfFilter();
+
+        $value    = csrf_hash();
+        $name     = csrf_token();
+        $expected = <<<EOH
+            <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" accept-charset="utf-8">
+            <input type="hidden" name="{$name}" value="{$value}">
+            <input type="hidden" name="foo" value="bar">
 
+            EOH;
         $attributes = [
             'name'   => 'form',
             'id'     => 'form',
@@ -189,21 +230,33 @@ public function testFormOpenMultipart(): void
     {
         $this->setRequest();
 
-        $before = (new Filters())->globals['before'];
-        if (in_array('csrf', $before, true) || array_key_exists('csrf', $before)) {
-            $Value    = csrf_hash();
-            $Name     = csrf_token();
-            $expected = <<<EOH
-                <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
-                <input type="hidden" name="{$Name}" value="{$Value}" style="display:none;">
-
-                EOH;
-        } else {
-            $expected = <<<'EOH'
-                <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
-
-                EOH;
-        }
+        $expected = <<<'EOH'
+            <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
+
+            EOH;
+        $attributes = [
+            'name'   => 'form',
+            'id'     => 'form',
+            'method' => 'POST',
+        ];
+        $this->assertSame($expected, form_open_multipart('foo/bar', $attributes));
+
+        // make sure it works with attributes as a string too
+        $attributesString = 'name="form" id="form" method="POST"';
+        $this->assertSame($expected, form_open_multipart('foo/bar', $attributesString));
+    }
+
+    public function testFormOpenMultipartWithCsrf(): void
+    {
+        $this->setRequest();
+        $this->setCsrfFilter();
+
+        $value    = csrf_hash();
+        $name     = csrf_token();
+        $expected = <<<EOH
+            <form action="http://example.com/index.php/foo/bar" name="form" id="form" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
+            <input type="hidden" name="{$name}" value="{$value}">
+            EOH;
         $attributes = [
             'name'   => 'form',
             'id'     => 'form',
@@ -267,7 +320,7 @@ public function testFormInput(): void
         $this->assertSame($expected, form_input($data));
     }
 
-    public function testFormInputXHTML(): void
+    public function testFormInputXhtml(): void
     {
         $this->disableHtml5();
 
@@ -287,14 +340,14 @@ public function testFormInputXHTML(): void
         $this->enableHtml5();
     }
 
-    private function disableHtml5()
+    private function disableHtml5(): void
     {
         $doctypes        = new DocTypes();
         $doctypes->html5 = false;
         _solidus($doctypes);
     }
 
-    private function enableHtml5()
+    private function enableHtml5(): void
     {
         $doctypes = new DocTypes();
         _solidus($doctypes);
@@ -332,7 +385,7 @@ public function testFormUpload(): void
         $this->assertSame($expected, form_upload('attachment'));
     }
 
-    public function testFormUploadXHTML(): void
+    public function testFormUploadXhtml(): void
     {
         $this->disableHtml5();
 
@@ -668,7 +721,7 @@ public function testFormCheckbox(): void
         $this->assertSame($expected, form_checkbox('newsletter', 'accept', true));
     }
 
-    public function testFormCheckboxXHTML(): void
+    public function testFormCheckboxXhtml(): void
     {
         $this->disableHtml5();
 
diff --git a/tests/system/Helpers/HTMLHelperTest.php b/tests/system/Helpers/HTMLHelperTest.php
index 0fc05a77ea91..ecce00af6783 100755
--- a/tests/system/Helpers/HTMLHelperTest.php
+++ b/tests/system/Helpers/HTMLHelperTest.php
@@ -218,14 +218,14 @@ public function testIMGXHTML(): void
         $this->enableHtml5();
     }
 
-    private function disableHtml5()
+    private function disableHtml5(): void
     {
         $doctypes        = new DocTypes();
         $doctypes->html5 = false;
         _solidus($doctypes);
     }
 
-    private function enableHtml5()
+    private function enableHtml5(): void
     {
         $doctypes = new DocTypes();
         _solidus($doctypes);
diff --git a/tests/system/Helpers/URLHelper/MiscUrlTest.php b/tests/system/Helpers/URLHelper/MiscUrlTest.php
index 6670b9fec4d2..1a15bb4c1fac 100644
--- a/tests/system/Helpers/URLHelper/MiscUrlTest.php
+++ b/tests/system/Helpers/URLHelper/MiscUrlTest.php
@@ -940,7 +940,7 @@ public function testUrlToWithNamedRouteWithNestedParentheses(): void
             'version' => 'master|\d+\.(?:\d+|x)',
             'page'    => '[a-z0-9-]+',
         ]);
-        $routes->get('docs/(:version)/(:page)', static function () {
+        $routes->get('docs/(:version)/(:page)', static function (): void {
             echo 'Test the documentation segment';
         }, ['as' => 'docs.version']);
 
diff --git a/tests/system/HotReloader/DirectoryHasherTest.php b/tests/system/HotReloader/DirectoryHasherTest.php
index 5ec7d02f9974..4df7e69fd924 100644
--- a/tests/system/HotReloader/DirectoryHasherTest.php
+++ b/tests/system/HotReloader/DirectoryHasherTest.php
@@ -32,7 +32,7 @@ protected function setUp(): void
         $this->hasher = new DirectoryHasher();
     }
 
-    public function testHashApp()
+    public function testHashApp(): void
     {
         $results = $this->hasher->hashApp();
 
@@ -40,7 +40,7 @@ public function testHashApp()
         $this->assertArrayHasKey('app', $results);
     }
 
-    public function testHashDirectoryInvalid()
+    public function testHashDirectoryInvalid(): void
     {
         $this->expectException(FrameworkException::class);
         $this->expectExceptionMessage('Directory does not exist: "' . APPPATH . 'Foo"');
@@ -48,7 +48,7 @@ public function testHashDirectoryInvalid()
         $this->hasher->hashDirectory(APPPATH . 'Foo');
     }
 
-    public function testUniqueHashes()
+    public function testUniqueHashes(): void
     {
         $hash1 = $this->hasher->hashDirectory(APPPATH);
         $hash2 = $this->hasher->hashDirectory(SYSTEMPATH);
@@ -56,7 +56,7 @@ public function testUniqueHashes()
         $this->assertNotSame($hash1, $hash2);
     }
 
-    public function testRepeatableHashes()
+    public function testRepeatableHashes(): void
     {
         $hash1 = $this->hasher->hashDirectory(APPPATH);
         $hash2 = $this->hasher->hashDirectory(APPPATH);
@@ -64,7 +64,7 @@ public function testRepeatableHashes()
         $this->assertSame($hash1, $hash2);
     }
 
-    public function testHash()
+    public function testHash(): void
     {
         $expected = md5(implode('', $this->hasher->hashApp()));
 
diff --git a/tests/system/I18n/TimeLegacyTest.php b/tests/system/I18n/TimeLegacyTest.php
index 8f0fec545e47..f966e3750ce9 100644
--- a/tests/system/I18n/TimeLegacyTest.php
+++ b/tests/system/I18n/TimeLegacyTest.php
@@ -1130,7 +1130,7 @@ public function testGetter(): void
         $this->assertNull($time->weekOfWeek);
     }
 
-    public function testUnserializeTimeObject()
+    public function testUnserializeTimeObject(): void
     {
         $time1     = new TimeLegacy('August 28, 2020 10:04:00pm', 'Asia/Manila', 'en');
         $timeCache = serialize($time1);
diff --git a/tests/system/I18n/TimeTest.php b/tests/system/I18n/TimeTest.php
index b81c8ae299af..8e85e8cff3e3 100644
--- a/tests/system/I18n/TimeTest.php
+++ b/tests/system/I18n/TimeTest.php
@@ -1137,7 +1137,7 @@ public function testGetter(): void
         $this->assertNull($time->weekOfWeek);
     }
 
-    public function testUnserializeTimeObject()
+    public function testUnserializeTimeObject(): void
     {
         $time1     = new Time('August 28, 2020 10:04:00pm', 'Asia/Manila', 'en');
         $timeCache = serialize($time1);
diff --git a/tests/system/Models/WhenWhenNotModelTest.php b/tests/system/Models/WhenWhenNotModelTest.php
index 003ccd02244d..3039fc0b57b5 100644
--- a/tests/system/Models/WhenWhenNotModelTest.php
+++ b/tests/system/Models/WhenWhenNotModelTest.php
@@ -42,7 +42,7 @@ public function testWhenWithTrueCondition(): void
 
         $this->createModel(SecondaryModel::class)->insertBatch($secondaryData);
 
-        $result = $this->model->when($filter, static function ($query, $filter) {
+        $result = $this->model->when($filter, static function ($query, $filter): void {
             $query->where('value', $filter);
         })->find();
 
@@ -71,9 +71,9 @@ public function testWhenWithFalseConditionAndDefaultCallback(): void
 
         $this->createModel(SecondaryModel::class)->insertBatch($secondaryData);
 
-        $result = $this->model->when($filter, static function ($query, $filter) {
+        $result = $this->model->when($filter, static function ($query, $filter): void {
             $query->where('value', $filter);
-        }, static function ($query) {
+        }, static function ($query): void {
             $query->where('value', 'foobar');
         })->find();
 
@@ -102,7 +102,7 @@ public function testWhenNotWithFalseCondition(): void
 
         $this->createModel(SecondaryModel::class)->insertBatch($secondaryData);
 
-        $result = $this->model->whenNot($filter, static function ($query, $filter) {
+        $result = $this->model->whenNot($filter, static function ($query, $filter): void {
             $query->where('value !=', 'foobar');
         })->find();
 
@@ -131,9 +131,9 @@ public function testWhenNotWithTrueConditionAndDefaultCallback(): void
 
         $this->createModel(SecondaryModel::class)->insertBatch($secondaryData);
 
-        $result = $this->model->whenNot($filter, static function ($query, $filter) {
+        $result = $this->model->whenNot($filter, static function ($query, $filter): void {
             $query->where('value !=', 'foobar');
-        }, static function ($query) {
+        }, static function ($query): void {
             $query->where('value', 'foobar');
         })->find();
 
diff --git a/tests/system/Router/AutoRouterImprovedTest.php b/tests/system/Router/AutoRouterImprovedTest.php
index 1441e2ca49e9..6c531db06a8b 100644
--- a/tests/system/Router/AutoRouterImprovedTest.php
+++ b/tests/system/Router/AutoRouterImprovedTest.php
@@ -75,7 +75,7 @@ public function testAutoRouteFindsDefaultControllerAndMethodGet(): void
         ], $router->getPos());
     }
 
-    public function testAutoRouteFindsModuleDefaultControllerAndMethodGet()
+    public function testAutoRouteFindsModuleDefaultControllerAndMethodGet(): void
     {
         $config               = config(Routing::class);
         $config->moduleRoutes = [
@@ -190,7 +190,7 @@ public function testAutoRouteFindsControllerWithSubfolder(): void
         ], $router->getPos());
     }
 
-    public function testAutoRouteFindsControllerWithSubSubfolder()
+    public function testAutoRouteFindsControllerWithSubSubfolder(): void
     {
         $router = $this->createNewAutoRouter();
 
@@ -258,7 +258,7 @@ public function testAutoRouteFindsDefaultDashFolder(): void
         $this->assertSame([], $params);
     }
 
-    public function testAutoRouteFallbackToDefaultMethod()
+    public function testAutoRouteFallbackToDefaultMethod(): void
     {
         $router = $this->createNewAutoRouter();
 
@@ -276,7 +276,7 @@ public function testAutoRouteFallbackToDefaultMethod()
         ], $router->getPos());
     }
 
-    public function testAutoRouteFallbackToDefaultControllerOneParam()
+    public function testAutoRouteFallbackToDefaultControllerOneParam(): void
     {
         $router = $this->createNewAutoRouter();
 
@@ -294,7 +294,7 @@ public function testAutoRouteFallbackToDefaultControllerOneParam()
         ], $router->getPos());
     }
 
-    public function testAutoRouteFallbackToDefaultControllerTwoParams()
+    public function testAutoRouteFallbackToDefaultControllerTwoParams(): void
     {
         $router = $this->createNewAutoRouter();
 
@@ -312,7 +312,7 @@ public function testAutoRouteFallbackToDefaultControllerTwoParams()
         ], $router->getPos());
     }
 
-    public function testAutoRouteFallbackToDefaultControllerNoParams()
+    public function testAutoRouteFallbackToDefaultControllerNoParams(): void
     {
         $router = $this->createNewAutoRouter();
 
@@ -396,7 +396,7 @@ public function testRejectsControllerWithRemapMethod(): void
         $router->getRoute('remap/test', Method::GET);
     }
 
-    public function testRejectsURIWithUnderscoreFolder()
+    public function testRejectsURIWithUnderscoreFolder(): void
     {
         $this->expectException(PageNotFoundException::class);
         $this->expectExceptionMessage(
@@ -408,7 +408,7 @@ public function testRejectsURIWithUnderscoreFolder()
         $router->getRoute('dash_folder', Method::GET);
     }
 
-    public function testRejectsURIWithUnderscoreController()
+    public function testRejectsURIWithUnderscoreController(): void
     {
         $this->expectException(PageNotFoundException::class);
         $this->expectExceptionMessage(
@@ -420,7 +420,7 @@ public function testRejectsURIWithUnderscoreController()
         $router->getRoute('dash-folder/dash_controller/dash-method', Method::GET);
     }
 
-    public function testRejectsURIWithUnderscoreMethod()
+    public function testRejectsURIWithUnderscoreMethod(): void
     {
         $this->expectException(PageNotFoundException::class);
         $this->expectExceptionMessage(
@@ -432,7 +432,7 @@ public function testRejectsURIWithUnderscoreMethod()
         $router->getRoute('dash-folder/dash-controller/dash_method', Method::GET);
     }
 
-    public function testPermitsURIWithUnderscoreParam()
+    public function testPermitsURIWithUnderscoreParam(): void
     {
         $router = $this->createNewAutoRouter();
 
@@ -445,7 +445,7 @@ public function testPermitsURIWithUnderscoreParam()
         $this->assertSame(['a_b'], $params);
     }
 
-    public function testDoesNotTranslateDashInParam()
+    public function testDoesNotTranslateDashInParam(): void
     {
         $router = $this->createNewAutoRouter();
 
@@ -469,7 +469,7 @@ public function testTranslateUriToCamelCase(
         int $controllerPos,
         ?int $methodPos,
         ?int $paramPos
-    ) {
+    ): void {
         $config                          = config(Routing::class);
         $config->translateUriToCamelCase = true;
         Factories::injectMock('config', Routing::class, $config);
@@ -535,7 +535,7 @@ public static function provideTranslateUriToCamelCase(): iterable
     /**
      * @dataProvider provideRejectTranslateUriToCamelCase
      */
-    public function testRejectTranslateUriToCamelCase(string $uri, string $expMsg)
+    public function testRejectTranslateUriToCamelCase(string $uri, string $expMsg): void
     {
         $this->expectException(PageNotFoundException::class);
         $this->expectExceptionMessage(
diff --git a/tests/system/Router/Controllers/Subfolder/Home.php b/tests/system/Router/Controllers/Subfolder/Home.php
index 9c28c2004a1b..386a86d81c66 100644
--- a/tests/system/Router/Controllers/Subfolder/Home.php
+++ b/tests/system/Router/Controllers/Subfolder/Home.php
@@ -17,7 +17,7 @@
 
 class Home extends Controller
 {
-    public function getIndex($p1 = null, $p2 = null)
+    public function getIndex($p1 = null, $p2 = null): void
     {
     }
 }
diff --git a/tests/system/Router/Controllers/Subfolder/Sub/Mycontroller.php b/tests/system/Router/Controllers/Subfolder/Sub/Mycontroller.php
index 6329369a60bb..f13003511e34 100644
--- a/tests/system/Router/Controllers/Subfolder/Sub/Mycontroller.php
+++ b/tests/system/Router/Controllers/Subfolder/Sub/Mycontroller.php
@@ -17,7 +17,7 @@
 
 class Mycontroller extends Controller
 {
-    public function getSomemethod()
+    public function getSomemethod(): void
     {
     }
 }
diff --git a/tests/system/Router/DefinedRouteCollectorTest.php b/tests/system/Router/DefinedRouteCollectorTest.php
index 7daf331340e7..779639204ded 100644
--- a/tests/system/Router/DefinedRouteCollectorTest.php
+++ b/tests/system/Router/DefinedRouteCollectorTest.php
@@ -46,7 +46,7 @@ private function createRouteCollection(array $config = [], $moduleConfig = null)
         return (new RouteCollection($loader, $moduleConfig, new Routing()))->setHTTPVerb(Method::GET);
     }
 
-    public function testCollect()
+    public function testCollect(): void
     {
         $routes = $this->createRouteCollection();
         $routes->get('journals', 'Blogs');
@@ -94,7 +94,7 @@ public function testCollect()
     /**
      * @see https://github.com/codeigniter4/CodeIgniter4/issues/8039
      */
-    public function testCollectSameFromWithDifferentVerb()
+    public function testCollectSameFromWithDifferentVerb(): void
     {
         $routes = $this->createRouteCollection();
         $routes->get('login', 'AuthController::showLogin', ['as' => 'loginShow']);
diff --git a/tests/system/Router/RouteCollectionTest.php b/tests/system/Router/RouteCollectionTest.php
index 86b3c8ba8d89..400f9a99ca29 100644
--- a/tests/system/Router/RouteCollectionTest.php
+++ b/tests/system/Router/RouteCollectionTest.php
@@ -348,12 +348,12 @@ public function testGroupNestedWithOuterOptionsWithoutInnerOptions(): void
         $routes->group(
             'admin',
             ['namespace' => 'Admin', 'filter' => ['csrf']],
-            static function ($routes) {
-                $routes->get('dashboard', static function () {
+            static function ($routes): void {
+                $routes->get('dashboard', static function (): void {
                 });
 
-                $routes->group('profile', static function ($routes) {
-                    $routes->get('/', static function () {
+                $routes->group('profile', static function ($routes): void {
+                    $routes->get('/', static function (): void {
                     });
                 });
             }
@@ -379,15 +379,15 @@ public function testGroupNestedWithOuterAndInnerOption(): void
         $routes->group(
             'admin',
             ['filter' => ['csrf']],
-            static function ($routes) {
-                $routes->get('dashboard', static function () {
+            static function ($routes): void {
+                $routes->get('dashboard', static function (): void {
                 });
 
                 $routes->group(
                     'profile',
                     ['filter' => ['honeypot']],
-                    static function ($routes) {
-                        $routes->get('/', static function () {
+                    static function ($routes): void {
+                        $routes->get('/', static function (): void {
                         });
                     }
                 );
@@ -412,15 +412,15 @@ public function testGroupNestedWithoutOuterOptionWithInnerOption(): void
         $routes->group(
             'admin',
             ['filter' => 'csrf'],
-            static function ($routes) {
-                $routes->get('dashboard', static function () {
+            static function ($routes): void {
+                $routes->get('dashboard', static function (): void {
                 });
 
                 $routes->group(
                     'profile',
                     ['namespace' => 'Admin'],
-                    static function ($routes) {
-                        $routes->get('/', static function () {
+                    static function ($routes): void {
+                        $routes->get('/', static function (): void {
                         });
                     }
                 );
diff --git a/tests/system/Security/CheckPhpIniTest.php b/tests/system/Security/CheckPhpIniTest.php
index 847f9fd82897..9028a676ca90 100644
--- a/tests/system/Security/CheckPhpIniTest.php
+++ b/tests/system/Security/CheckPhpIniTest.php
@@ -24,7 +24,7 @@
  */
 final class CheckPhpIniTest extends CIUnitTestCase
 {
-    public function testCheckIni()
+    public function testCheckIni(): void
     {
         $output = CheckPhpIni::checkIni();
 
@@ -37,7 +37,7 @@ public function testCheckIni()
         $this->assertSame($expected, $output['display_errors']);
     }
 
-    public function testRunCli()
+    public function testRunCli(): void
     {
         // Set MockInputOutput to CLI.
         $io = new MockInputOutput();
@@ -54,7 +54,7 @@ public function testRunCli()
         CLI::resetInputOutput();
     }
 
-    public function testRunWeb()
+    public function testRunWeb(): void
     {
         $output = CheckPhpIni::run(false);
 
diff --git a/tests/system/SuperglobalsTest.php b/tests/system/SuperglobalsTest.php
index ee526f230614..54ab69958ec4 100644
--- a/tests/system/SuperglobalsTest.php
+++ b/tests/system/SuperglobalsTest.php
@@ -22,7 +22,7 @@
  */
 final class SuperglobalsTest extends CIUnitTestCase
 {
-    public function testSetGet()
+    public function testSetGet(): void
     {
         $globals = new Superglobals([], []);
 
diff --git a/tests/system/Test/ControllerTestTraitTest.php b/tests/system/Test/ControllerTestTraitTest.php
index 26c356116db5..94146215bc13 100644
--- a/tests/system/Test/ControllerTestTraitTest.php
+++ b/tests/system/Test/ControllerTestTraitTest.php
@@ -272,7 +272,7 @@ public function throwsBody(): never
         $this->withBody('banana')->execute('throwsBody');
     }
 
-    public function testWithUriUpdatesUriStringAndCurrentUrlValues()
+    public function testWithUriUpdatesUriStringAndCurrentUrlValues(): void
     {
         $result = $this->withURI('http://example.com/foo/bar/1/2/3')
             ->controller(Newautorouting::class)
diff --git a/tests/system/Test/FeatureTestTraitTest.php b/tests/system/Test/FeatureTestTraitTest.php
index bab25613b805..bd746c7a9c57 100644
--- a/tests/system/Test/FeatureTestTraitTest.php
+++ b/tests/system/Test/FeatureTestTraitTest.php
@@ -99,13 +99,13 @@ public function testCallGetAndFilterReturnsResponse(): void
         $response->assertRedirectTo('login');
     }
 
-    public function testClosureWithEcho()
+    public function testClosureWithEcho(): void
     {
         $this->withRoutes([
             [
                 'GET',
                 'home',
-                static function () { echo 'test echo'; },
+                static function (): void { echo 'test echo'; },
             ],
         ]);
 
@@ -639,7 +639,7 @@ public function testSetupRequestBodyWithBody(): void
         $this->assertSame('test', $request->getBody());
     }
 
-    public function testAutoRoutingLegacy()
+    public function testAutoRoutingLegacy(): void
     {
         $config            = config(Routing::class);
         $config->autoRoute = true;
@@ -650,7 +650,7 @@ public function testAutoRoutingLegacy()
         $response->assertOK();
     }
 
-    public function testForceGlobalSecureRequests()
+    public function testForceGlobalSecureRequests(): void
     {
         $config                            = config(App::class);
         $config->forceGlobalSecureRequests = true;
diff --git a/tests/system/Validation/DotArrayFilterTest.php b/tests/system/Validation/DotArrayFilterTest.php
index abbd7011ad77..67274860ed35 100644
--- a/tests/system/Validation/DotArrayFilterTest.php
+++ b/tests/system/Validation/DotArrayFilterTest.php
@@ -22,7 +22,7 @@
  */
 final class DotArrayFilterTest extends CIUnitTestCase
 {
-    public function testRunReturnEmptyArray()
+    public function testRunReturnEmptyArray(): void
     {
         $data = [];
 
@@ -31,7 +31,7 @@ public function testRunReturnEmptyArray()
         $this->assertSame([], $result);
     }
 
-    public function testRunReturnEmptyArrayMissingValue()
+    public function testRunReturnEmptyArrayMissingValue(): void
     {
         $data = [
             'foo' => [
@@ -44,7 +44,7 @@ public function testRunReturnEmptyArrayMissingValue()
         $this->assertSame([], $result);
     }
 
-    public function testRunReturnEmptyArrayEmptyIndex()
+    public function testRunReturnEmptyArrayEmptyIndex(): void
     {
         $data = [
             'foo' => [
@@ -57,7 +57,7 @@ public function testRunReturnEmptyArrayEmptyIndex()
         $this->assertSame([], $result);
     }
 
-    public function testRunEarlyIndex()
+    public function testRunEarlyIndex(): void
     {
         $data = [
             'foo' => [
@@ -70,7 +70,7 @@ public function testRunEarlyIndex()
         $this->assertSame($data, $result);
     }
 
-    public function testRunWildcard()
+    public function testRunWildcard(): void
     {
         $data = [
             'foo' => [
@@ -85,7 +85,7 @@ public function testRunWildcard()
         $this->assertSame($data, $result);
     }
 
-    public function testRunWildcardWithMultipleChoices()
+    public function testRunWildcardWithMultipleChoices(): void
     {
         $data = [
             'foo' => [
@@ -103,7 +103,7 @@ public function testRunWildcardWithMultipleChoices()
         $this->assertSame($data, $result);
     }
 
-    public function testRunNestedNotFound()
+    public function testRunNestedNotFound(): void
     {
         $data = [
             'foo' => [
@@ -121,7 +121,7 @@ public function testRunNestedNotFound()
         $this->assertSame([], $result);
     }
 
-    public function testRunIgnoresLastWildcard()
+    public function testRunIgnoresLastWildcard(): void
     {
         $data = [
             'foo' => [
@@ -136,7 +136,7 @@ public function testRunIgnoresLastWildcard()
         $this->assertSame($data, $result);
     }
 
-    public function testRunNestedArray()
+    public function testRunNestedArray(): void
     {
         $array = [
             'user' => [
@@ -183,7 +183,7 @@ public function testRunNestedArray()
         $this->assertSame($expected, $result);
     }
 
-    public function testRunReturnOrderedIndices()
+    public function testRunReturnOrderedIndices(): void
     {
         $data = [
             'foo' => [
diff --git a/tests/system/View/ParserPluginTest.php b/tests/system/View/ParserPluginTest.php
index d0295ef387b5..9d6b97dec716 100644
--- a/tests/system/View/ParserPluginTest.php
+++ b/tests/system/View/ParserPluginTest.php
@@ -93,6 +93,10 @@ public function testLang(): void
         $template = '{+ lang Number.terabyteAbbr +}';
 
         $this->assertSame('TB', $this->parser->renderString($template));
+
+        $template = '{+ lang Time.years 2024 +}';
+
+        $this->assertSame('2,024 years', $this->parser->renderString($template));
     }
 
     public function testValidationErrors(): void
@@ -122,6 +126,10 @@ public function testSiteURL(): void
         $template = '{+ siteURL +}';
 
         $this->assertSame('http://example.com/index.php', $this->parser->renderString($template));
+
+        $template = '{+ siteURL login +}';
+
+        $this->assertSame('http://example.com/index.php/login', $this->parser->renderString($template));
     }
 
     public function testValidationErrorsList(): void
diff --git a/tests/system/View/ViewTest.php b/tests/system/View/ViewTest.php
index 18faf053a478..996db86be92a 100644
--- a/tests/system/View/ViewTest.php
+++ b/tests/system/View/ViewTest.php
@@ -390,7 +390,7 @@ public function testRenderNestedSections(): void
         $this->assertStringContainsString('<p>Third</p>', $content);
     }
 
-    public function testRenderSectionSavingData()
+    public function testRenderSectionSavingData(): void
     {
         $view     = new View($this->config, $this->viewsDir, $this->loader);
         $expected = "<title>Welcome to CodeIgniter 4!</title>\n<h1>Welcome to CodeIgniter 4!</h1>\n<p>Hello World</p>";
diff --git a/user_guide_src/source/changelogs/index.rst b/user_guide_src/source/changelogs/index.rst
index 2b8f39479236..8f5c5df8d290 100644
--- a/user_guide_src/source/changelogs/index.rst
+++ b/user_guide_src/source/changelogs/index.rst
@@ -12,6 +12,7 @@ See all the changes.
 .. toctree::
     :titlesonly:
 
+    v4.5.1
     v4.5.0
     v4.4.8
     v4.4.7
diff --git a/user_guide_src/source/changelogs/v4.5.1.rst b/user_guide_src/source/changelogs/v4.5.1.rst
new file mode 100644
index 000000000000..c2407f651ae1
--- /dev/null
+++ b/user_guide_src/source/changelogs/v4.5.1.rst
@@ -0,0 +1,19 @@
+#############
+Version 4.5.1
+#############
+
+Release Date: April 14, 2024
+
+**4.5.1 release of CodeIgniter4**
+
+.. contents::
+    :local:
+    :depth: 3
+
+**********
+Bugs Fixed
+**********
+
+See the repo's
+`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_
+for a complete list of bugs fixed.
diff --git a/user_guide_src/source/conf.py b/user_guide_src/source/conf.py
index 100b9cb012cb..1bc7efd9d0ab 100644
--- a/user_guide_src/source/conf.py
+++ b/user_guide_src/source/conf.py
@@ -26,7 +26,7 @@
 version = '4.5'
 
 # The full version, including alpha/beta/rc tags.
-release = '4.5.0'
+release = '4.5.1'
 
 # -- General configuration ---------------------------------------------------
 
diff --git a/user_guide_src/source/database/configuration/010.php b/user_guide_src/source/database/configuration/010.php
index de06d231b015..d1f89b31fa64 100644
--- a/user_guide_src/source/database/configuration/010.php
+++ b/user_guide_src/source/database/configuration/010.php
@@ -10,7 +10,7 @@ class Database extends Config
 
     // Postgre
     public array $default = [
-        'DSN' => 'Postgre://username:password@hostname:5432/database?charset=utf8&connect_timeout=5&sslmode=1',
+        'DSN' => 'Postgre://username:password@hostname:5432/database?charset=utf8&connect_timeout=5&sslmode=require',
         // ...
     ];
 
diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst
index dcbe950b2e36..bd1f011df78b 100644
--- a/user_guide_src/source/incoming/controllers.rst
+++ b/user_guide_src/source/incoming/controllers.rst
@@ -11,7 +11,7 @@ Controllers are the heart of your application, as they determine how HTTP reques
 What is a Controller?
 *********************
 
-A Controller is simply a class file that handles a HTTP request.
+A Controller is simply a class file that handles an HTTP request.
 :doc:`URI Routing <routing>` associates a URI with a controller. It returns a
 view string or ``Response`` object.
 
@@ -477,7 +477,7 @@ without route definitions. The auto-routing is disabled by default.
     Auto Routing (Legacy). It is easy to create vulnerable apps where controller filters
     or CSRF protection are bypassed.
 
-.. important:: Auto Routing (Legacy) routes a HTTP request with **any** HTTP method to a controller method.
+.. important:: Auto Routing (Legacy) routes an HTTP request with **any** HTTP method to a controller method.
 
 .. important:: Since v4.5.0, if Auto Routing (Legacy) doesn't find the controller,
     it will throw ``PageNotFoundException`` exception before the Controller Filters
diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst
index 77da04253bff..2515d1a888b9 100644
--- a/user_guide_src/source/incoming/routing.rst
+++ b/user_guide_src/source/incoming/routing.rst
@@ -122,8 +122,7 @@ Or using ``use`` keyword:
    :lines: 2-
 
 If you forget to add ``use App\Controllers\Home;``, the controller classname is
-interpreted as ``Config\Home``, not ``App\Controllers\Home`` because
-**app/Config/Routes.php** has ``namespace Config;`` at the top.
+interpreted as ``\Home``, not ``App\Controllers\Home``.
 
 .. note:: When you use Array Callable Syntax, the classname is always interpreted
     as a fully qualified classname. So :ref:`routing-default-namespace` and
@@ -815,7 +814,7 @@ Consider this URI::
 
     example.com/index.php/helloworld/hello/1
 
-In the above example, when you send a HTTP request with **GET** method,
+In the above example, when you send an HTTP request with **GET** method,
 Auto Routing would attempt to find a controller named ``App\Controllers\Helloworld``
 and executes ``getHello()`` method with passing ``'1'`` as the first argument.
 
@@ -919,7 +918,7 @@ or to use :ref:`auto-routing-improved`,
     Auto Routing (Legacy) feature. It is easy to create vulnerable apps where controller filters
     or CSRF protection are bypassed.
 
-.. important:: Auto Routing (Legacy) routes a HTTP request with **any** HTTP method to a controller method.
+.. important:: Auto Routing (Legacy) routes an HTTP request with **any** HTTP method to a controller method.
 
 Enable Auto Routing (Legacy)
 ============================
diff --git a/user_guide_src/source/installation/installing_composer.rst b/user_guide_src/source/installation/installing_composer.rst
index 7096c3d6fb73..3dd4c2a6a1b7 100644
--- a/user_guide_src/source/installation/installing_composer.rst
+++ b/user_guide_src/source/installation/installing_composer.rst
@@ -65,6 +65,35 @@ If you omit the "project-root" argument, the command will create an
     that are not needed in the production environment. This will greatly reduce
     the vendor folder size.
 
+Installing Previous Versions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, you may want to install v4.4.8 after v4.5.0 has been released.
+
+In that case, specify the version in the command:
+
+.. code-block:: console
+
+    composer create-project codeigniter4/appstarter:4.4.8 project-root
+
+Then, open **composer.json** in your project root folder, and specify
+the framework version:
+
+.. code-block:: text
+
+    "require": {
+        ...
+        "codeigniter4/framework": "4.4.8"
+    },
+
+Then, run the ``composer update`` command.
+
+.. note:: When you use a fixed version number like ``"codeigniter4/framework": "4.4.8"``
+    in your **composer.json**, ``composer update`` command will not update the
+    framework to the latest version. See `Writing Version Constraints`_ for how to specify the version.
+
+.. _Writing Version Constraints: https://getcomposer.org/doc/articles/versions.md#writing-version-constraints
+
 Initial Configuration
 ---------------------
 
@@ -82,7 +111,29 @@ Whenever there is a new release, then from the command line in your project root
 
     composer update
 
-Read the :doc:`upgrade instructions <upgrading>`, and check Breaking Changes and Enhancements.
+Read the :doc:`upgrade instructions <upgrading>` and :doc:`change log <../changelogs/index>`,
+and check Breaking Changes and Enhancements.
+
+Upgrading to a Specified Version
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, you may want to upgrade from v4.4.7 to v4.4.8 after v4.5.0 has been released.
+
+In that case, open **composer.json** in your project root folder, and specify
+the framework version:
+
+.. code-block:: text
+
+    "require": {
+        ...
+        "codeigniter4/framework": "4.4.8"
+    },
+
+Then, run the ``composer update`` command.
+
+.. note:: When you use a fixed version number like ``"codeigniter4/framework": "4.4.8"``
+    in your **composer.json**, ``composer update`` command will not update the
+    framework to the latest version. See `Writing Version Constraints`_ for how to specify the version.
 
 Pros
 ----
@@ -215,7 +266,25 @@ Whenever there is a new release, then from the command line in your project root
 
     composer update
 
-Read the :doc:`upgrade instructions <upgrading>`, and check Breaking Changes and Enhancements.
+Read the :doc:`upgrade instructions <upgrading>` and :doc:`change log <../changelogs/index>`,
+and check Breaking Changes and Enhancements.
+
+Upgrading to a Specified Version
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, you may want to upgrade from v4.4.7 to v4.4.8 after v4.5.0 has been released.
+
+In that case, open **composer.json** in your project root folder, and specify
+the framework version:
+
+.. code-block:: text
+
+    "require": {
+        ...
+        "codeigniter4/framework": "4.4.8"
+    },
+
+Then, run the ``composer update`` command.
 
 Pros
 ----
diff --git a/user_guide_src/source/installation/installing_manual.rst b/user_guide_src/source/installation/installing_manual.rst
index 8b55e375de0b..150c42ee98a1 100644
--- a/user_guide_src/source/installation/installing_manual.rst
+++ b/user_guide_src/source/installation/installing_manual.rst
@@ -42,7 +42,8 @@ Upgrading
 
 Download a new copy of the framework, and then replace the **system** folder.
 
-Read the :doc:`upgrade instructions <upgrading>`, and check Breaking Changes and Enhancements.
+Read the :doc:`upgrade instructions <upgrading>` and :doc:`change log <../changelogs/index>`,
+and check Breaking Changes and Enhancements.
 
 Pros
 ====
diff --git a/user_guide_src/source/installation/upgrade_448.rst b/user_guide_src/source/installation/upgrade_448.rst
index 5dd3da148a03..bca6e99af3df 100644
--- a/user_guide_src/source/installation/upgrade_448.rst
+++ b/user_guide_src/source/installation/upgrade_448.rst
@@ -29,6 +29,5 @@ This is a list of all files in the **project space** that received changes;
 many will be simple comments or formatting that have no effect on the runtime:
 
 - app/.htaccess
-- composer.json
 - public/.htaccess
-- tests/.htaccess
+- writable/.htaccess
diff --git a/user_guide_src/source/installation/upgrade_450.rst b/user_guide_src/source/installation/upgrade_450.rst
index 09a6b16d15b1..3c4cdc4eddbe 100644
--- a/user_guide_src/source/installation/upgrade_450.rst
+++ b/user_guide_src/source/installation/upgrade_450.rst
@@ -88,7 +88,7 @@ you would get the error response::
         'http_errors' => false,
     ]);
     $response->getStatusCode(); // In previous versions: 200
-                                //     In this verrsion: 405
+                                //      In this version: 405
 
 .. _upgrade-450-nested-route-groups-and-options:
 
@@ -227,8 +227,9 @@ for details.
 Removed Deprecated Items
 ========================
 
-Some deprecated items have been removed. If you extend these classes and are
-using them, upgrade your code. See :ref:`ChangeLog <v450-removed-deprecated-items>` for details.
+Some deprecated items have been removed. If you are still using these items, or
+extending these classes, upgrade your code. See :ref:`ChangeLog <v450-removed-deprecated-items>`
+for details.
 
 Breaking Enhancements
 *********************
@@ -322,6 +323,8 @@ Others
     - The default value of ``DBCollat`` in ``$default`` has been change to ``utf8mb4_general_ci``.
     - The default value of ``DBCollat`` in ``$tests`` has been change to ``''``.
 - app/Config/Feature.php
+    - ``Config\Feature::$oldFilterOrder`` has been added. See
+      :ref:`filter-execution-order`.
     - ``Config\Feature::$limitZeroAsAll`` has been added. See
       :ref:`v450-query-builder-limit-0-behavior`.
     - ``Config\Feature::$multipleFilters`` has been removed, because now
diff --git a/user_guide_src/source/installation/upgrade_451.rst b/user_guide_src/source/installation/upgrade_451.rst
new file mode 100644
index 000000000000..2900209474f0
--- /dev/null
+++ b/user_guide_src/source/installation/upgrade_451.rst
@@ -0,0 +1,38 @@
+#############################
+Upgrading from 4.5.0 to 4.5.1
+#############################
+
+Please refer to the upgrade instructions corresponding to your installation method.
+
+- :ref:`Composer Installation App Starter Upgrading <app-starter-upgrading>`
+- :ref:`Composer Installation Adding CodeIgniter4 to an Existing Project Upgrading <adding-codeigniter4-upgrading>`
+- :ref:`Manual Installation Upgrading <installing-manual-upgrading>`
+
+.. contents::
+    :local:
+    :depth: 2
+
+*************
+Project Files
+*************
+
+Some files in the **project space** (root, app, public, writable) received updates. Due to
+these files being outside of the **system** scope they will not be changed without your intervention.
+
+There are some third-party CodeIgniter modules available to assist with merging changes to
+the project space: `Explore on Packagist <https://packagist.org/explore/?query=codeigniter4%20updates>`_.
+
+All Changes
+===========
+
+This is a list of all files in the **project space** that received changes;
+many will be simple comments or formatting that have no effect on the runtime:
+
+- .gitignore
+- composer.json
+- phpunit.xml.dist
+- tests/.htaccess
+- tests/index.html
+- writable/debugbar/.gitkeep (Removed)
+- writable/debugbar/index.html
+- writable/index.html
diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst
index fb5fecd151a3..9e5e1730daba 100644
--- a/user_guide_src/source/installation/upgrading.rst
+++ b/user_guide_src/source/installation/upgrading.rst
@@ -16,6 +16,7 @@ See also :doc:`./backward_compatibility_notes`.
 
     backward_compatibility_notes
 
+    upgrade_451
     upgrade_450
     upgrade_448
     upgrade_447
diff --git a/user_guide_src/source/testing/fabricator/001.php b/user_guide_src/source/testing/fabricator/001.php
index 8fbf136032ca..f237d56b1324 100644
--- a/user_guide_src/source/testing/fabricator/001.php
+++ b/user_guide_src/source/testing/fabricator/001.php
@@ -6,5 +6,15 @@
 
 class MyModel implements FabricatorModel
 {
+    public function find($id = null)
+    {
+        // TODO: Implement find() method.
+    }
+
+    public function insert($row = null, bool $returnID = true)
+    {
+        // TODO: Implement insert() method.
+    }
+
     // ...
 }
diff --git a/user_guide_src/source/tutorial/static_pages/002.php b/user_guide_src/source/tutorial/static_pages/002.php
index 9bd046ec3d21..67ed7d951058 100644
--- a/user_guide_src/source/tutorial/static_pages/002.php
+++ b/user_guide_src/source/tutorial/static_pages/002.php
@@ -2,7 +2,8 @@
 
 namespace App\Controllers;
 
-use CodeIgniter\Exceptions\PageNotFoundException; // Add this line
+// Add this line to import the class.
+use CodeIgniter\Exceptions\PageNotFoundException;
 
 class Pages extends BaseController
 {
diff --git a/writable/debugbar/.gitkeep b/writable/debugbar/.gitkeep
deleted file mode 100755
index e69de29bb2d1..000000000000
diff --git a/writable/debugbar/index.html b/writable/debugbar/index.html
new file mode 100755
index 000000000000..b702fbc3967b
--- /dev/null
+++ b/writable/debugbar/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
diff --git a/writable/index.html b/writable/index.html
new file mode 100755
index 000000000000..b702fbc3967b
--- /dev/null
+++ b/writable/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>