版本 4.3.0

发布日期:2023 年 1 月 10 日

CodeIgniter 4.3.0 版发布

亮点

  • 查询构建器支持 upsert()upsertBatch()deleteBatch(), 现在 *batch() 方法可以从查询中设置数据 ( sclubricants 贡献)。 详情请参阅 查询构建器

  • 数据库 Forge 支持在 现有表中添加索引命名索引 ( sclubricants 贡献)。 详情请参阅 Forge

  • 为了使默认配置更安全,默认验证规则 已更改为 严格规则

  • 当数据库错误发生时,会抛出异常的条件和 可以抛出的异常类已发生变化。 请参阅 数据库错误时抛出的异常

不兼容变更

行为变化

数据库错误时抛出的异常

  • 数据库连接类抛出的异常已更改为 CodeIgniter\Database\Exceptions\DatabaseException。以前,不同的数据库驱动程序会抛出不同的异常类,但这些已经统一为 DatabaseException

  • 准备好的查询的 execute() 方法抛出的异常已更改为 DatabaseException。以前,不同的数据库驱动程序可能会抛出不同的异常类,或者不抛出异常,但这些已统一为 DatabaseException

  • 在事务期间,即使 DBDebug 为 true,默认情况下也不会抛出异常。

  • DBDebugCI_DEBUG 变化

    • 为了在不同环境下保持一致的行为, Config\Database::$default['DBDebug']Config\Database::$tests['DBDebug'] 默认更改为 true。通过这些 设置,当数据库错误发生时,总是会抛出异常。以前,在生产环境中默认为 false

    • 现在,如果 $DBDebug 为 true,则在 BaseBuilder 中抛出的 DatabaseException 会被抛出。 以前,如果 CI_DEBUG 为 true 则会抛出。

    • BaseConnection::$DBDebug 的默认值已更改为 true

    • 通过这些更改, DBDebug 现在表示数据库错误发生时是否抛出异常。 虽然与调试无关,但名称未更改。

    • DBDebugtrue 运行事务时,即使查询错误也不会抛出异常。以前,如果发生查询错误, 所有查询都会回滚,并抛出异常,因此 管理错误手动运行事务 不起作用。

    • 现在,在 Model 中删除没有 WHERE 子句时,即使 CI_DEBUG 为 false 也会抛出 DatabaseException。以前,如果 CI_DEBUG 为 true 则会抛出。

异常发生时的 HTTP 状态码和退出代码

以前,CodeIgniter 的异常处理程序在某些情况下会使用 异常代码 作为 HTTP 状态码,并根据异常代码计算 退出代码。但是异常代码与 HTTP 状态码或退出代码之间不应该有逻辑联系。

  • 现在,异常处理程序默认将 HTTP 状态码设置为 500,并将退出代码设置为常量 EXIT_ERROR (= 1)。

  • 你可以在异常类中实现 HTTPExceptionInterfaceHasExitCodeInterface 来更改 HTTP 状态码或退出代码。请参阅 在异常中指定 HTTP 状态码在异常中指定退出代码

例如,退出代码已发生如下更改:

  • 如果发生未捕获的 ConfigException,退出代码将是 EXIT_CONFIG (= 3),而不是 12

  • 如果发生未捕获的 CastException,退出代码将是 EXIT_CONFIG (= 3),而不是 9

  • 如果发生未捕获的 DatabaseException,退出代码将是 EXIT_DATABASE (= 8),而不是 17

时间

时间 类的以下方法存在会更改当前对象状态的错误。为了修复这些错误,时间类已被修复:

  • add()

  • modify()

  • setDate()

  • setISODate()

  • setTime()

  • sub()

  • 现在 Time 类扩展 DateTimeImmutable 并完全是不可变的。

  • 添加了 TimeLegacy 类用于向后兼容性,它的行为与未修改的 Time 类相同。

其他

  • 辅助函数: script_tag()safe_mailto() 不再在 <script> 标签中输出 type="text/javascript"

  • CLI: 由于 Spark 命令处理的更改, spark 文件已更改。

  • CLI: CITestStreamFilter::$buffer = '' 不再导致过滤器注册为侦听流。现在有一个 CITestStreamFilter::registration() 方法用于此目的。详情请参阅 在测试中捕获 STDERR 和 STDOUT 流

  • 数据库: BaseBuilder::_whereIn() 中的 InvalidArgumentExceptionLogicException 的一种,不会被配置禁止。以前如果 CI_DEBUG 为 false,异常会被禁止。

  • 数据库: BaseConnection::getForeignKeyData() 返回的数据结构已更改。

  • 数据库: CodeIgniter\Database\BasePreparedQuery 类现在对写入类型的查询返回布尔值,而不是 Result 类对象。

  • 模型: 如果 Model::update() 方法生成没有 WHERE 子句的 SQL 语句,现在会引发 DatabaseException;模型不支持更新所有记录的操作。

  • 路由: RouteCollection::resetRoutes() 会重置自动发现路由。以前一旦发现,即使调用 RouteCollection::resetRoutes(),RouteCollection 也不会再发现 Routes 文件。

