CakePHP 4.4 is an API compatible upgrade from 4.0. This page outlines the deprecations and features added in 4.4.
You can can use composer to upgrade to CakePHP 4.4.0:
php composer.phar require --update-with-dependencies "cakephp/cakephp:^4.4"
Note
CakePHP 4.4 requires PHP 7.4 or greater.
4.4 introduces a few deprecations. All of these features will continue for the duration of 4.x but will be removed in 5.0.
You can use the upgrade tool to automate updating usage of deprecated features:
bin/cake upgrade rector --rules cakephp44 <path/to/app/src>
Note
This only updates CakePHP 4.4 changes. Make sure you apply CakePHP 4.3 changes first.
A new configuration option has been added to disable deprecations on a path by path basis. See Deprecation Warnings for more information.
The paginator
option for Controller::paginate()
is deprecated. Instead
use the className
option.
The paginator
option for PaginatorComponent
is deprecated. Instead
use the className
option.
FactoryLocator::add()
no longer accepts closure factory functions. Instead
you must pass an instance of the LocatorInterface
.
Cake\Datasource\Paging\Paginator
has been renamed to
Cake\Datasource\Paging\NumericPaginator
.
The ErrorHandler
and ConsoleErrorHandler
classes are now deprecated.
They have been replaced by the new ExceptionTrap
and ErrorTrap
classes.
The trap classes provide a more extensible and consistent error & exception
handling framework. To upgrade to the new system you can replace the usage of
ErrorHandler
and ConsoleErrorHandler
(such as in your config/bootstrap.php
) with:
use Cake\Error\ErrorTrap;
use Cake\Error\ExceptionTrap;
(new ErrorTrap(Configure::read('Error')))->register();
(new ExceptionTrap(Configure::read('Error')))->register();
If you have defined the Error.errorLogger
configure value, you will need to
use Error.logger
instead.
See the Error & Exception Handling for more detailed documentation. Additionally the following methods related to the deprecated error handling system are deprecated:
Debugger::outputError()
Debugger::getOutputFormat()
Debugger::setOutputFormat()
Debugger::addFormat()
Debugger::addRenderer()
ErrorLoggerInterface::log()
. Implement logException()
instead.
ErrorLoggerInterface::logMessage()
. Implement logError()
instead.
The RequestHandlerComponent has been soft-deprecated. Like AuthComponent
using RequestHandler
will not trigger runtime deprecations but it will
be removed in 5.0.
Replace accepts()
with $this->request->accepts()
.
Replace requestedWith()
with a custom request detector (for example,
$this->request->is('json')
).
Replace prefers()
with ContentTypeNegotiation
. See Content Type Negotiation.
Replace renderAs()
with controller content negotiation features on
Controller
.
Replace checkHttpCache
option with Checking HTTP Cache.
Use Content Type Negotiation instead of defining view class mappings in
RequestHandlerComponent
.
The automatic view switching for ‘ajax’ requests offered by
RequestHandlerComponent
is deprecated. Instead you can either
handle this in a controller action or Controller.beforeRender
callback
with:
// In a controller action, or in beforeRender.
if ($this->request->is('ajax')) {
$this->viewBuilder()->setClassName('Ajax');
}
Alternatively, you can have the HTML view class switch to the ajax
layout as
required in your controller actions or view templates.
The PaginatorComponent
is deprecated and will be removed in 5.0.
Use the Controller::$paginate
property or the $settings
parameter of
Controller::paginate()
method to specify required paging settings.
SaveOptionsBuilder
was deprecated. Use an array for options instead.
Plugin class names should now match the plugin name with a “Plugin” suffix. For
example, the plugin class for ADmad/I18n
plugin would be ADmad\I18n\I18nPlugin
instead of ADmad\I18n\Plugin
, as was the case for CakePHP 4.3 and below.
The old style name for existing majors should be kept to avoid BC breaks.
The new naming convention should be followed when developing a new plugin or
when doing a major release.
Cached route files have been deprecated. There are a number of edge cases that are impossible to resolve with cached routes. Because the feature of cached routes is non-functional for many use cases it will be removed in 5.x
ConsoleIntegrationTestTrait
was moved to the console package along with
dependencies to allow testing console applications without requiring the full
cakephp/cakephp package.
Cake\TestSuite\ConsoleIntegrationTestTrait
moved to Cake\Console\TestSuite\ConsoleIntegrationTestTrait
Cake\TestSuite\Constraint\Console\*
moved to Cake\Console\TestSuite\Constraint\*
Cake\TestSuite\Stub\ConsoleInput
moved to Cake\Console\TestSuite\StubConsoleInput
Cake\TestSuite\Stub\ConsoleOutput
moved to Cake\Console\TestSuite\StubConsoleOutput
Cake\TestSuite\Stub\MissingConsoleInputException
moved to Cake\Console\TestSuite\MissingConsoleInputException
ContainerStubTrait
was moved to the core package to allow testing console applications
without requiring the full cakephp/cakephp package.
Cake\TestSuite\ContainerStubTrait
moved to Cake\Core\TestSuite\ContainerStubTrait
HttpClientTrait
was moved to the http package to allow testing http applications
without requiring the full cakephp/cakephp package.
Cake\TestSuite\HttpClientTrait
moved to Cake\Http\TestSuite\HttpClientTrait
While the following changes do not change the signature of any methods they do change the semantics or behavior of methods.
Table::saveMany()
now triggers the Model.afterSaveCommit
event with
entities that are still ‘dirty’ and contain the original field values. This
aligns the event payload for Model.afterSaveCommit
with Table::save()
.
Router::parseRequest()
now raises BadRequestException
instead of
InvalidArgumentException
when an invalid HTTP method is used by a client.
RedisEngine
now supports deleteAsync()
and clearBlocking()
methods. These methods use the UNLINK
operation in redis to mark data for
removal later by Redis.
bin/cake routes
now highlights collisions in route templates.
Command::getDescription()
allows you to set a custom description. See Setting Command Description
Controller::viewClasses()
was added. This method should be implemented by
controllers that need to perform content-type negotiation. View classes will
need to implement the static method contentType()
to participate in
content-type negotiation.
The previously experimental API for the Dependency Injection container, introduced in CakePHP 4.2, is now considered stable.
The SQLite
driver now supports shared in memory databases in PHP8.1+.
Query::expr()
was added as an alternative to Query::newExpr()
.
The QueryExpression::case()
builder now supports inferring the type
from expressions passed to then()
and else()
that implement
\Cake\Database\TypedResultInterface
.
ErrorTrap
and ExceptionTrap
were added. These classes form the
foundation of an updated error handling system for applications. Read more
about these classes in Error & Exception Handling.
Response::checkNotModified()
was deprecated.
Use Response::isNotModified()
instead.
BaseApplication::handle()
now adds the $request
into the service
container all the time.
HttpsEnforcerMiddleware
now has an hsts
option that allows you to
configure the Strict-Transport-Security
header.
Mailer
now accepts a autoLayout
config which disabled auto layout
in the ViewBuilder
if set to false
.
The cascadeCallbacks
option was added to TreeBehavior
. When enabled,
TreeBehavior
will iterate a find()
result and delete records
individually. This enables ORM callbacks to be used when deleting tree nodes.
Plugin classes should now be named to match the plugin name instead of just Plugin
.
For example, you should now use ADmad\I18n\I18nPlugin
instead of ADmad\I18n\Plugin
.
RoutingMiddleware
now sets the “route” request attribute with the matched
Route
instance.
View::contentType()
was added. Views should implement this method in order
to participate in content-type negotiation.
View::TYPE_MATCH_ALL
was added. This special content-type allows you to
build fallback views for when content-type negotiation provides no matches.