yii2中对象转数组时整数变字符串,主因是pdo默认将数据库数值字段以字符串返回;解决方法包括:配置db组件关闭pdo::attr_stringify_fetches和pdo::attr_emulate_prepares,或在toarray()后手动类型转换,或在模型afterfind()中强制cast。

Yii2 中对象转数组时整数变字符串,主要是因为 Json::encode() 或数据库字段类型(如 MySQL 的 JSON 字段、TEXT 存储)在序列化过程中丢失了原始 PHP 类型;更常见的是模型属性被定义为 string 类型(比如通过 ActiveRecord 从数据库读取时,MySQL 的 INT 字段在 PDO 中默认以字符串形式返回),导致 toArray() 输出后仍是字符串。
确认数据来源是否已丢失类型
先检查原始模型属性值的类型:
- 用
gettype($model->id)或var_dump($model->id)查看实际类型 —— 很可能已是string - 如果是 ActiveRecord,检查对应数据库字段是否为
INT,但 PDO 默认未启用PDO::ATTR_STRINGIFY_FETCHES = false - 查看
phpinfo()或配置中pdo_mysql.default_socket无关,关键是PDO::ATTR_EMULATE_PREPARES和类型映射
在 toArray() 前手动转换关键字段
不依赖框架自动类型推断,主动做强制类型转换:
$data = $model->toArray(); $data['id'] = (int)$data['id']; $data['status'] = (int)$data['status']; $data['sort_order'] = (int)$data['sort_order'];
也可封装成方法复用:
public function toArrayWithIntegers($fields = [], $expand = [], $recursive = true)
{
$data = parent::toArray($fields, $expand, $recursive);
foreach (['id', 'status', 'score', 'version'] as $field) {
if (isset($data[$field])) {
$data[$field] = (int)$data[$field];
}
}
return $data;
}
统一配置 PDO 返回原生类型(推荐长期方案)
在 Yii2 配置 db 组件时,显式关闭字符串模拟:
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=testdb',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
'attributes' => [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_STRINGIFY_FETCHES => false,
],
],
✅ 这样 ActiveRecord 查询后,INT、TINYINT 等字段会以 int 类型返回,toArray() 自然保持整数。
⚠️ 注意:需确保 MySQL 版本 ≥ 5.6,PDO 扩展启用了 mysqlnd(现代 PHP 默认满足);若用 libmysql,该设置可能无效。
前端校验兼容字符串数字(兜底策略)
若后端无法立即修复,前端可宽松处理:
- 用
Number(value)或parseInt(value, 10)转换后再校验 - 校验逻辑改用
typeof value === 'number' || (!isNaN(value) && !isNaN(parseFloat(value))) - 避免直接用
===比较数字,改用==或转换后比较
但注意:这仅是临时缓解,不能替代后端类型修复,否则会影响排序、计算、API 规范性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