接口变更

备注

只要你没有扩展相关的 CodeIgniter 核心类 或实现这些接口,所有这些变化都是向后兼容的, 不需要任何干预。

OutgoingRequestInterface

  • 添加新的 OutgoingRequestInterface,表示传出请求。

  • 添加新的 OutgoingRequest 类,实现 OutgoingRequestInterface

  • 现在 RequestInterface 扩展 OutgoingRequestInterface

  • 现在 CURLRequest 扩展 OutgoingRequest

  • 现在 Request 扩展 OutgoingRequest

其他

  • HTTP:MessageInterface 中添加了缺失的 getProtocolVersion()getBody()hasHeader()getHeaderLine() 方法。

  • HTTP: 现在 ResponseInterface 扩展 MessageInterface

  • HTTP: 添加了缺失的 ResponseInterface::getCSP() (和 Response::getCSP() ), ResponseInterface::getReasonPhrase()ResponseInterface::getCookieStore() 方法。

  • 数据库: 添加了缺失的 CodeIgniter\Database\ResultInterface::getNumRows() 方法。

  • 参阅 验证变更

方法签名变化

验证变更

ValidationInterface

ValidationInterface 已更改,以消除 ValidationInterfaceValidation 类之间的不匹配。

  • ValidationInterface::run() 添加了第三个参数 $dbGroup

  • 接口中添加了以下方法:

    • ValidationInterface::setRule()

    • ValidationInterface::getRules()

    • ValidationInterface::getRuleGroup()

    • ValidationInterface::setRuleGroup()

    • ValidationInterface::loadRuleGroup()

    • ValidationInterface::hasError()

    • ValidationInterface::listErrors()

    • ValidationInterface::showError()

Validation

$group 为空时, Validation::loadRuleGroup() 的返回值已从 null 更改为 []

数据库

  • CodeIgniter\Database\BasePreparedQuery::close()CodeIgniter\Database\PreparedQueryInterface 的返回类型已更改为 bool (之前未定义)。

  • CodeIgniter\Database\Database::loadForge() 的返回类型已更改为 Forge

  • CodeIgniter\Database\Database::loadUtils() 的返回类型已更改为 BaseUtils

  • Table::dropForeignKey() 中的参数名 $column 已更改为 $foreignName

  • BaseBuilder::updateBatch() 的第二个参数 $index 已更改为 $constraints。它现在接受 array、string 或 RawSql 类型。扩展类也应相应更改类型。

  • BaseBuilder::insertBatch()BaseBuilder::updateBatch()$set 参数现在接受单行数据的对象。

  • BaseBuilder::_updateBatch()
    • 第二个参数 $values 已更改为 $keys

    • 第三个参数 $index 已更改为 $values。参数类型也已更改为 array

数据库 Forge

  • Forge::dropKey() 的方法签名已更改。添加了一个可选参数 $prefixKeyName

  • Forge::addKey() 的方法签名已更改。添加了一个可选参数 $keyName

  • Forge::addPrimaryKey() 的方法签名已更改。添加了一个可选参数 $keyName

  • Forge::addUniqueKey() 的方法签名已更改。添加了一个可选参数 $keyName

  • 以下方法添加了一个额外的 $asQuery 参数。当设置为 true 时,该方法返回一个独立的 SQL 查询。

    • CodeIgniter\Database\Forge::_processPrimaryKeys()

  • 除了上面添加的 $asQuery 参数外,以下方法现在也返回一个数组。

    • CodeIgniter\Database\Forge::_processIndexes()

    • CodeIgniter\Database\Forge::_processForeignKeys()

其他

  • API: API\ResponseTrait::failServerError() 的返回类型已更改为 ResponseInterface

  • 以下方法已更改为接受 ResponseInterface 作为参数,而不是 Response

    • Debug\Exceptions::__construct()

    • Services::exceptions()

  • Request: IncomingRequest::getJsonVar()$index 参数现在接受 arraystringnull 值。

增强功能

