Yii2 toArray 日期字段经过 getter 格式化,asArray 没有,如何统一输出

冬敏君_8429

冬敏君_8429

2026-10-20

966人浏览

原创

统一 yii2 中日期字段输出格式的核心方案是:小数据量用 toarray() 配合重写 fields() 方法,大数据量用 sql 层(如 date_format 或 expression)格式化,中间场景可封装 touniformarray() 辅助方法。

yii2 toarray 日期字段经过 getter 格式化,asarray 没有,如何统一输出

在 Yii2 中,toArray() 和 asArray() 对日期字段的处理确实不一致:前者会触发模型中定义的 getter(比如 getCreatedAtText()),后者则直接取原始数据库值(如 UNIX 时间戳或 Y-m-d H:i:s 字符串),不走 getter 逻辑。要统一输出格式,核心思路是「让 asArray 也能应用相同的格式化逻辑」,而不是反过来禁用 getter。

用 fields() 或 extraFields() 显式声明格式化字段

这是最推荐、最符合 Yii2 设计理念的方式。在模型中重写 fields(),对日期字段返回格式化后的值(调用 getter 或直接格式化),这样 toArray() 和 asArray() 都会按此规则输出:

  • 在模型类中添加:
public function fields()
{
  $fields = parent::fields();
  // 替换 createdAt 为格式化后的字符串
  $fields['createdAt'] = function ($model) {
    return $model->createdAt ? date('Y-m-d H:i', $model->createdAt) : null;
  };
  // 或复用已有 getter:
  // $fields['createdAt'] = 'createdAtText'; // 前提是已定义 getCreatedAtText()
  return $fields;
}

之后无论调用 $model->toArray() 还是 $query->asArray()->all()(注意:asArray 本身不走 fields,但如果你用 $model->toArray() 就能统一)——等等,这里需澄清一个关键点:

  • ActiveQuery::asArray() 返回的是纯数组,不经过模型实例,所以 它根本不会调用 fields() 或任何 getter;
  • 真正能统一控制的是 ActiveRecord::toArray()(即先查出模型对象,再转数组);
  • 若你坚持用 asArray()(例如大数据量为性能考虑),就得在查询层手动格式化。

在 Query 中用 select() + 表达式格式化日期

适用于必须用 asArray() 的场景。利用数据库函数(如 MySQL 的 DATE_FORMAT)或 Yii2 的 Expression 在 SQL 层完成格式化:

Yii Framework 2.0.51
Yii Framework 2.0.51

Yii Framework 2.0.51 官方 Basic 应用模板,适合旧项目兼容、升级验证和开发测试。

下载
  • 示例(MySQL):
$rows = Article::find()
  ->select(['id', 'title', 'DATE_FORMAT(created_at, "%Y-%m-%d %H:%i") as created_at'])
  ->asArray()
  ->all();
  • 跨数据库兼容写法(用 yii\db\Expression):
use yii\db\Expression;
// 根据 DB 类型调整函数名,如 PostgreSQL 用 TO_CHAR
$format = YII_ENV_DEV ? new Expression("DATE_FORMAT([[created_at]], '%Y-%m-%d %H:%i')") : ...;
$rows = Article::find()->select(['*', $format.' as created_at'])->asArray()->all();

封装一个统一的数组转换方法

避免到处写重复逻辑,可在模型基类或行为中提供一个方法,内部自动处理日期字段:

  • 例如在模型中加:
public function toUniformArray($withRelations = [])
{
  $arr = $this->toArray([], $withRelations);
  // 手动覆盖日期字段(适配已有 getter)
  foreach (['createdAt', 'updatedAt', 'publishedAt'] as $field) {
    if (isset($this->$field) && method_exists($this, 'get'.ucfirst($field).'Text')) {
      $arr[$field] = $this->{'get'.ucfirst($field).'Text'}();
    }
  }
  return $arr;
}

调用时:$model->toUniformArray(),确保所有日期都走 getter 格式化。

不建议的做法:重写 asArray() 行为

试图给 ActiveQuery 注入模型逻辑(如强制实例化模型再 toArray)会破坏 asArray 的性能初衷,且容易引发关联数据加载混乱,得不偿失。保持职责分离更稳妥。

统一的关键不在“让 asArray 走 getter”,而在于根据场景选对方式:小数据量用 toArray() + fields() 最干净;大数据量用 SQL 层格式化最高效;中间场景可封装辅助方法。三者目标一致,路径不同。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
ThinkPHP框架企业级应用开发实战
ThinkPHP框架企业级应用开发实战

本专题围绕 ThinkPHP 框架展开,系统讲解企业级应用开发的关键技术。内容涵盖 MVC 架构设计、路由与中间件配置、数据库操作与 ORM 使用、缓存优化、权限控制以及常用扩展集成。通过完整项目案例,帮助开发者掌握高效、可维护的 PHP 企业级应用开发方法。

2026.05.06

310

22

python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end='\n', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.27

2900

5

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

2026.02.03

249

24

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.31

2951

5

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

2025.10.31

554

9

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

2026.02.12

502

19

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

6359

3

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

2024.04.28

6547

8

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

2025.10.23

764

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Yii2.0框架开发实战视频教程
Yii2.0框架开发实战视频教程

共22课时 | 9.3万人学习

Yii2中文手册
Yii2中文手册

共0课时 | 0.6万人学习