Version 4.7.1
Release Date: March 22, 2026
4.7.1 release of CodeIgniter4
BREAKING
Database:
CodeIgniter\Database\SQLite3\Connection::$busyTimeoutis 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_numkey toValidation.valid_cc_number.
Changes
Events
Worker Mode:
Events::cleanupForWorkerMode()now accepts an optional$resetEventListenersarray parameter, corresponding to the new$resetEventListenersproperty inConfig\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
buildsscript (forcodeigniter4/appstarter), thenextargument has been added to switch4.7.xto the next minor version4.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()andgetStyleNonce()were not added to thescript-src-elemandstyle-src-elemdirectives, 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
.envoverrides) were not normalized for typed connection properties, which could cause SQLite3 options likesynchronousandbusyTimeoutto be assigned with the wrong type.Model: Fixed a bug where
BaseModel::updateBatch()threw an exception whenupdateOnlyChangedwastrueand 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 throwsInvalidArgumentExceptionwhen called with a non-positive chunk size.Session: Fixed a bug in
MemcachedHandlerwhere the constructor incorrectly threw an exception whensavePathwas not empty.Testing: Fixed a bug in
FeatureTestTrait::withRoutes()where invalid HTTP methods were not properly validated, thus passing them all toRouteCollection.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_numbernow 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
Viewwould throw an error if theappOverridesFolderconfig property was not defined.
See the repo’s CHANGELOG.md for a complete list of bugs fixed.