命令

  • CodeIgniter\CodeIgniter 类中提取了 Spark 命令的调用处理程序。这将减少控制台调用的成本。

  • 添加了 spark filter:check 命令来检查路由的过滤器。详情请参阅 Controller Filters

  • 添加了 spark make:cell 命令来创建新的 Cell 文件及其视图。详情请参阅 通过命令生成单元格

  • 现在 spark routes 命令显示路由名称。请参阅 URI 路由

  • 现在 spark routes 命令可以按处理程序排序输出。 请参阅 按处理程序排序

  • 现在可以使用 --help 选项访问 spark 命令的帮助信息(例如 php spark serve --help)

  • 添加了 CLI::promptByMultipleKeys() 方法以支持多值输入,与 promptByKey() 不同。详情请参阅 promptByMultipleKeys()

  • HTTP/3 现在被视为有效协议。

测试

  • 添加了 StreamFilterTrait 以更轻松地使用从 STDOUT 和 STDERR 流中捕获数据。请参阅 测试 CLI 输出

  • CITestStreamFilter 过滤器类现在实现了向流添加过滤器的方法。请参阅 测试 CLI 输出

  • 添加了 PhpStreamWrapper 以更轻松地使用 php://stdin 设置数据。请参阅 测试 CLI 输入

  • 添加了 Timer::record() 方法来测量可调用的性能。还增强了通用函数 timer() 以接受可选的可调用。

  • 将布尔第三参数 $useExactComparison 添加到 TestLogger::didLog(),它设置是否逐字检查日志消息。默认为 true

  • 添加了 CIUnitTestCase::assertLogContains() 方法,它通过消息的一部分而不是整个消息来比较日志消息。

数据库

查询构建器

  • 向 QueryBuilder 添加了 upsert()upsertBatch() 方法。参见 插入更新数据

  • 向 QueryBuilder 添加了 deleteBatch() 方法。参见 $builder->deleteBatch()

  • 添加了 when()whenNot() 方法以有条件地向查询添加子句。详情请参阅 BaseBuilder::when()

  • 改进了 Builder::updateBatch() 的 SQL 结构。详情请参阅 UpdateBatch

  • 添加了 BaseBuilder::setQueryAsData(),它允许从查询中使用 insertBatch()updateBatch()upsertBatch()deleteBatch()。参见 insertBatch

Forge

  • 添加了 Forge::processIndexes(),允许在现有表上创建索引。详情请参阅 向表添加键

  • 现在可以手动设置索引名称。这些方法包括:Forge::addKey()Forge::addPrimaryKey()Forge::addUniqueKey()

  • 新的 Forge::dropPrimaryKey() 方法允许删除表上的主键。参见 删除主键

  • 修复了 Forge::dropKey(),以允许删除唯一索引。这需要 DROP CONSTRAINT SQL命令。

  • CodeIgniter\Database\Forge::addForeignKey() 现在包括一个名称参数来手动设置外键名称。SQLite3 不支持此功能。

  • SQLSRV 现在在使用 Forge::dropColumn() 时会自动删除 DEFAULT 约束。

其他

  • SQLite3 有一个新的配置项 busyTimeout 来设置表锁定时的超时。

  • BaseConnection::escape() 现在排除 RawSql 数据类型。这允许将 SQL 字符串传递到数据中。

  • 改进了 BaseConnection::getForeignKeyData() 返回的数据。所有 DBMS 返回相同的结构。

  • SQLite BaseConnection::getIndexData() 现在可以为 AUTOINCREMENT 列返回伪索引名为 PRIMARY,并且每个返回的索引数据都有 type 属性。

  • BasePreparedQuery::close() 现在在所有 DBMS 中都会释放准备好的语句。以前,它们在 Postgre、SQLSRV 和 OCI8 中没有被释放。参见 close()

  • 添加了 BaseConnection::transException() 用于在事务过程中抛出异常。参见:抛出异常

模型

  • Publisher: 在 Publisher 中添加了 replace()addLineAfter()addLineBefore() 方法以修改文件。详情请参阅 Publisher

  • Encryption: 现在 Encryption 可以解密使用 CI3 Encryption 加密的数据。请参阅 用于与 CI3 保持兼容性的配置

  • CURLRequest:CURLRequest 中添加了 HTTP2 版本选项。

辅助函数和函数

HTML5 兼容性

通过在 app/Config/DocTypes.php 中设置 $html5 属性,可以配置创建诸如 <input> 之类的空 HTML 元素时是否排除或包含 solidus 字符 (/) 和右尖括号 (>) 之间的字符。如果将其设置为 true,则会输出不带 / 的 HTML5 兼容标签,如 <br>

