CakePHP 5.0 包含重大变更,与 4.x 版本不向后兼容。在尝试升级到 5.0 之前,请先升级到 4.5 并解决所有弃用警告。
请参阅 5.0 升级指南,了解有关如何升级到 5.0 的分步说明。
自 4.5 版本以来,发出弃用警告的所有方法、属性和功能均已移除。
除了移除已弃用功能外,还进行了重大变更
在所有可能的地方,函数参数和返回值都添加了类型声明。这些类型声明旨在与文档注释相匹配,但也包含对不正确注释的修复。
在所有可能的地方,类属性都添加了类型声明。这些类型声明还包含对不正确注释的一些修复。
已移除 SECOND
、MINUTE
、HOUR
、DAY
、WEEK
、MONTH
、YEAR
常量。
#[\AllowDynamicProperties]
。它用于以下类:Command/Command
Console/Shell
Controller/Component
Controller/Controller
Mailer/Mailer
View/Cell
View/Helper
View/View
MySQL (5.7 或更高版本)
MariaDB (10.1 或更高版本)
PostgreSQL (9.6 或更高版本)
Microsoft SQL Server (2012 或更高版本)
SQLite 3 (3.16 或更高版本)
已移除 Auth。请改用 cakephp/authentication 和 cakephp/authorization 插件。
已移除 Wincache
引擎。PHP 8 不支持 wincache 扩展。
combine()
现在会在键路径或分组路径不存在或包含空值时抛出异常。这与 indexBy()
和 groupBy()
的行为一致。
已移除 BaseCommand::__construct()
。
已移除 ConsoleIntegrationTestTrait::useCommandRunner()
,因为它不再需要。
已移除 Shell
,应替换为 Command
已移除 ConsoleOptionParser::addSubcommand()
,与移除 Shell
一致。子命令应替换为实现 Command::defaultName()
以定义必要命令名的 Command
类。
BaseCommand
现在会在框架调用命令的 execute()
方法前后发出 Command.beforeExecute
和 Command.afterExecute
事件。
已移除 Connection::prepare()
。您可以改用 Connection::execute()
在单个调用中通过指定 SQL 字符串、参数和类型来执行 SQL 查询。
已移除 Connection::enableQueryLogging()
。如果您尚未通过连接配置启用日志记录,则可以稍后为驱动程序设置记录器实例以启用查询日志记录 $connection->getDriver()->setLogger()
。
Controller::__construct()
的方法签名已更改。因此,如果您要覆盖构造函数,则需要相应地调整代码。
加载后,组件不再被设置为动态属性。相反,Controller
使用 __get()
为组件提供属性访问。此更改可能会影响使用 property_exists()
的应用程序。
组件的 Controller.shutdown
事件回调已从 shutdown
重命名为 afterFilter
,以匹配控制器回调。这使回调更加一致。
PaginatorComponent
已移除,应替换为在控制器中调用 $this->paginate()
或直接使用 Cake\Datasource\Paging\NumericPaginator
RequestHandlerComponent
已移除。请参阅 4.4 迁移 指南,了解如何升级
SecurityComponent
已移除。请改用 FormProtectionComponent
进行表单篡改保护或使用 HttpsEnforcerMiddleware
来强制请求使用 HTTPS。
Controller::paginate()
不再接受其 $settings
参数的查询选项,如 contain
。相反,您应该使用 finder
选项 $this->paginate($this->Articles, ['finder' => 'published'])
。或者,您可以在预先创建所需的 select 查询,然后将其传递给 paginate()
$query = $this->Articles->find()->where(['is_published' => true]); $this->paginate($query);
。
已移除函数 getTypeName()
。请改用 PHP 的 get_debug_type()
。
已将 league/container
的依赖项更新为 4.x
。这将要求您在 ServiceProvider
实现中添加类型提示。
deprecationWarning()
现在有一个 $version
参数。
已移除配置选项 App.uploadedFilesAsObjects
,以及整个框架对 PHP 文件上传形状数组的支持。
已移除 ClassLoader
。请改用 composer 生成自动加载文件。
DateTimeType
和 DateType
现在始终返回不可变对象。此外,Date
对象的接口反映了 ChronosDate
接口,该接口缺少 CakePHP 4.x 中存在的所有与时间相关的方法。
DateType::setLocaleFormat()
不再接受数组。
Query
现在只接受 \Closure
参数,而不是 callable
。可调用对象可以使用 PHP 8.1 中新的头等数组语法转换为闭包。
Query::execute()
不再运行结果装饰器回调。 您必须使用 Query::all()
代替。
TableSchemaAwareInterface
已被移除。
Driver::quote()
已被移除。 请改用预处理语句。
Query::orderBy()
已被添加以替换 Query::order()
。
Query::groupBy()
已被添加以替换 Query::group()
。
SqlDialectTrait
已被移除,其所有功能已移至 Driver
类本身。
CaseExpression
已被移除,应替换为 QueryExpression::case()
或 CaseStatementExpression
Connection::connect()
已被移除。 请改用 $connection->getDriver()->connect()
。
Connection::disconnect()
已被移除。 请改用 $connection->getDriver()->disconnect()
。
cake.database.queries
已被添加作为 queriesLog
范围的替代方案。
启用/禁用结果集缓冲的功能已被移除。 结果始终被缓冲。
getAccessible()
方法已添加到 EntityInterface
。 非 ORM 实现现在需要实现此方法。
aliasField()
方法已添加到 RepositoryInterface
。 非 ORM 实现现在需要实现此方法。
事件有效载荷必须是数组。 其他对象(如 ArrayAccess
)不再转换为数组,现在将引发 TypeError
。
建议调整事件处理程序以成为 void 方法,并使用 $event->setResult()
而不是返回结果。
ErrorHandler
和 ConsoleErrorHandler
已被移除。 有关如何升级,请参阅 4.4 迁移 指南。
ExceptionRenderer
已被移除,应替换为 WebExceptionRenderer
ErrorLoggerInterface::log()
已被移除,应替换为 ErrorLoggerInterface::logException()
ErrorLoggerInterface::logMessage()
已被移除,应替换为 ErrorLoggerInterface::logError()
Filesystem 包已被移除,Filesystem
类已移至 Utility 包。
ServerRequest
不再与 files
作为数组兼容。 此行为自 4.1.0 起默认情况下已被禁用。 files
数据现在将始终包含 UploadedFileInterfaces
对象。
FrozenDate
已重命名为 Date,FrozenTime
已重命名为 DateTime。
Time
现在扩展了 Cake\Chronos\ChronosTime
,因此是不可变的。
Date
对象不再扩展 DateTimeInterface
- 因此您无法将它们与 DateTime
对象进行比较。 有关更多信息,请参阅 cakephp/chronos 版本发布文档。
Date::parseDateTime()
已被移除。
Date::parseTime()
已被移除。
Date::setToStringFormat()
和 Date::setJsonEncodeFormat()
不再接受数组。
Date::i18nFormat()
和 Date::nice()
不再接受时区参数。
具有供应商前缀名称 (FooBar/Awesome
) 的插件的翻译文件现在将在文件名中包含该前缀,例如 foo_bar_awesome.po
,以避免与来自相应插件 (Awesome
) 的 awesome.po
文件冲突。
日志引擎配置现在使用 null
而不是 false
来禁用范围。 因此,在您的日志配置中,您需要使用 'scopes' => null
而不是 'scopes' => false
。
Email
已被移除。 请改用 Mailer。
cake.mailer
已被添加作为 email
范围的替代方案。
EntityTrait::has()
现在在属性存在且设置为 null
时返回 true
。 在之前的 CakePHP 版本中,这将返回 false
。 有关如何在 4.x 中采用此行为,请参阅 4.5.0 的版本发布说明。
EntityTrait::extractOriginal()
现在仅返回存在的字段,类似于 extractOriginalChanged()
。
查找器参数现在要求是关联数组,因为它们始终被预期为关联数组。
TranslateBehavior
现在默认为 ShadowTable
策略。 如果您正在使用 Eav
策略,您需要更新您的行为配置以保留以前的行为。
allowMultipleNulls
选项用于 isUnique
规则现在默认为 true,匹配原始 3.x 行为。
Table::query()
已被移除,有利于特定于查询类型的函数。
Table::updateQuery()
、Table::selectQuery()
、Table::insertQuery()
和 Table::deleteQuery()
)已被添加,并返回以下新的特定于类型的查询对象。
SelectQuery
、InsertQuery
、UpdateQuery
和 DeleteQuery
已被添加,它们仅代表一种类型的查询,不允许在查询类型之间切换,也不允许调用与特定查询类型无关的函数。
Table::_initializeSchema()
已被移除,应替换为在 initialize()
方法中调用 $this->getSchema()
。
SaveOptionsBuilder
已被移除。 请改用普通数组作为选项。
Router
的静态方法 connect()
、prefix()
、scope()
和 plugin()
已被移除,应替换为通过 RouteBuilder
实例调用其非静态方法变体。
RedirectException
已被移除。 请改用 \Cake\Http\Exception\RedirectException
。
TestSuite
已被移除。 用户应该使用环境变量来自定义单元测试设置。
TestListenerTrait
已被移除。 PHPUnit 放弃了对这些侦听器的支持。 请参阅 PHPUnit 10 升级
IntegrationTestTrait::configRequest()
现在在多次调用时合并配置,而不是替换当前存在的配置。
Validation::isEmpty()
不再与文件上传形状数组兼容。 对 PHP 文件上传数组的支持已从 ServerRequest
中移除,因此您在测试之外不应该看到这是一个问题。
以前,大多数数据验证错误消息只是 The provided value is invalid
。 现在,数据验证错误消息的措辞更加准确。 例如,The provided value must be greater than or equal to \`5\`
。
ViewBuilder
选项现在确实是关联的(字符串键)。
NumberHelper
和 TextHelper
不再接受 engine
配置。
ViewBuilder::setHelpers()
参数 $merge
已被移除。 请改用 ViewBuilder::addHelpers()
。
在 View::initialize()
内部,优先使用 addHelper()
而不是 loadHelper()
。无论如何,所有配置的助手将在之后加载。
View\Widget\FileWidget
现在不再与 PHP 文件上传形状数组兼容。这与 ServerRequest
和 Validation
的更改保持一致。
FormHelper
不再在 CSRF 令牌字段上设置 autocomplete=off
。这是一个针对 Safari 漏洞的解决方法,现在不再相关。
以下是已弃用的方法、属性和行为的列表。这些功能将在 5.x 中继续发挥作用,并在 6.0 中被移除。
Query::order()
已被弃用。现在 Connection
方法不再被代理,请使用 Query::orderBy()
代替。这使函数名称与 SQL 语句保持一致。
Query::group()
已被弃用。现在 Connection
方法不再被代理,请使用 Query::groupBy()
代替。这使函数名称与 SQL 语句保持一致。
使用选项数组调用 Table::find()
已被弃用。请使用 命名参数 代替。例如,不要使用 find('all', ['conditions' => $array])
,请使用 find('all', conditions: $array)
。同样,对于自定义查找器选项,不要使用 find('list', ['valueField' => 'name'])
,请使用 find('list', valueField: 'name')
或多个命名参数,如 find(type: 'list', valueField: 'name', conditions: $array)
。
CakePHP 5 利用了 PHP 8.1+ 中可用的扩展类型系统功能。CakePHP 还使用 assert()
来提供改进的错误消息和额外的类型安全性。在生产模式下,您可以配置 PHP 不为 assert()
生成代码,从而提高应用程序性能。有关如何执行此操作,请参阅 提高应用程序性能。
添加了 unique()
,它根据提供的回调过滤掉重复的值。
reject()
现在支持默认回调,该回调过滤掉真值,这与 filter()
的默认行为相反。
将 services()
方法添加到 PluginInterface
中。
PluginCollection::addFromConfig()
已添加到 简化插件加载 中。
ConnectionManager
现在支持读写连接角色。角色可以通过连接配置中的 read
和 write
键进行配置,这些键会覆盖共享配置。
添加了 Query::all()
,它运行结果修饰器回调并返回选择查询的结果集。
添加了 Query::comment()
,用于将 SQL 注释添加到执行的查询中。这使得调试查询变得更加容易。
添加了 EnumType
,允许在 PHP 支持的枚举和字符串或整数列之间进行映射。
将 getMaxAliasLength()
和 getConnectionRetries()
添加到 DriverInterface
中。
现在,支持的驱动程序会自动将自增仅添加到名为“id”的整数主键,而不是所有整数主键。将 ‘autoIncrement’ 设置为 false 将始终在所有支持的驱动程序上禁用。
添加了对 PSR-17 工厂接口的支持。这使得 cakephp/http
能够为允许自动接口解析的库(如 php-http)提供客户端实现。
添加了 CookieCollection::__get()
和 CookieCollection::__isset()
,以提供符合人体工程学的方式访问 cookie,而无需出现异常。
实体具有一个新的选择性功能,允许实体更严格地处理属性。这种新行为称为“必需字段”。启用后,访问实体中未定义的属性将引发异常。这会影响以下用法
$entity->get();
$entity->has();
$entity->getOriginal();
isset($entity->attribute);
$entity->attribute;
如果字段通过 array_key_exists
,则认为字段已定义。这包括空值。由于这可能是一个繁琐的启用功能,因此它被推迟到 5.0。我们希望您能对这个功能提供任何反馈,因为我们正在考虑在将来将其设为默认行为。
表查找器现在可以具有类型化参数作为必需参数,而不是选项数组。例如,用于按类别或用户获取帖子的查找器
public function findByCategoryOrUser(SelectQuery $query, array $options)
{
if (isset($options['categoryId'])) {
$query->where(['category_id' => $options['categoryId']]);
}
if (isset($options['userId'])) {
$query->where(['user_id' => $options['userId']]);
}
return $query;
}
现在可以写成
public function findByCategoryOrUser(SelectQuery $query, ?int $categoryId = null, ?int $userId = null)
{
if ($categoryId) {
$query->where(['category_id' => $categoryId]);
}
if ($userId) {
$query->where(['user_id' => $userId]);
}
return $query;
}
然后可以像 find('byCategoryOrUser', userId: $somevar)
那样调用查找器。您甚至可以包含用于设置查询子句的特殊命名参数。 find('byCategoryOrUser', userId: $somevar, conditions: ['enabled' => true])
。
对 RepositoryInterface::get()
方法也进行了类似的更改
public function view(int $id)
{
$author = $this->Authors->get($id, [
'contain' => ['Books'],
'finder' => 'latest',
]);
}
现在可以写成
public function view(int $id)
{
$author = $this->Authors->get($id, contain: ['Books'], finder: 'latest');
}
添加了 IntegrationTestTrait::requestAsJson()
,用于为下一个请求设置 JSON 标头。
插件安装程序已更新,可以自动处理您的应用程序插件的类自动加载。因此,您可以从 composer.json
中删除插件的命名空间到路径映射,只需运行 composer dumpautoload
。