English
6.0 Migration Guide
CakePHP 6.0 contains breaking changes, and is not backwards compatible with 5.x. Before attempting to upgrade to 6.0 first upgrade to 5.3+ and resolve all deprecation warnings.
Behavior Changes
All datasource connections require the
username,passwordanddatabasekeys as default values have been removed to prevent accidental privileged user usage.The
ORM.mapJsonTypeForSqliteconfiguration option has been removed. The SQLite adapter will map all columns withjsonin their names to theJsonTypeby default.Cake\View\Widget\FileWidgetwas removed as it was redundant. The standard input widget will be used for file inputs in 6.x.Text::uuid()now generates UUID v7 complaint strings instead of UUID v4.Cake\Event\Event::getSubject()can now returnnullif the event has no subject instead of throwing an exception.Model.buildValidatoris now dispatched before the named validation method, allowing listeners to register providers used byValidator::add(). Listeners that inspect rules added byvalidationDefault()must account for this order.Calling behavior methods directly on the table instance is now opt-in. Behaviors no longer expose their public methods as mixin methods on the table unless they are attached with the
implementedMethodsconfiguration set totrue, a map ofalias => methodpairs, or a list of method names.
Breaking Changes
Renamed Methods
Methods starting with a _ have been renamed to remove the leading underscore. You can find a full list of adjusted methods in the cakephp/upgrade tool.
Some methods have also been renamed to better reflect their purpose. These are:
| Class | Old Method(s) | New Method(s) |
|---|---|---|
Cake\Collection\ExtractTrait | _extract() | extractColumn() |
Cake\Console\ConsoleOutput | _write() | writeStream() |
Cake\Form\Form | _execute() | process() |
Cake\Http\Client | _sendRequest() | processRequest() |
Cake\Http\ServerRequest | _is() | isType() |
Cake\Http\Client\Adapter\Stream | _send() | processRequest() |
Cake\Http\Cookie\Cookie | resolveSameSiteEnum() | resolveSameSite() |
Cake\I18n\DateFormatTrait | _parseDateTime() | processDateTime() |
Cake\Mailer\Transport\SmtpTransport | _connect()_disconnect() | connectSmtp()disconnectSmtp() |
Cake\ORM\Table | _saveMany()_deleteMany() | doSaveMany()doDeleteMany() |
Cake\ORM\Behavior\TreeBehavior | _moveUp()_moveDown()_removeFromTree() | doMoveUp()doMoveDown()doRemoveFromTree() |
Cake\ORM\Association\HasMany | _unlink() | doUnlink() |
Cake\ORM\Query\SelectQuery | _decorateResults()_execute() | ormDecorateResults()ormExecute() |
Cake\Utility\Hash | _filter()_merge() | doFilter()doMerge() |
Cake\Utility\Text | _wordWrap() | doWordWrap() |
Cake\Utility\Xml | _fromArray()_toArray() | doFromArray()doToArray() |
Cake\View\View | _render() | renderFile() |
Cake\View\Helper\PaginatorHelper | _numbers() | buildNumbers() |
Renamed Properties
Properties starting with a _ have been renamed to remove the leading underscore. You can find a full list of adjusted properties in the cakephp/upgrade tool.
Some properties have also been renamed to better reflect their purpose. These are:
Cake\ORM\Entity$_accessiblehas been renamed topatchable
Cake\View\View$_helpershas been renamed tohelperRegistryas$helpersalready exists to hold the configuration
Renamed Classes
Cake\Database\DriverFeatureEnumhas moved toCake\Database\Enum\DriverFeature.Cake\Http\Cookie\SameSiteEnumhas moved toCake\Http\Cookie\Enum\SameSite.- The
Cake\Command\Helpernamespace has been removed. Use theCake\Console\Helpernamespace forBannerHelper,ProgressHelper,TableHelper, andTreeHelper.
Method Signatures
- All fluent methods now declare a
staticreturn type. Update return types in overridden methods and interface implementations accordingly. This affects methods on classes and interfaces such asController,Table,EntityInterface,EventInterface,Mailer, andViewBuilder. The upgrade tool contains the full list. - The following methods now return
void:ServerRequest::allowMethod(),Configure::load(),ResponseEmitter::emit(),Session::close(),Table::deleteOrFail(),FixtureInterface::insert()andtruncate(), andConsoleInputArgument::validateChoice()andConsoleInputOption::validateChoice(). Remove assignments and conditions that depend on their former return values. Handle exceptions where applicable. - The callback parameters of
CsrfProtectionMiddleware::skipCheckCallback(),SessionCsrfProtectionMiddleware::skipCheckCallback(),View::cache(),TestCase::withErrorReporting(),Table::executeTransaction(), andAttributeCollection::filter()now require aClosureinstead of a generalcallable.ResultSetFactory::getDtoHydrator()now returns aClosure.
Console
- The
validChoicemethod onConsoleInputArgumentandConsoleInputOptionhas been renamed tovalidateChoice.
Command
- Command args and io are now available as properties instead of them being passed down to the execute method. See the current state of Commands for examples.
Event
- The signature of
EventManagerInterface::on()has changed. The 2nd and 3rd parameters have been swapped. Calls which pass an options array as the 2nd argument will need to be updated to pass it as the 3rd argument instead or use named parameters.
Dependency Injection
- CakePHP now uses
Cake\Container\Containerby default and no longer requiresleague/container. Remove the oldApp.container = 'cake'config option. To use a custom container, setApp.containerto a class name implementingCake\Container\ContainerInterface. - Replace
Cake\Core\Container,Cake\Core\ContainerInterfaceandCake\Core\ServiceProviderwith theirCake\Containerequivalents. - Auto-wiring and its resolution cache are enabled by default. Remove delegation to
League\Container\ReflectionContainer; usedisableAutoWiring()andenableAutoWiring()to configure the built-in resolver. See Auto-wiring for details. Container::defaultToShared(),enableAutoWiring()anddisableAutoWiring()returnstatic. Update the return types of overrides accordingly.
Datasource
Datasource/Paging/PaginatedInterfacenow extendsIteratorAggregateinstead ofTraversable.EntityTrait::isEmpty()has been dropped in favor ofhasValue().
Database
- Binary columns now use
binaryfor fixed-length data andvarbinaryfor variable-length data. In migrationaddColumn()calls, remove'fixed' => truefrom fixed-lengthbinarycolumns, and change variable-lengthbinarycolumns tovarbinary. Thefixedoption is no longer used;TableSchemaInterface::TYPE_VARBINARYis available for the new type.
Error
Debugger::outputMask(),setOutputMask()have been removed.
Http
Using
$request->getParam('?')to get the query params is no longer possible. Use$request->getQueryParams()instead.The methods
_getCookies(),_getJson(),_getXml(),_getHeaders()and_getBody()have been removed. Use/Overwrite their non-prefixed public alternative instead.URL parsing now uses PHP 8.5's
Uri\WhatWg\UrlandUri\Rfc3986\Uriparsers. Review malformed or relative URL inputs and exception handling. In particular,Client::createFromUrl()can now throwUri\WhatWg\InvalidUrlExceptionfor inputs previously rejected withInvalidArgumentException. See Creating Scoped Clients.
ORM
- The
_accessibleproperty inside Entities has been renamed topatchableto better reflect its purpose. setAccessmethod has been renamed tosetPatchable.getAccessiblemethod has been renamed togetPatchable.isAccessiblemethod has been renamed toisPatchable.- The
accessibleFieldsoption used in e.g. ORM Queries has been renamed topatchableFields. TranslateTrait::translation()now only retrieves an existing translation and returnsnullwhen none exists. UsegetOrCreateTranslation()if the previous create-on-access behavior is needed.
Router
RouteBuilderhas adjusted the signature ofscope(),prefix()andresources()so the 2nd and 3rd parameters have been swapped. We recommend using named parameters to prevent confusion and make the code more readable.
Utility
- The default placeholder format for
Text::insert()has been changed. They now use{foo}instead of:foo. You can get the old behavior by using thebeforeandafterkeys of$options.
View
'escape'/'escapeTitle'keys have now been separated cleanly intoescapefor escaping content/labels, and'escapeAttributes'for HTML attributes respectively. They also don't overlap anymore, so if you need to prevent escaping on content and attributes, make sure to set them both to false.titlehas been renamed tocontentin scopes where this is not an attribute, but content or label element, specifically:'item'/itemWithoutLinkbreadcrumb templates.multicheckboxTitletemplate of FormHelper is nowmulticheckboxLabel.FormHelpernow defaultsnestedCheckboxAndRadiotofalse, placing checkbox and radio inputs before their labels. Set it totrueto retain nesting, or usenestedInputon individual controls. Review CSS selectors that depend on the old markup.The default
radioWrappertemplate is now<div class="radio"></div>. Custom wrappers must includeas well aswhen inputs are not nested.Multicheckbox option labels cannot be disabled. Use an array for label attributes when calling
multiCheckbox(); directMultiCheckboxWidgetcallers must also pass an array forlabel.
New Features
Event
- Event subscriptions can now be declared on listener classes and methods with the repeatable
Cake\Event\Attribute\EventListenerattribute. Register them throughEventManager::registerAttributeListeners()orAttributeEventListenerConnector, with support for constructor dependency injection and named event managers. See Registering Listeners with Attributes for configuration and examples.
ORM
- Entities can now map fields to real class properties, including typed properties and PHP 8.4 asymmetric visibility/property hooks. When changing declared fields inside entity methods, continue to use
set()/patch()if you need dirty tracking and related entity bookkeeping.
Router
- Attribute routing is now available via
RouteBuilder::connectAttributes()and the newCake\Routing\Attributenamespace. Routes can be defined directly on controller classes and actions using PHP attributes such as#[Get],#[Post],#[Scope],#[Resource], and more. See Attribute Routing for full documentation.