版本 4.3.0

发布日期:2023 年 1 月 10 日

CodeIgniter4 的 4.3.0 版本

亮点

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

  • Database 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 状态码或退出码之间不应该有任何逻辑联系。

例如,退出码已更改如下

  • 如果发生未捕获的 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 流

  • 数据库: InvalidArgumentException,一种 LogicException,在 BaseBuilder::_whereIn() 中出现,不会被配置抑制。之前如果 CI_DEBUG 为 false,则会抑制该异常。

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

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

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

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

接口变更

注意

只要您没有扩展相关的 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。现在它接受类型数组、字符串或 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()

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

增强功能

命令

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

  • 添加了 spark filter:check 命令来检查路由的过滤器。有关详细信息,请参阅 控制器过滤器

  • 添加了 spark make:cell 命令来创建新的 Cell 文件及其视图。有关详细信息,请参见 通过命令生成 Cell

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

  • 现在 spark routes 命令可以按 Handler 对输出进行排序。请参见 按 Handler 排序

  • 现在可以使用 --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() 以接受可选的可调用函数。

  • TestLogger::didLog() 中添加了一个布尔类型的第三个参数 $useExactComparison,用于设置是否逐字检查日志消息。默认值为 true

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

数据库

查询构建器

  • 在 QueryBuilder 中添加了 upsert()upsertBatch() 方法。请参阅 插入数据

  • 在 QueryBuilder 中添加了 deleteBatch() 方法。请参阅 批量删除

  • 添加了 when()whenNot() 方法,用于有条件地向查询添加子句。有关详细信息,请参阅 BaseBuilder::when()

  • 改进了 Builder::updateBatch() 的 SQL 结构。有关详细信息,请参阅 批量更新

  • 添加了 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(),用于在事务期间抛出异常。请参阅 抛出异常

模型

  • 发布者:在发布者中添加了 replace()addLineAfter()addLineBefore() 方法来修改文件。有关详细信息,请参阅 发布者

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

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

助手和函数

HTML5 兼容性

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

以下项目受到影响

  • 排版类:创建 br 标签

  • 视图解析器:nl2br 过滤器

  • 蜜罐:input 标签

  • 表单助手

  • HTML 助手

  • 通用函数

错误处理

  • 您现在可以记录弃用警告,而不是抛出异常。有关详细信息,请参阅 记录弃用警告

  • 默认情况下,弃用记录已启用。

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

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

多域名支持

  • 添加了 Config\App::$allowedHostnames 用于设置除 baseURL 中主机名之外的其他主机名。

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

其他

  • 路由:添加了 $routes->useSupportedLocalesOnly(true),以便路由器在 URL 中的语言环境不受 Config\App::$supportedLocales 支持时返回 404 未找到。请参阅 本地化

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

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

  • 视图:添加了 Controlled Cells,为您的视图单元提供更多结构和灵活性。有关详细信息,请参阅 视图单元

  • 验证:添加了闭包验证规则。有关详细信息,请参阅 使用闭包规则

  • 配置: 现在您可以指定 Composer 包以手动自动发现。请参阅 代码模块

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

  • 调试: Kint 已更新至 5.0.2。

  • 请求: 添加了新的 $request->getRawInputVar() 方法,用于从原始流中返回指定变量。请参阅 获取原始数据

  • 请求: 添加了新的 $request->is() 方法,用于查询请求类型。请参阅 确定请求类型

消息变更

  • 更新了英文语言字符串,使其更加一致。

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

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

变更

  • 配置
    • Config 类中所有原子类型属性都已进行类型化。

    • 请参阅 升级,了解有关更改默认值的详细信息。

  • 更改了 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 已被弃用。它将变为受保护的。请改用 Response::getCSP()

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

  • 公共属性 IncomingRequest::$uri 已弃用。它将被保护。请改用 IncomingRequest::getUri()

  • 公共属性 IncomingRequest::$config 已弃用。它将被保护。

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

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

已修复的错误

  • 修复了所有类型的 Prepared Queries 返回 Result 对象而不是写入类型查询的布尔值的错误。

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

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

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

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