← PHP usort函数详解:自定义回调按值排序与键名重建机制 PHP array_walk函数详解:遍历数组并施加自定义回调 →

PHP array_values函数详解:提取数组值并重建数字索引

著
原创 2026-10-09 PHP 已有人查阅

一、函数定位与核心机制

array_values是PHP内置的数组处理函数,从PHP4.0开始提供。它的作用很直接:把数组里的所有值提取出来,组成一个新的索引数组。

用一句话概括它的行为:丢掉键名,只留值,重新从0开始编号。

这个名字里没有u,没有assoc,没有sort,因为它做的事情非常单一。它不比较、不排序、不去重,只是把键值对里的值那部分抽出来,重新打包成一个连续索引的数组。

语法结构

array array_values(array $array): array

参数说明:

参数 是否必需 说明
array 必需 输入数组

返回值是一个新数组,包含原数组的所有值,键名从0开始,依次加1。原数组不被修改,函数不传引用。

键名重建规则

原文里有一条重要说明:返回的数组使用数字键名,从0开始,每次加1。

这条规则不分原数组的键名类型。不管是字符串键名、数字键名、还是混合键名,结果数组的键名都是0、1、2、3这样的连续整数。

$arr = array(5 => "a", 10 => "b", "name" => "c");
print_r(array_values($arr));

输出:

Array
(
    [0] => a
    [1] => b
    [2] => c
)

原来的5、10、name全部丢弃,重新编号成0、1、2。值的顺序保持不变,还是按原数组里的顺序排列。

二、与相近函数的区分

array_values和几个相关函数经常被放在一起比较,这里做一次梳理:

函数 作用 返回内容
array_keys 提取键名 键名组成的索引数组
array_values 提取值 值组成的索引数组
array_flip 键值互换 键名变值,值变键名
array_combine 合并键值 用两个数组合成一个关联数组

array_values和array_keys是一对反向操作。前者取值,后者取键。在调试时,如果只想看数组里有哪些值,用array_values;如果只想看有哪些键,用array_keys。

个人经验:在接口返回数据时,如果数据源是一个关联数组,但前端期望拿到一个数组格式(JSON里的[]而不是{}),就需要用array_values处理一下。PHP的json_encode会把连续数字索引的数组编码成JSON数组,把关联数组编码成JSON对象。这个差异在前端联调时经常引发问题,明明后端返回的是列表,前端拿到的却是对象。

三、JSON输出场景的实际价值

这一点值得单独展开,因为它是array_values在项目里最常见的用途之一。

PHP数组在json_encode时的行为:

$list1 = array("a", "b", "c");
echo json_encode($list1);
// 输出:["a","b","c"]

$list2 = array("x" => "a", "y" => "b");
echo json_encode($list2);
// 输出:{"x":"a","y":"b"}

如果数组经过某些操作(比如array_filter、array_unique)后键名变得不连续,json_encode会把它当成关联数组处理:

$data = array("a", "b", "c");
$filtered = array_filter($data, function($v) {
    return $v !== "b";
});
echo json_encode($filtered);
// 输出:{"0":"a","2":"c"}

键名是0和2,不连续,json_encode输出成对象。前端拿到的就不是数组,遍历方式、长度判断都会出问题。

用array_values包一层:

echo json_encode(array_values($filtered));
// 输出:["a","c"]

问题解决。这个用法在接口开发里出现频率很高,尤其是数据经过过滤、去重、排序之后。

四、项目实战示例

示例一:数字键名数组取值

<?php
$a = array(1 => "javatpoint", 2 => "udemy", 3 => "byjus");
print_r(array_values($a));

输出:

Array
(
    [0] => javatpoint
    [1] => udemy
    [2] => byjus
)

原来的键名1、2、3被丢弃,重新编号成0、1、2。

示例二:字符串键名数组取值

<?php
$a = array("a" => "apple", "b" => "ball", "c" => "cat");
print_r(array_values($a));

输出:

Array
(
    [0] => apple
    [1] => ball
    [2] => cat
)

字符串键名全部丢弃,值按原顺序保留。

示例三:混合键名数组取值

<?php
$game = array("a" => "mario", "b" => "need for speed", "c" => "igi", "road race");
print_r(array_values($game));

输出:

Array
(
    [0] => mario
    [1] => need for speed
    [2] => igi
    [3] => road race
)

这个示例里"roadrace"没有指定键名,PHP自动分配了下一个数字索引。array_values处理后,所有键名统一重建成0、1、2、3。

示例四:配合array_filter输出JSON数组

<?php
$scores = array(88, 0, 72, 0, 95);
$passed = array_filter($scores, function($v) {
    return $v > 0;
});
echo json_encode(array_values($passed));

输出:

[88,72,95]

array_filter去掉了值为0的元素,但保留了原键名0、2、4。直接json_encode会输出{"0":88,"2":72,"4":95},前端拿到的是对象。用array_values重新索引后,输出标准的JSON数组。

示例五:取关联数组的值做批量处理

<?php
$person = array("Name" => "Tom", "Age" => 30, "Country" => "China");
$values = array_values($person);
foreach ($values as $v) {
    echo $v . "\n";
}

输出:

Tom
30
China

当只需要处理值、不关心键名时,先array_values提取出来,后续逻辑可以按索引访问,代码更简洁。

五、容易踩的坑

误以为会修改原数组。array_values返回新数组,原数组不变。这一点和usort、array_unshift这些传引用的函数不同。如果业务上想用结果替换原数组,需要显式赋值:

$arr = array_values($arr);

键名信息丢失后无法恢复。array_values丢弃键名,如果后续逻辑需要按原键名访问,就没办法了。调用之前先确认键名是否还有用。

多维数组只处理最外层。array_values只重建最外层的键名,子数组的键名不受影响。如果子数组也是关联数组,需要递归处理或手动遍历。

对已经是索引数组的数组调用没有副作用。如果原数组已经是0、1、2连续索引,array_values返回一个内容相同的新数组。功能上没变化,但会多占一份内存。在内存敏感的场景下,先判断一下是否必要。

性能开销。array_values需要遍历整个数组,时间复杂度是O(n)。对超大数组(几十万条以上)频繁调用,会带来可观的开销。如果只是为了让json_encode输出数组格式,可以在数据源头就保持索引连续,减少这类转换操作。

和array_column的区别。array_column是从多维数组里提取某一列的值,array_values是提取一维数组的所有值。两者用途不同,不要混用。比如从用户列表里提取所有用户名的数组,用array_column(users,′name′);把用户列表的键名去掉重新索引,用arrayvalues(users,′name′);把用户列表的键名去掉重新索引,用arrayv​alues(users)。

六、知识点总结

  • array_values提取数组的所有值,返回新的索引数组

  • 返回数组的键名从0开始,依次加1,连续排列

  • 原数组的键名类型不影响结果,字符串键名和数字键名都会被丢弃

  • 原数组不被修改,函数不传引用

  • 值的顺序保持不变

  • 与array_keys是反向操作,一个取值一个取键

  • 配合json_encode使用时,可以保证输出JSON数组而不是对象

  • 对已经是连续索引的数组调用会多占一份内存

七、适用场景

这个函数适合以下场景:

  • 数据经过array_filter、array_unique等操作后键名不连续,需要重新索引

  • 接口返回列表数据,需要保证json_encode输出数组格式

  • 只需要处理值、不关心键名的场景

  • 把关联数组转成索引数组,方便用for循环遍历

不适合的场景:

  • 需要保留键名的场景,用asort或uasort排序后保留键名

  • 需要按键名访问数据的场景

  • 只需要某一列的值,用array_column更直接

  • 超大数组且键名已经连续的场景,调用会多占内存

← PHP usort函数详解:自定义回调按值排序与键名重建机制 PHP array_walk函数详解:遍历数组并施加自定义回调 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号