在PHP开发场景中,接口返回数据、数据库查询的fetchObject结果等经常会以stdClass对象数组的形式呈现,这类数据结构无法直接调用数组去重相关的函数,因此需要先将其转换为关联数组再处理。如果转换过程不规范,很容易出现属性丢失、数据类型异常等问题,影响后续去重逻辑的正确性。

stdClass对象数组的特点
stdClass是PHP中的内置空类,通常作为匿名对象使用,它的属性可以直接通过对象操作符访问,但不具备数组的索引访问能力,也没有数组的相关内置函数支持。一个典型的stdClass对象数组示例如下:
<?php
$objArr = [
(object)['id' => 1, 'name' => '张三', 'age' => 20],
(object)['id' => 2, 'name' => '李四', 'age' => 22],
(object)['id' => 1, 'name' => '张三', 'age' => 20],
(object)['id' => 3, 'name' => '王五', 'age' => 25]
];
?>
安全转换方法
方法一:类型强制转换
PHP支持将对象直接强制转换为数组,这种方式简单高效,适合属性都是公开且不需要特殊处理的场景。转换后对象的属性会成为数组的键,属性值对应数组的值。
<?php
$assocArr = [];
foreach ($objArr as $obj) {
// 强制将stdClass对象转换为关联数组
$assocArr[] = (array)$obj;
}
// 打印转换结果
print_r($assocArr);
?>
这种方式的优点是性能高,代码简洁,但需要注意如果对象属性是私有或者受保护的,转换后键名会带有特殊的访问修饰符前缀,需要额外处理。
方法二:json_encode与json_decode组合
通过先将对象序列化为JSON字符串,再反序列化为数组的方式,可以规避属性访问权限的问题,转换结果更稳定,适合复杂对象场景。
<?php
$assocArr = [];
foreach ($objArr as $obj) {
// 先编码为JSON字符串,再解码为关联数组
$jsonStr = json_encode($obj);
$assocArr[] = json_decode($jsonStr, true);
}
// 打印转换结果
print_r($assocArr);
?>
这种方式的缺点是会额外消耗序列化和反序列化的性能,如果数据量较大,效率会比强制转换低一些。
方法三:遍历手动赋值
如果需要过滤部分属性或者做格式转换,可以遍历对象属性手动赋值到新数组,这种方式灵活性最高,可以完全控制转换后的数组结构。
<?php
$assocArr = [];
foreach ($objArr as $obj) {
$temp = [];
// 遍历对象所有属性赋值
foreach ($obj as $key => $value) {
$temp[$key] = $value;
}
$assocArr[] = $temp;
}
// 打印转换结果
print_r($assocArr);
?>
转换后去重处理
转换为关联数组后,可以根据去重需求选择对应的函数。如果是根据整个数组内容去重,可以使用array_unique函数,注意需要设置排序标志保证去重正确。
<?php // 接上面的转换结果$assocArr // 对整个数组去重,SORT_REGULAR表示按照常规方式比较 $uniqueArr = array_unique($assocArr, SORT_REGULAR); // 重置数组索引 $uniqueArr = array_values($uniqueArr); print_r($uniqueArr); ?>
如果是根据某个特定字段去重,比如根据id字段去重,可以先提取该字段作为临时键,再去重后重置数组。
<?php
// 接上面的转换结果$assocArr
$uniqueArr = [];
foreach ($assocArr as $item) {
// 以id为键,自动覆盖重复项
$uniqueArr[$item['id']] = $item;
}
// 重置数组索引
$uniqueArr = array_values($uniqueArr);
print_r($uniqueArr);
?>
方案选择建议
- 如果对象都是公开属性,数据量较大,优先选择类型强制转换,性能最优。
- 如果对象包含私有属性或者需要兼容复杂结构,选择json_encode与json_decode组合方案。
- 如果需要过滤属性或者做格式调整,选择遍历手动赋值方案。
- 去重时根据需求选择全量去重还是单字段去重,单字段去重效率通常高于全量去重。