Yii 2.0.26 REST接口默认不转换时间字段为时间戳,需在模型中重写fields()方法统一处理,如将created_at、updated_at转为strtotime()结果;formatter和全局配置对REST无效;自定义Serializer适用于多模型统一管控。

Yii 2.0.26 的 REST 接口默认不会自动将时间字段(如 created_at、updated_at)转为时间戳格式返回,它原样输出数据库存储值(通常是 'Y-m-d H:i:s' 字符串)。若需统一返回整型时间戳(如 1734589200),不能靠前端解析或手动赋值,而应通过序列化层统一控制。
在模型中重写 fields() 方法
这是最直接、最符合 REST 规范的做法。所有时间字段的格式转换逻辑集中在此,不影响数据库操作,也不干扰 TimestampBehavior。
- 在你的 ActiveRecord 模型(如
User)中重写fields():
<?php
public function fields()
{
$fields = parent::fields();
// 将 datetime 字段转为 int 时间戳
$fields['created_at'] = function ($model) {
return $model->created_at ? strtotime($model->created_at) : null;
};
$fields['updated_at'] = function ($model) {
return $model->updated_at ? strtotime($model->updated_at) : null;
};
return $fields;
}
- 注意:确保数据库字段类型是
DATETIME或TIMESTAMP,且 PHP 能正确解析该字符串(如'2026-10-20 14:58:00'); - 若字段可能为
NULL,务必判空,避免strtotime(null)返回-1; - 此方式对关联模型、嵌套数据同样生效,因为
yii\rest\Serializer会递归调用各模型的fields()。
全局配置 formatter(仅适用于视图/非 REST 场景)
Yii::$app->formatter 对 REST 接口的 JSON 响应不生效——它主要用于 GridView、DetailView 等小部件,或控制器中显式调用 asTimestamp()。在 ActiveController 的标准流程中,响应由 Serializer 直接序列化数组,绕过了 formatter。
- 不要尝试在
config/web.php中配'timestamp' => 'U'并期望它影响 API 输出; - 若你在非 REST 控制器里用
asJson()手动返回数据,可主动调用:
return $this->asJson([
'created_at' => Yii::$app->formatter->asTimestamp($model->created_at)
]);
使用自定义 Serializer(进阶、统一管控)
当项目中多个模型都需要时间戳化,且希望复用逻辑时,可继承 yii\rest\Serializer 并覆盖 serialize() 或 buildData() 方法。
- 新建类
app\serializers\TimestampSerializer,在buildData()中检测字段名含_at或_time的值,自动转strtotime(); - 在控制器中指定:
public $serializer = ['class' => 'app\serializers\TimestampSerializer']; - 优点:一次配置,全模型生效;缺点:增加抽象层级,调试稍复杂。
避免常见错误
以下做法看似简单,实则破坏 REST 一致性或引发隐患:
- 在控制器里
return ['created_at' => time()]:绕过Serializer,丢失分页、元数据、嵌套关联等 REST 特性; - 在
rules()中把时间字段设为integer类型:导致表单验证失败,且与数据库类型冲突; - 用
beforeSave把时间字段改为整型存库:违背 TimestampBehavior 设计初衷,且破坏 MySQL 自动更新能力(如ON UPDATE CURRENT_TIMESTAMP)。


















