在 yii 框架中,需通过 getattribute()、显式声明 integer 类型或原生 sql 查询获取时间戳字段原始值,避免自动类型转换导致 unix 时间戳丢失。

在 Yii 框架中,模型的时间戳字段(如 created_at、updated_at)通常被自动转换为 DateTime 对象或格式化字符串,这会导致原始数据库值(如 UNIX 时间戳整数或未格式化的 DATETIME 字符串)丢失。若需获取未经框架处理的原始值(例如直接读取数据库存入的 int 型时间戳),需绕过 Yii 的自动类型转换机制。
确认字段是否被 ActiveRecord 自动类型转换
Yii 2.0+ 默认对 datetime、timestamp 类型字段启用自动类型转换(通过 Schema::TYPE_DATETIME 等映射触发)。若数据库字段是 INT(11) 存储 UNIX 时间戳,且模型未显式声明为 integer 类型,则可能被误转为 DateTime 或字符串。
- 检查数据库表结构:确认字段实际类型是
INT还是DATETIME/TIMESTAMP - 查看模型中的
rules():避免为时间戳字段添加'datetime'验证器或'date'格式化规则 - 检查
attributeTypes()或数据库 Schema 缓存:确保字段类型映射准确(如INT→Schema::TYPE_INTEGER)
使用 getAttribute() 绕过访问器和类型转换
Yii 的 $model->attr 语法会触发 getter 方法和类型转换;而 $model->getAttribute('attr') 直接从内部属性数组 $_attributes 中读取原始值(即数据库查询后未处理的值)。
- 适用于已加载/查询完成的模型实例
- 若字段在
$_attributes中仍为字符串(如'2024-05-20 10:30:00'),说明数据库返回的就是该格式,需进一步处理 - 示例:
$rawTs = $model->getAttribute('created_at');—— 返回原始数据库值
强制声明属性类型为 integer(针对 UNIX 时间戳字段)
若数据库字段为 INT 存储 UNIX 时间戳,应在模型中显式覆盖类型声明,阻止 Yii 自动转为 DateTime:
- 重写
attributes()方法,为对应字段指定Schema::TYPE_INTEGER - 或在
init()中调用$this->attachBehavior('timestamp', [...])时禁用自动格式化 - 更稳妥方式:在迁移中定义字段为
$this->integer(),并在模型rules()中声明['created_at', 'integer']
查询时跳过 ActiveRecord,直连 DB 获取原始值
对必须 100% 保证原始性的场景(如审计、日志比对),可绕过模型层,用 Yii::$app->db 执行原生查询:
$ts = Yii::$app->db->createCommand('SELECT created_at FROM user WHERE id=:id', [':id' => 123])->queryScalar();- 返回值类型完全由数据库驱动决定(如 PDO 返回 int 或 string,取决于字段类型和 PDO 设置)
- 适合单次、低频、高确定性需求,不推荐高频使用











