|
| 1 | +############# |
| 2 | +版本 4.6.0 |
| 3 | +############# |
| 4 | + |
| 5 | +发布日期:2025 年 1 月 19 日 |
| 6 | + |
| 7 | +**CodeIgniter4 的 4.6.0 版本发布** |
| 8 | + |
| 9 | +.. contents:: |
| 10 | + :local: |
| 11 | + :depth: 3 |
| 12 | + |
| 13 | +******** |
| 14 | +重大变更 |
| 15 | +******** |
| 16 | + |
| 17 | +行为变更 |
| 18 | +======== |
| 19 | + |
| 20 | +.. _v460-behavior-changes-exceptions: |
| 21 | + |
| 22 | +异常处理 |
| 23 | +-------- |
| 24 | + |
| 25 | +异常类已重新设计。详细信息请参阅 :ref:`exception-design`。 |
| 26 | +以下是相应的破坏性变更: |
| 27 | + |
| 28 | +- ``Validation::setRule()`` 现在抛出 ``CodeIgniter\Exceptions\InvalidArgumentException`` 而非 ``TypeError`` |
| 29 | +- ``CriticalError`` 现在继承自 ``CodeIgniter\Exceptions\RuntimeException`` 而非 ``Error`` |
| 30 | +- ``DatabaseException`` 现在继承自 ``CodeIgniter\Exceptions\RuntimeException`` 而非 ``Error`` |
| 31 | +- ``ConfigException`` 现在继承自 ``CodeIgniter\Exceptions\RuntimeException`` 而非 ``CodeIgniter\Exceptions\CriticalError`` |
| 32 | +- ``TestException`` 现在继承自 ``CodeIgniter\Exceptions\LogicException`` 而非 ``CodeIgniter\Exceptions\CriticalError`` |
| 33 | + |
| 34 | +过滤器变更 |
| 35 | +--------------- |
| 36 | + |
| 37 | +``Filters`` 类已修改,允许在 before 或 after 阶段使用不同参数多次运行相同过滤器。详细信息请参阅 :ref:`Upgrading Guide <upgrade-460-filters-changes>`。 |
| 38 | + |
| 39 | +注册器 |
| 40 | +---------- |
| 41 | + |
| 42 | +新增检查以防止注册器自动发现机制重复运行。若重复执行将抛出异常。详细信息请参阅 :ref:`upgrade-460-registrars-with-dirty-hack`。 |
| 43 | + |
| 44 | +Time::createFromTimestamp() |
| 45 | +--------------------------- |
| 46 | + |
| 47 | +``Time::createFromTimestamp()`` 处理时区的方式已变更。若未显式传递 ``$timezone`` 参数,实例时区将设为 UTC(此前使用系统默认时区)。详细信息请参阅 :ref:`Upgrading Guide <upgrade-460-time-create-from-timestamp>`。 |
| 48 | + |
| 49 | +支持微秒的时间处理 |
| 50 | +---------------------- |
| 51 | + |
| 52 | +修复了 ``Time`` 类中部分方法丢失微秒的缺陷。详细信息请参阅 :ref:`Upgrade Guide <upgrade-460-time-keeps-microseconds>`。 |
| 53 | + |
| 54 | +Time::setTimestamp() |
| 55 | +-------------------- |
| 56 | + |
| 57 | +``Time::setTimestamp()`` 的行为已修正。详细信息请参阅 :ref:`Upgrade Guide <upgrade-460-time-set-timestamp>`。 |
| 58 | + |
| 59 | +非 HTML 请求的错误报告 |
| 60 | +------------------------------------ |
| 61 | + |
| 62 | +旧版本中,当请求不接受 HTML 时,CodeIgniter 仅在 ``development`` 和 ``testing`` 环境下显示错误详情。 |
| 63 | + |
| 64 | +由于在自定义环境中无法显示错误详情,现修正此行为:只要 PHP 配置中的 ``display_errors`` 启用即显示错误详情。 |
| 65 | + |
| 66 | +此修正后,HTML 请求与非 HTML 请求的错误详情显示条件现已统一。 |
| 67 | + |
| 68 | +会话 ID (SID) |
| 69 | +---------------- |
| 70 | + |
| 71 | +现在 ``Session`` 类库强制使用 PHP 默认的 32 字符 SID(每字符 4 位熵值)。详细信息请参阅 :ref:`Upgrade Guide <upgrade-460-sid-change>`。 |
| 72 | + |
| 73 | +.. _v460-interface-changes: |
| 74 | + |
| 75 | +响应头处理 |
| 76 | +---------- |
| 77 | + |
| 78 | +通过 ``Response`` 类设置的响应头将覆盖通过 PHP ``header()`` 函数设置的响应头。 |
| 79 | + |
| 80 | +旧版本中,``Response`` 类设置的响应头会追加到现有响应头(无法修改),当存在互斥指令的同名响应头时可能导致意外行为。 |
| 81 | + |
| 82 | +例如,session 会自动通过 ``header()`` 函数设置响应头: |
| 83 | + |
| 84 | +.. code-block:: none |
| 85 | +
|
| 86 | + Expires: Thu, 19 Nov 1981 08:52:00 GMT |
| 87 | + Cache-Control: no-store, no-cache, must-revalidate |
| 88 | + Pragma: no-cache |
| 89 | +
|
| 90 | +若再次设置 **Expires** 响应头将导致重复: |
| 91 | + |
| 92 | +.. code-block:: php |
| 93 | +
|
| 94 | + $response->removeHeader('Expires'); // 无效操作 |
| 95 | + return $response->setHeader('Expires', 'Sun, 17 Nov 2024 14:17:37 GMT'); |
| 96 | +
|
| 97 | +响应头结果: |
| 98 | + |
| 99 | +.. code-block:: none |
| 100 | +
|
| 101 | + Expires: Thu, 19 Nov 1981 08:52:00 GMT |
| 102 | + // ... |
| 103 | + Expires: Sun, 17 Nov 2024 14:17:37 GMT |
| 104 | +
|
| 105 | +此时浏览器可能无法正确识别有效响应头。本版本变更后,旧响应头将被覆盖: |
| 106 | + |
| 107 | +.. code-block:: none |
| 108 | +
|
| 109 | + Cache-Control: no-store, no-cache, must-revalidate |
| 110 | + Pragma: no-cache |
| 111 | + Expires: Sun, 17 Nov 2024 14:17:37 GMT |
| 112 | +
|
| 113 | +接口变更 |
| 114 | +================= |
| 115 | + |
| 116 | +.. note:: 只要你未扩展相关 CodeIgniter 核心类或实现这些接口,所有变更均向后兼容且无需调整。 |
| 117 | + |
| 118 | +- **Router:** 以下方法已加入 ``RouteCollectionInterface`` 接口: |
| 119 | + |
| 120 | + - ``getDefaultNamespace()`` |
| 121 | + - ``getRoutesOptions()`` |
| 122 | + - ``setHTTPVerb()`` |
| 123 | + - ``isFiltered()`` |
| 124 | + - ``getFiltersForRoute()`` |
| 125 | + |
| 126 | +.. _v460-method-signature-changes: |
| 127 | + |
| 128 | +方法签名变更 |
| 129 | +======================== |
| 130 | + |
| 131 | +- **Router:** ``DefinedRouteCollector`` 的构造函数参数类型由 ``RouteCollection`` 改为 ``RouteCollectionInterface`` |
| 132 | +- **View:** ``renderSection()`` 方法的返回类型改为 ``string``,且不再调用 ``echo`` |
| 133 | +- **Time:** ``createFromTimestamp()`` 的首个参数类型由 ``int`` 改为 ``int|float``,并新增返回类型 ``static`` |
| 134 | +- **Helpers:** 更新了 ``character_limiter()`` 的参数命名。若使用命名参数需更新函数调用 |
| 135 | + |
| 136 | +移除类型定义 |
| 137 | +------------------------ |
| 138 | + |
| 139 | +- **Database:** |
| 140 | + - 移除 ``BaseConnection::escapeIdentifier()`` 首个参数的 ``string`` 类型 |
| 141 | + - 移除 ``BaseConnection::getFieldNames()`` 和 ``SQLite3\Connection::getFieldNames()`` 首个参数的 ``string`` 类型 |
| 142 | + - 移除 ``BaseConnection::_listColumns()``、``MySQLi\Connection::_listColumns()``、``OCI8\Connection::_listColumns()``、``Postgre\Connection::_listColumns()``、``SQLSRV\Connection::_listColumns()``、``SQLite3\Connection::_listColumns()`` 首个参数的 ``string`` 类型 |
| 143 | + |
| 144 | +.. _v460-removed-deprecated-items: |
| 145 | + |
| 146 | +移除已弃用项 |
| 147 | +======================== |
| 148 | + |
| 149 | +- **API:** 移除 ``CodeIgniter\API\ResponseTrait`` 中已弃用的 ``failValidationError()`` 方法,改用 ``failValidationErrors()`` |
| 150 | +- **HTTP:** 移除 ``CodeIgniter\HTTP\Response`` 和 ``ResponseInterface`` 中已弃用的 ``getReason()`` 方法,改用 ``getReasonPhrase()`` |
| 151 | +- **Logger:** 移除已弃用的 ``CodeIgniter\Log\Logger::cleanFilenames()`` 和 ``CodeIgniter\Test\TestLogger::cleanup()`` 方法,改用 ``clean_path()`` 函数 |
| 152 | +- **Router:** 移除已弃用的 ``CodeIgniter\Router\Exceptions\RedirectException`` 异常类,改用 ``CodeIgniter\HTTP\Exceptions\RedirectException`` |
| 153 | +- **Constants:** 移除已弃用的 ``EVENT_PRIORITY_*`` 常量,改用类常量 ``CodeIgniter\Events\Events::PRIORITY_LOW``、``CodeIgniter\Events\Events::PRIORITY_NORMAL`` 和 ``CodeIgniter\Events\Events::PRIORITY_HIGH`` |
| 154 | +- **View:** 移除已弃用的 ``CodeIgniter\View\View::$currentSection`` 属性 |
| 155 | +- **Config:** 移除已弃用的 ``Config\Cache::$storePath`` 属性,改用 ``Config\Cache::$file['storePath']`` |
| 156 | +- **Formatter:** 移除已弃用的 ``Config\Format::getFormatter()`` 方法,改用 ``CodeIgniter\Format\Format::getFormatter()`` |
| 157 | +- **Security:** 移除 ``Config\Security::$samesite`` 配置项,改用 ``Config\Cookie::$samesite`` |
| 158 | +- **Cookie:** 移除 ``CodeIgniter\Cookie\CookieStore`` 中的 ``dispatch()``、``setRawCookie()``、``setCookie()`` 方法,这些方法已移至 ``CodeIgniter\HTTP\ResponseTrait`` |
| 159 | + |
| 160 | +************ |
| 161 | +功能增强 |
| 162 | +************ |
| 163 | + |
| 164 | +发布器 |
| 165 | +========= |
| 166 | + |
| 167 | +- ``Publisher::discover()`` 新增第二个参数(``namespace``)用于指定搜索发布器的命名空间。详细信息请参阅 :ref:`discovery-in-a-specific-namespace`。 |
| 168 | + |
| 169 | +异常处理 |
| 170 | +========== |
| 171 | + |
| 172 | +异常类已重新设计。详细信息请参阅 :ref:`exception-design`。 |
| 173 | +新增以下异常类: |
| 174 | + |
| 175 | +- ``CodeIgniter\Exceptions\LogicException`` |
| 176 | +- ``CodeIgniter\Exceptions\RuntimeException`` |
| 177 | +- ``CodeIgniter\Exceptions\BadFunctionCallException`` |
| 178 | +- ``CodeIgniter\Exceptions\BadMethodCallException`` |
| 179 | +- ``CodeIgniter\Exceptions\InvalidArgumentException`` |
| 180 | + |
| 181 | +新增以下异常接口: |
| 182 | + |
| 183 | +- ``CodeIgniter\Files\Exceptions\ExceptionInterface`` |
| 184 | +- ``CodeIgniter\HTTP\Exceptions\ExceptionInterface`` |
| 185 | +- ``CodeIgniter\Router\Exceptions\ExceptionInterface`` |
| 186 | + |
| 187 | +非 HTML 响应的异常显示现基于 PHP 的 ``display_errors`` 设置,而非硬编码环境判断。 |
| 188 | + |
| 189 | +命令行工具 |
| 190 | +========== |
| 191 | + |
| 192 | +- ``spark routes`` 和 ``spark filter:check`` 命令现显示过滤器参数 |
| 193 | +- ``spark filter:check`` 命令现显示过滤器类名 |
| 194 | +- 新增 ``spark lang:sync`` 命令用于同步翻译文件。详细信息请参阅 :ref:`sync-translations-command` |
| 195 | +- ``spark phpini:check`` 命令新增可选 ``opcache`` 参数,用于显示 opcache 设置信息 |
| 196 | + |
| 197 | +路由 |
| 198 | +======= |
| 199 | + |
| 200 | +- 现可在限制路由时指定多个主机名 |
| 201 | + |
| 202 | +协商器 |
| 203 | +========== |
| 204 | + |
| 205 | +- 新增特性开关 ``Feature::$strictLocaleNegotiation`` 用于启用严格区域匹配。 |
| 206 | + 旧版本中,对于 ``Accept-language: en-US,en-GB;q=0.9`` 的请求会返回首个允许的语言 ``en``(而非精确匹配 ``en-US`` 或 ``en-GB``)。 |
| 207 | + 设为 ``true`` 后启用基于语言代码('en' - ISO 639-1)和区域代码('en-US' - ISO 639-1 + ISO 3166-1 alpha)的精确匹配。 |
| 208 | + |
| 209 | +分页 |
| 210 | +========== |
| 211 | + |
| 212 | +- 新增获取当前页总条目数和范围的功能。 |
| 213 | + 详细信息请参阅 :ref:`Displaying the Number of Items on the Page <displaying-the-number-of-items-on-the-page>`。 |
| 214 | + |
| 215 | +数据库 |
| 216 | +======== |
| 217 | + |
| 218 | +其他改进 |
| 219 | +-------- |
| 220 | + |
| 221 | +- 为 MySQLi 新增 ``foundRows`` 配置项以使用 ``MYSQLI_CLIENT_FOUND_ROWS`` |
| 222 | +- 新增 ``BaseConnection::resetTransStatus()`` 方法用于重置事务状态。详细信息请参阅 :ref:`transactions-resetting-transaction-status` |
| 223 | +- SQLite3 新增 ``synchronous`` 配置项,用于调整事务期间磁盘刷写策略。结合 ``WAL`` 日志模式时可有效优化性能 |
| 224 | + |
| 225 | +类库 |
| 226 | +========= |
| 227 | + |
| 228 | +- **File:** ``File`` 类新增 ``getSizeByBinaryUnit()`` 和 ``getSizeByMetricUnit()`` 方法。 |
| 229 | + 详细信息请参阅 :ref:`File::getSizeByBinaryUnit() <file-get-size-by-binary-unit>` 和 :ref:`File::getSizeByMetricUnit() <file-get-size-by-metric-unit>`。 |
| 230 | +- **FileCollection:** ``FileCollection`` 类新增 ``retainMultiplePatterns()`` 方法。 |
| 231 | + 详细信息请参阅 :ref:`FileCollection::retainMultiplePatterns() <file-collections-retain-multiple-patterns>`。 |
| 232 | +- **Validation:** ``FileRules`` 类新增 ``min_dims`` 验证规则。 |
| 233 | + 详细信息请参阅 :ref:`Validation <rules-for-file-uploads>`。 |
| 234 | +- **Validation:** ``is_unique`` 和 ``is_not_unique`` 规则现允许在首个参数中指定 ``dbGroup``。 |
| 235 | + 详细信息请参阅 :ref:`Validation <rules-for-general-use>`。 |
| 236 | + |
| 237 | +其他 |
| 238 | +====== |
| 239 | + |
| 240 | +- **Filters:** 现可在 before 或 after 阶段使用不同参数多次执行同一过滤器 |
| 241 | +- **Services:** 新增 ``BaseService::resetServicesCache()`` 方法用于重置服务缓存。 |
| 242 | + 详细信息请参阅 :ref:`resetting-services-cache` |
| 243 | +- **Errors:** 新增默认的 "400 Bad Request" 错误页面 |
| 244 | + |
| 245 | +*************** |
| 246 | +消息变更 |
| 247 | +*************** |
| 248 | + |
| 249 | +- 新增 ``Validation.min_dims`` 消息 |
| 250 | +- 新增 ``Errors.badRequest`` 和 ``Errors.sorryBadRequest`` 消息 |
| 251 | + |
| 252 | +******** |
| 253 | +变更列表 |
| 254 | +******** |
| 255 | + |
| 256 | +异常处理 |
| 257 | +========== |
| 258 | + |
| 259 | +异常类已重新设计。详细信息请参阅 :ref:`exception-design`。 |
| 260 | +以下是相应变更: |
| 261 | + |
| 262 | +- 缓存处理器类的 ``deleteMatching()`` 方法现抛出 ``CodeIgniter\Exceptions\BadMethodCallException`` 而非 ``Exception`` |
| 263 | +- ``Cache\ResponseCache::get()`` 现抛出 ``CodeIgniter\Exceptions\RuntimeException`` 而非 ``Exception`` |
| 264 | +- 原抛出 ``RuntimeException`` 的类现改为抛出 ``CodeIgniter\Exceptions\RuntimeException`` |
| 265 | +- 原抛出 ``InvalidArgumentException`` 的类现改为抛出 ``CodeIgniter\Exceptions\InvalidArgumentException`` |
| 266 | +- 原抛出 ``LogicException`` 的类现改为抛出 ``CodeIgniter\Exceptions\LogicException`` |
| 267 | +- 原抛出 ``BadMethodCallException`` 的类现改为抛出 ``CodeIgniter\Exceptions\BadMethodCallException`` |
| 268 | +- 原抛出 ``BadFunctionCallException`` 的类现改为抛出 ``CodeIgniter\Exceptions\BadFunctionCallException`` |
| 269 | +- ``RedirectException`` 现继承自 ``CodeIgniter\Exceptions\RuntimeException`` 而非 ``Exception`` |
| 270 | +- ``PageNotFoundException`` 现继承自 ``CodeIgniter\Exceptions\RuntimeException`` 而非 ``OutOfBoundsException`` |
| 271 | + |
| 272 | +************ |
| 273 | +已弃用项 |
| 274 | +************ |
| 275 | + |
| 276 | +- **Filters:** |
| 277 | + - 弃用 ``Filters`` 的 ``$arguments`` 和 ``$argumentsClass`` 属性(不再使用) |
| 278 | + - 弃用 ``Filters::getArguments()`` 方法(不再使用) |
| 279 | +- **File:** |
| 280 | + - 弃用 ``File`` 的 ``getSizeByUnit()`` 方法,改用 ``getSizeByBinaryUnit()`` 或 ``getSizeByMetricUnit()`` |
| 281 | + |
| 282 | +************ |
| 283 | +已修复的缺陷 |
| 284 | +************ |
| 285 | + |
| 286 | +- **Response:** |
| 287 | + - 现在通过 ``Response`` 类设置的响应头将优先覆盖通过 PHP ``header()`` 函数手动设置的响应头 |
| 288 | +- **View:** 为 ``View::excerpt()`` 新增多字节字符串支持 |
| 289 | +- **Helpers:** 为 ``excerpt()`` 新增多字节字符串支持 |
| 290 | + |
| 291 | +完整缺陷修复列表请查阅仓库的 |
| 292 | +`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_。 |
0 commit comments