Version 4.7.1

Release Date: March 22, 2026

4.7.1 release of CodeIgniter4

BREAKING

  • Database: CodeIgniter\Database\SQLite3\Connection::$busyTimeout is now typed as ?int. Custom subclasses that redeclare this property will need to be updated.

Message Changes

  • Updated Images.unsupportedImageCreate.

  • Renamed the Validation.valid_cc_num key to Validation.valid_cc_number.

Changes

Events

  • Worker Mode: Events::cleanupForWorkerMode() now accepts an optional $resetEventListeners array parameter, corresponding to the new $resetEventListeners property in Config\WorkerMode. This allows users to declare event names that should be cleaned up between requests when listeners are registered inside event callbacks. See Reset Event Listeners.

Others

  • builds: In the builds script (for codeigniter4/appstarter), the next argument has been added to switch 4.7.x to the next minor version 4.8.x-dev. See Latest Dev.

Bugs Fixed

  • ContentSecurityPolicy: Fixed a bug where custom CSP tags were not removed from generated HTML when CSP was disabled. The method now ensures that all custom CSP tags are removed from the generated HTML.

  • ContentSecurityPolicy: Fixed a bug where generateNonces() produces corrupted JSON responses by replacing CSP nonce placeholders with unescaped double quotes. The method now automatically JSON-escapes nonce attributes when the response Content-Type is JSON.

  • ContentSecurityPolicy: Fixed a bug where nonces generated by getScriptNonce() and getStyleNonce() were not added to the script-src-elem and style-src-elem directives, causing nonces to be silently ignored by browsers when those directives were present.

  • CURLRequest: Fixed a bug where HTTP/2 responses without a reason phrase (e.g., HTTP/2 200) were not parsed correctly, causing the status code and protocol version to be ignored.

  • Database: Fixed a bug where BaseConnection::callFunction() could double-prefix already-prefixed function names.

  • Database: Fixed a bug where BasePreparedQuery::prepare() could mis-handle SQL containing colon syntax by over-broad named-placeholder replacement. It now preserves PostgreSQL cast syntax like ::timestamp.

  • Database: Fixed a bug where string values from config arrays (including .env overrides) were not normalized for typed connection properties, which could cause SQLite3 options like synchronous and busyTimeout to be assigned with the wrong type.

  • Model: Fixed a bug where BaseModel::updateBatch() threw an exception when updateOnlyChanged was true and the index field value did not change.

  • Model: Fixed a bug where Model::chunk() ran an unnecessary extra database query at the end of iteration. chunk() now also throws InvalidArgumentException when called with a non-positive chunk size.

  • Session: Fixed a bug in MemcachedHandler where the constructor incorrectly threw an exception when savePath was not empty.

  • Testing: Fixed a bug in FeatureTestTrait::withRoutes() where invalid HTTP methods were not properly validated, thus passing them all to RouteCollection.

  • Toolbar: Fixed a bug where the standalone toolbar page loaded from ?debugbar_time=... was not interactive.

  • Toolbar: Fixed a bug in the Routes panel where only the first route parameter was converted to an input field on hover.

  • Validation: Rule valid_cc_number now has the correct translation.

  • Validation: Fixed a bug where rules did not fire for array elements missing a key when using wildcard fields (e.g., contacts.friends.*.name).

  • View: Fixed a bug where View would throw an error if the appOverridesFolder config property was not defined.

See the repo’s CHANGELOG.md for a complete list of bugs fixed.