php 8.3 的 array_count_values() 不支持直接统计二维数组,需先将子数组转为唯一字符串标识(如 json_encode),再统计;也可按指定字段(如 name)提取一维数组后直接统计。

PHP 8.3 中 array_count_values() 本身**不支持直接统计二维数组**,因为它只接受一维索引数组或关联数组,且要求所有值为字符串或整数。对二维数组(如 [['a'=>1,'b'=>2], ['a'=>1,'b'=>2], ['a'=>3,'b'=>4]])直接调用会报错:Warning: array_count_values(): Expected parameter 1 to be an array, but got array(实际是因内部元素非标量而触发致命错误:“Can only count STRING and INTEGER values!”)。
把二维数组“扁平化”成可统计的唯一标识
核心思路:将每个子数组转换为一个**唯一、可哈希的字符串标识**(如 JSON 字符串或序列化字符串),再用 array_count_values() 统计这些标识的出现次数。
-
推荐用
json_encode($item, JSON_UNESCAPED_UNICODE | JSON_SORT_KEYS):保证键序一致、中文不转义,适合大多数场景 - 避免直接用
serialize():它包含类型和长度信息,对相同内容不同变量名可能产生不同结果,且不易读 - 若子数组结构固定且键名已知,也可拼接字符串(如
$item['a'].'|'.$item['b']),但扩展性差、易出错
完整示例代码(PHP 8.3 兼容)
假设你有如下二维数组:
$data = [
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 30],
['name' => 'Alice', 'age' => 25],
['name' => 'Alice', 'age' => 26],
];
统计完全相同的子数组出现次数:
$keys = array_map(fn($item) => json_encode($item, JSON_UNESCAPED_UNICODE | JSON_SORT_KEYS), $data);
$counts = array_count_values($keys);
// 还原回原始结构并关联计数
$result = [];
foreach ($counts as $json => $freq) {
$original = json_decode($json, true);
$result[] = ['item' => $original, 'count' => $freq];
}
print_r($result);
输出类似:
Array(
[0] => Array('item' => ['name'=>'Alice','age'=>25], 'count' => 2),
[1] => Array('item' => ['name'=>'Bob','age'=>30], 'count' => 1),
[2] => Array('item' => ['name'=>'Alice','age'=>26], 'count' => 1)
)
只按某几个字段去重统计(更常见需求)
比如只看 'name' 是否重复,忽略 'age':
- 先提取目标字段构成一维数组:
$names = array_column($data, 'name'); - 再直接统计:
$nameCounts = array_count_values($names); - 结果是
['Alice'=>3, 'Bob'=>1]
如需同时保留其他字段,可结合 array_reduce() 或循环构建分组数组,而非强求 array_count_values。
注意边界情况
- 子数组含
null、float、resource或闭包时,json_encode会丢失或报错,需提前过滤或转换 - 浮点数精度问题:
25.0和25经json_encode后不同,建议统一转为整型或字符串处理 - 大数组性能:
json_encode+array_count_values是内存友好方案;超大数据可考虑数据库或 SplFixedArray 优化
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











