从 4.5.8 升级到 4.6.0
请根据你的安装方式参考对应的升级指南:
重大变更
异常类变更
部分类抛出的异常类已变更,部分异常类的父类已调整。详见 更新日志。
如果你的代码捕获了这些异常,请修改对应的异常类。
Time::createFromTimestamp() 时区变更
当未显式传递时区参数时,Time::createFromTimestamp() 现在返回 UTC 时区的 Time 实例。在 v4.4.6 至 v4.6.0 之前的版本中,返回的是当前设置的默认时区的 Time 实例。
此行为变更是为了与 PHP 8.4 新增的 DateTimeInterface::createFromTimestamp()
方法行为保持一致。
如需保持默认时区,需显式传递时区作为第二个参数:
use CodeIgniter\I18n\Time;
$time = Time::createFromTimestamp(1501821586, date_default_timezone_get());
Time 保留微秒
在先前版本中,Time 在某些情况下会丢失微秒。这些问题已修复。
由于修复,Time
的比较结果可能发生变化:
use CodeIgniter\I18n\Time;
$time1 = new Time('2024-01-01 12:00:00.654321');
$time2 = new Time('2024-01-01 12:00:00');
$time1->equals($time2);
// Before: true
// After: false
在此情况下,你需要手动移除微秒:
use CodeIgniter\I18n\Time;
$time1 = new Time('2024-01-01 12:00:00.654321');
$time2 = new Time('2024-01-01 12:00:00');
// Removes the microseconds.
$time1 = Time::createFromFormat(
'Y-m-d H:i:s',
$time1->format('Y-m-d H:i:s'),
$time1->getTimezone(),
);
$time1->equals($time2);
// Before: true
// After: true
以下情况现在会保留微秒:
use CodeIgniter\I18n\Time;
$time = Time::createFromFormat('Y-m-d H:i:s.u', '2024-07-09 09:13:34.654321');
echo $time->format('Y-m-d H:i:s.u');
// Before: 2024-07-09 09:13:34.000000
// After: 2024-07-09 09:13:34.654321
use CodeIgniter\I18n\Time;
$time = new Time('1 hour ago');
echo $time->format('Y-m-d H:i:s.u');
// Before: 2024-07-26 21:05:57.000000
// After: 2024-07-26 21:05:57.857235
注意:表示当前时间的 Time
实例在此前版本中已保留微秒。
use CodeIgniter\I18n\Time;
$time = Time::now();
echo $time->format('Y-m-d H:i:s.u');
// Before: 2024-07-26 21:39:32.249072
// After: 2024-07-26 21:39:32.249072
返回 int
类型的方法仍会丢失微秒:
use CodeIgniter\I18n\Time;
$time1 = new Time('2024-01-01 12:00:00');
echo $time1->getTimestamp(); // 1704110400
$time2 = new Time('2024-01-01 12:00:00.654321');
echo $time2->getTimestamp(); // 1704110400
Time::setTimestamp() 行为修正
在先前版本中,对非默认时区的 Time 实例调用 Time::setTimestamp()
可能返回错误日期/时间的实例。
此问题已修复,现在行为与 DateTimeImmutable
一致:
use CodeIgniter\I18n\Time;
// The Application Timezone is "UTC".
// Set $time1 timezone to "America/Chicago".
$time1 = Time::parse('2024-08-20', 'America/Chicago');
// The timestamp is "2024-08-20 00:00" in "UTC".
$stamp = strtotime('2024-08-20'); // 1724112000
// But $time2 timezone is "America/Chicago".
$time2 = $time1->setTimestamp($stamp);
echo $time2->format('Y-m-d H:i:s P');
// Before: 2024-08-20 00:00:00 -05:00
// After: 2024-08-19 19:00:00 -05:00
注意:使用默认时区时行为未改变:
use CodeIgniter\I18n\Time;
// The Application Timezone is "America/Chicago".
// $time1 timezone is "America/Chicago".
$time1 = Time::parse('2024-08-20');
// The timestamp is "2024-08-20 00:00" in "America/Chicago".
$stamp = strtotime('2024-08-20'); // 1724130000
// $time2 timezone is also "America/Chicago".
$time2 = $time1->setTimestamp($stamp);
echo $time2->format('Y-m-d H:i:s P');
// Before: 2024-08-20 00:00:00 -05:00
// After: 2024-08-20 00:00:00 -05:00
注册器的脏数据修复
为防止 注册器 的自动发现机制重复执行,当 Registrar 类被加载或实例化时,如果实例化了 Config 类(继承自 CodeIgniter\Config\BaseConfig
),将会抛出 ConfigException
。
这是因为注册器的自动发现机制若重复执行,可能导致 Config 类属性被重复赋值。
所有 Registrar 类(所有命名空间中的 Config/Registrar.php)必须修改为在加载或实例化时不实例化任何 Config 类。
如果你使用的包/模块包含此类 Registrar 类,需要修复这些包/模块中的 Registrar 类。
以下是不再适用的代码示例:
<?php
namespace CodeIgniter\Shield\Config;
use Config\App;
class Registrar
{
public function __construct()
{
$config = new App(); // Bad. When this class is instantiated, Config\App will be instantiated.
// Does something.
}
public static function Pager(): array
{
return [
'templates' => [
'module_pager' => 'MyModule\Views\Pager',
],
];
}
public static function hack(): void
{
$config = config('Cache');
// Does something.
}
}
Registrar::hack(); // Bad. When this class is loaded, Config\Cache will be instantiated.
Session ID (SID) 变更
现在 Session 库 强制使用 PHP 默认的 32 字符 SID(每字符 4 位熵)。此变更是为了匹配 PHP 9 的行为。
即始终使用以下设置:
session.sid_bits_per_character = 4
session.sid_length = 32
先前版本遵循 PHP ini 设置。因此此变更可能改变你的 SID 长度。
如无法接受此变更,请自定义 Session 类库。
接口变更
部分接口已变更。实现这些接口的类应更新其 API 以反映变更。详见 更新日志。
方法签名变更
部分方法签名已变更。继承这些方法的类应更新其 API 以反映变更。详见 更新日志。
移除已弃用项
部分已弃用项已被移除。如仍在使用这些项或继承这些类,请更新代码。详见 更新日志。
重大增强
过滤器变更
Filters
类已变更,允许在 before 或 after 阶段多次运行相同过滤器(使用不同参数)。
如继承 Filters
类,需根据以下变更进行调整:
数组属性
$filters
和$filtersClasses
的结构已变更属性
$arguments
和$argumentsClass
已停用Filters
已调整为不重复实例化相同过滤器类。如过滤器类在 before 和 after 阶段均使用,将复用同一实例
项目文件
项目空间 (根目录、app、public、writable)中的部分文件已更新。由于这些文件位于 system 范围之外,需手动干预才能更新。
可通过第三方 CodeIgniter 模块辅助合并项目空间变更:在 Packagist 上探索。
内容变更
以下文件有重大变更(包含弃用或视觉调整),建议将更新版本合并至你的应用:
配置
- app/Config/Feature.php
Config\Feature::$autoRoutesImproved
已变更为true
新增
Config\Feature::$strictLocaleNegotiation
- app/Config/Routing.php
Config\Routing::$translateUriToCamelCase
已变更为true
所有变更
以下是 项目空间 中所有发生变更的文件列表(多数为不影响运行的注释或格式调整):
app/Config/Cache.php
app/Config/Constants.php
app/Config/Database.php
app/Config/Feature.php
app/Config/Format.php
app/Config/Kint.php
app/Config/Routing.php
app/Config/Security.php
app/Views/errors/html/debug.css
app/Views/errors/html/error_400.php
preload.php
public/index.php
spark