以下项目会受到影响:

  • 排版类:创建 br 标签

  • 视图解析器: nl2br 过滤器

  • 诱饵模式:input 标签

  • 表单辅助函数

  • HTML 辅助函数

  • 常用函数

错误处理

  • 现在可以记录弃用警告而不是抛出异常。详情请参阅 记录弃用警告

  • 弃用的记录默认启用。

  • 要*临时*启用弃用抛出,请将环境变量 CODEIGNITER_SCREAM_DEPRECATIONS 设置为真值。

  • Config\Logger::$threshold 现在默认为特定于环境。对于生产环境,默认阈值仍为 4,但对于其他环境已更改为 9

多域名支持

  • 添加了 Config\App::$allowedHostnames 以设置基准 URL 中主机名以外的主机名。

  • 如果设置了 Config\App::$allowedHostnames,当当前 URL 匹配时,诸如 base_url()current_url()site_url() 之类的与 URL 相关的函数将返回使用 Config\App::$allowedHostnames 中设置的主机名的 URL。

其他

  • 路由: 添加了 $routes->useSupportedLocalesOnly(true),以便当 URL 中的 locale 不在 Config\App::$supportedLocales 中受支持时,路由器返回 404 Not Found。请参阅 Localization

  • 路由: 添加了新的 $routes->view() 方法以直接返回视图。请参阅 View Routes

  • 视图: 视图 Cell 现在是一等公民,可以位于 app/Cells 目录中。请参阅 View Cells

  • 视图: 添加了“受控 Cell”,为你的视图 Cell 提供了更多结构和灵活性。详情请参阅 View Cells

  • 验证: 添加了闭包验证规则。详情请参阅 使用闭包规则

  • 配置: 现在可以指定要手动发现的 Composer 包。请参阅 Code Modules

  • 配置: 添加了 Config\Session 类来处理会话配置。

  • 调试: 将 Kint 更新到 5.0.2。

  • 请求: 添加了新的 $request->getRawInputVar() 方法从原始流中返回指定变量。请参阅 Retrieving Raw data

  • 请求: 添加了新的 $request->is() 方法来查询请求类型。 请参阅 Determining Request Type

消息变更

  • 更新英文语言字符串以保持更一致。

  • 添加了 CLI.generator.className.cellCLI.generator.viewName.cell

  • 添加了 en/Errors.php 文件。

变更

  • 配置
    • Config 类中的所有原子类型属性现已加类型。

    • 有关更改默认值的信息,请参阅 Upgrading

  • 更改了 Spark 命令的处理:
    • CodeIgniter\CodeIgniter 不再处理 Spark 命令。

    • 已删除 CodeIgniter::isSparked() 方法。

    • 已删除 CodeIgniter\CLI\CommandRunner 类,因为 Spark 命令处理发生了变化。

    • 已删除系统路由配置文件 system/Config/Routes.php

    • 应用路由配置文件 app/Config/Routes.php 已更改。删除系统路由配置文件的包含。

弃用功能

  • 弃用 RouteCollection::localizeRoute()

  • 弃用 RouteCollection::fillRouteParams()。请使用 RouteCollection::buildReverseRoute()

  • 弃用 BaseBuilder::setUpdateBatch()BaseBuilder::setInsertBatch()。请使用 BaseBuilder::setData()

  • 弃用公共属性 Response::$CSP。它将变为 protected。请使用 Response::getCSP()

  • 弃用 CodeIgniter::$pathCodeIgniter::setPath()。不再使用。

  • 弃用公共属性 IncomingRequest::$uri。它将变为 protected。请使用 IncomingRequest::getUri()

  • 弃用公共属性 IncomingRequest::$config。它将变为 protected。

  • 弃用 CLI::isWindows() 方法。请使用 is_windows()

  • 弃用 Config\App 中的会话属性,改用新的会话配置类 Config\Session

错误修复

  • 修复了所有类型的“准备查询”在写入类型查询中返回 Result 对象而不是 bool 值的错误。

  • 修复了在使用 IncomingRequest::getVar()IncomingRequest::getJsonVar() 方法时 JSON 请求中的变量过滤的错误。

  • 修复了在使用指定索引调用 IncomingRequest::getVar()IncomingRequest::getJsonVar() 方法时可能更改变量类型的错误。

  • 修复了启用 CSP 时 Honeypot 字段出现的错误。另请参阅 Honeypot 和 CSP

有关完整的错误修复列表,请参阅仓库的 CHANGELOG.md