Release Date: Unreleased
4.7.0 release of CodeIgniter4
- Update minimal PHP requirement to
8.2.
Placeholders in the regex_match validation rule must now use double curly braces.
If you previously used single braces like regex_match[/^{placeholder}$/], you must
update it to use double braces: regex_match[/^{{placeholder}}$/].
This change was introduced to avoid ambiguity with regular expression syntax,
where single curly braces (e.g., {1,3}) are used for quantifiers.
The insertBatch() and updateBatch() methods now honor model settings like
updateOnlyChanged and allowEmptyInserts. This change ensures consistent handling
across all insert/update operations.
The insert() and insertBatch() (when useAutoIncrement is disabled), update(),
and delete() methods now validate primary key values before executing database queries.
Invalid primary key values will now throw InvalidArgumentException instead of
DatabaseException.
What changed:
Exception type: Invalid primary keys now throw
InvalidArgumentExceptionwith specific error messages instead of genericDatabaseExceptionfrom the database layer.Validation timing:
- For
update()anddelete(): Validation happens before thebeforeUpdate/beforeDeleteevents and before any database queries are executed. - For
insert()andinsertBatch()(when auto-increment is disabled): Validation happens after thebeforeInsertevent but before database queries are executed.
- For
Invalid values: The following values are now explicitly rejected as primary keys:
null(for insert when auto-increment is disabled)0(integer zero)'0'(string zero)''(empty string)trueandfalse(booleans)[](empty array)- Nested arrays (e.g.,
[[1, 2]]) - Arrays containing any of the above invalid values
Note:
RawSqlobjects are allowed as primary key values for complex scenarios where you need to use raw SQL expressions.
This change improves error reporting by providing specific validation messages (e.g., "Invalid primary key: 0 is not allowed") instead of generic database errors, and prevents invalid queries from reaching the database.
If you need to allow some of these values for the primary key, you can override the
validateID() method in your model.
The Entity::hasChanged() and Entity::syncOriginal() methods now perform deep comparison
for objects and arrays instead of shallow comparison. This means:
- Objects and arrays are now JSON-encoded and normalized for comparison, detecting changes in nested structures, object properties, and array elements.
- Enums (both
BackedEnumandUnitEnum) are properly tracked by their backing value or case name. - DateTime objects (
DateTimeInterface) are compared using their ISO 8601 representation including timezone information. - Collections (
Traversable) such asArrayObjectandArrayIteratorare converted to arrays for comparison. - Value objects with
__toString()method are compared by their string representation when properties are not accessible (fallback for objects with private properties). - Nested entities (using
toRawArray()),JsonSerializableobjects, and objects withtoArray()methods are recursively normalized for accurate change detection. - Scalar values (strings, integers, floats, booleans, null) continue to use direct comparison with an optimization when all entity attributes are scalars.
Previously, changing an object property or an array containing objects would not be detected as a change because only reference comparison was performed. Now, any modification to the internal state of objects or arrays will be properly detected. If you relied on the old shallow comparison behavior, you will need to update your code accordingly.
The Entity::toRawArray() method now properly converts arrays of entities when the $recursive
parameter is true. Previously, properties containing arrays were not recursively processed.
If you were relying on the old behavior where arrays remained unconverted, you will need to update
your code.
- Cache: The
CacheInterfacenow includes thedeleteMatching()method. If you've implemented your own caching driver from scratch, you will need to provide an implementation for this method to ensure compatibility. - Images: The
ImageHandlerInterfacenow includes a new method:clearMetadata(). If you've implemented your own handler from scratch, you will need to provide an implementation for this method to ensure compatibility.
- BaseModel: The type of the
$rowparameter for thecleanValidationRules()method has been changed from?array $row = nulltoarray $row. - PageCache: The
PageCachefilter constructor now accepts an optionalCacheconfiguration parameter:__construct(?Cache $config = null). This allows dependency injection for testing purposes. While this is technically a breaking change if you extend thePageCacheclass with your own constructor, it should not affect most users as the parameter has a default value. - Added the
SensitiveParameterattribute to various methods to conceal sensitive information from stack traces. Affected methods are: CodeIgniter\Encryption\EncrypterInterface::encrypt()CodeIgniter\Encryption\EncrypterInterface::decrypt()CodeIgniter\Encryption\Handlers\OpenSSLHandler::encrypt()CodeIgniter\Encryption\Handlers\OpenSSLHandler::decrypt()CodeIgniter\Encryption\Handlers\SodiumHandler::encrypt()CodeIgniter\Encryption\Handlers\SodiumHandler::decrypt()CodeIgniter\HTTP\CURLRequest::setAuth()CodeIgniter\HTTP\URI::setUserInfo()CodeIgniter\Security\Security::derandomize()
- Added the
- Added native types to
CacheInterfacemethods that were missing them. The following methods were updated: initialize()save()delete()increment()decrement()clean()getCacheInfo()getMetaData()
- Added native types to
- Added native return types to
CodeIgniter\Debug\Toolbarmethods: prepare(): voidrespond(): void
- Added native return types to
- BaseModel: The deprecated method
transformDataRowToArray()has been removed. - CodeIgniter: The deprecated
CodeIgniter\CodeIgniter::resolvePlatformExtensions()has been removed. - Cache: The deprecated return type
falseforCodeIgniter\Cache\CacheInterface::getMetaData()has been replaced withnulltype. - IncomingRequest: The deprecated methods has been removed:
CodeIgniter\HTTP\IncomingRequest\detectURI()CodeIgniter\HTTP\IncomingRequest\detectPath()CodeIgniter\HTTP\IncomingRequest\parseRequestURI()CodeIgniter\HTTP\IncomingRequest\parseQueryString()
- IncomingRequest: The deprecated
$configparameter has been removed fromCodeIgniter\HTTP\IncomingRequest::setPath(), and the method visibility has been changed frompublictoprivate. - Text Helper: The deprecated types in
random_string()function:basic,md5, andsha1has been removed.
- API Transformers: This new feature provides a structured way to transform data for API responses. See :ref:`API Transformers <api_transformers>` for details.
- CLI: Added
SignalTraitto provide unified handling of operating system signals in CLI commands. - Cache: Added
asyncandpersistentconfig item to Predis handler. - Cache: Added
persistentconfig item to Redis handler. - Cache: Added support for HTTP status in
ResponseCache. - Cache: Added
Config\Cache::$cacheStatusCodesto control which HTTP status codes are allowed to be cached by thePageCachefilter. Defaults to[](all status codes for backward compatibility). Recommended value:[200]to only cache successful responses. See :ref:`Setting $cacheStatusCodes <web_page_caching_cache_status_codes>` for details. - CURLRequest: Added
shareConnectionconfig item to change default share connection. - CURLRequest: Added
dns_cache_timeoutoption to change default DNS cache timeout. - CURLRequest: Added
fresh_connectoptions to enable/disable request fresh connection. - DataConverter: Added
EnumCastcaster for database and entity. - Email: Added support for choosing the SMTP authorization method. You can change it via
Config\Email::$SMTPAuthMethodoption. - Image: The
ImageMagickHandlerhas been rewritten to rely solely on the PHPimagickextension. - Image: Added
ImageMagickHandler::clearMetadata()method to remove image metadata for privacy protection. - ResponseTrait: Added
paginate`method to simplify paginated API responses. See :ref:`ResponseTrait::paginate() <api_response_trait_paginate>` for details. - Time: added methods
Time::addCalendarMonths()andTime::subCalendarMonths() - Time: Added
Time::isPast()andTime::isFuture()convenience methods. See :ref:`isPast <time-comparing-two-times-isPast>` and :ref:`isFuture <time-comparing-two-times-isFuture>` for details.
- Exception Logging: All DB drivers now log database exceptions uniformly. Previously, each driver had its own log format.
- MigrationRunner: Added distributed locking support to prevent concurrent migrations in multi-process environments. Enable with
Config\Migrations::$lock = true.
- UserAgents: Expanded the list of recognized
robotswith new search engine and service crawlers.
- Controller Attributes: Added support for PHP Attributes to define filters and other metadata on controller classes and methods. See :ref:`Controller Attributes <incoming/controller_attributes>` for details.
- Added
Email.invalidSMTPAuthMethod,Email.failureSMTPAuthMethod,CLI.signals.noPcntlExtension,CLI.signals.noPosixExtensionandCLI.signals.failedSignal. - Deprecated
Email.failedSMTPLoginandImage.libPathInvalid
- Cookie: The
CookieInterface::EXPIRES_FORMAThas been changed toD, d M Y H:i:s Tto follow the recommended format in RFC 7231. - Format: Added support for configuring
json_encode()maximum depth viaConfig\Format::$jsonEncodeDepth. - Paths: Added support for changing the location of the
.envfile via thePaths::$envDirectoryproperty. - Toolbar: Added
$disableOnHeadersproperty to app/Config/Toolbar.php.
- Image:
- The config property
Config\Image::libraryPathhas been deprecated. No longer used. - The exception method
CodeIgniter\Images\Exceptions\ImageException::forInvalidImageLibraryPathhas been deprecated. No longer used.
- The config property
- Cookie: The
CookieInterface::SAMESITE_STRICT,CookieInterface::SAMESITE_LAX, andCookieInterface::SAMESITE_NONEconstants are now written in ucfirst style to be consistent with usage in the rest of the framework. - Cache: Changed
WincacheHandler::increment()andWincacheHandler::decrement()to returnboolinstead ofmixed. - Toolbar: Fixed Maximum call stack size exceeded crash when AJAX-like requests (HTMX, Turbo, Unpoly, etc.) were made on pages with Debug Toolbar enabled.
See the repo's CHANGELOG.md for a complete list of bugs fixed.