hyperf中关于时间的设定
下面我来总结这三者的用法和它们之间的关系:
1. protected ?string $dateFormat = 'U';
作用:
- 定义数据库日期字段的存储格式
- ‘U’ 表示使用 Unix 时间戳格式(秒级,10位数字)
影响范围:
- 决定了模型从数据库读取和写入数据时的格式
- 当使用
save()
方法保存模型时,日期时间会按此格式存储到数据库
关键点:
- 这是日期在数据库层面的表示形式
- 常用格式有 ‘Y-m-d H:i:s’(MySQL 标准日期时间)和 ‘U’(Unix 时间戳)
2. $casts = ['created_at' => 'datetime']
作用:
- 定义数据在 PHP 代码中的类型
- 自动将数据库值转换为指定的 PHP 类型
影响范围:
- 从数据库读取时,
datetime
会将时间戳转换为 DateTime 对象 - 访问属性时会得到 DateTime 对象,而不是原始的时间戳
类型选项:
datetime
: 转换为 DateTime 对象,允许日期操作timestamp
: 保持为时间戳整数date
: 只有日期部分,没有时间immutable_datetime
: 不可变的 DateTime 对象
3. function serializeDate(DateTimeInterface $date)
作用:
- 控制模型序列化时日期时间的输出格式
- 决定
toArray()
和toJson()
方法中日期的展示方式
影响范围:
- 仅影响模型转换为数组或 JSON 时的输出
- 不影响数据库存储或属性访问
执行时机:
- 当调用
toArray()
或toJson()
方法时 - 当使用
response()->json($model)
时
完整工作流程
-
数据库存储:
- 由
$dateFormat = 'U'
决定以时间戳格式存储
- 由
-
数据从数据库读取:
- 读取原始时间戳值(如 1742887304)
- 如果有
casts
,将根据casts
配置转换:'created_at' => 'datetime'
会将时间戳转换为 DateTime 对象'created_at' => 'timestamp'
会保持时间戳整数
-
属性访问:
$model->created_at
会根据casts
返回相应类型datetime
类型返回 DateTime 对象timestamp
类型返回整数
-
序列化输出:
- 当模型转换为数组或 JSON 时
- 对于
datetime
类型,会调用serializeDate()
方法 - 返回方法中定义的格式,如
'Y-m-d H:i:s'
- 对于
timestamp
类型,直接输出整数,不调用serializeDate()
最佳实践
根据您的需求选择配置:
-
如果想在数据库中存储时间戳,但 API 输出格式化日期:
protected ?string $dateFormat = 'U'; // 数据库存储为时间戳 protected array $casts = ['created_at' => 'datetime']; // PHP 中使用 DateTime protected function serializeDate(DateTimeInterface $date): string|int { return $date->format('Y-m-d H:i:s'); // API 输出格式化日期 }
-
如果想在数据库中存储时间戳,API 也输出时间戳:
protected ?string $dateFormat = 'U'; // 数据库存储为时间戳 protected array $casts = ['created_at' => 'timestamp']; // PHP 中使用时间戳 // 不需要 serializeDate 方法,因为 timestamp 类型不会调用它
-
如果想在数据库中存储格式化日期,API 也输出格式化日期:
protected ?string $dateFormat = 'Y-m-d H:i:s'; // 数据库存储为格式化日期 protected array $casts = ['created_at' => 'datetime']; // PHP 中使用 DateTime protected function serializeDate(DateTimeInterface $date): string|int { return $date->format('Y-m-d H:i:s'); // API 输出格式化日期 }