PHP 数组 (Array) 相关函数详解
PHP 数组 (Array) 是一种特殊的数据类型,可以存储多个值在一个变量中。PHP 数组是高度灵活的,既可以作为普通索引数组(数值键),也可以作为关联数组(字符串键),甚至可以两者混合使用,或者作为多维数组。PHP 提供了极其丰富和强大的内置函数来操作数组,涵盖了从创建、遍历、排序、过滤到搜索、合并等几乎所有常见的数组操作需求。深入理解并熟练运用这些函数,是高效编写 PHP 代码的关键。
核心思想:PHP 数组函数旨在提供强大、灵活且高效的方式来管理和操作复杂的数据集合,简化开发者对数据的处理。
一、数组基础知识回顾
在深入函数之前,快速回顾 PHP 数组的几个核心特性:
- 异构性 (Heterogeneous):数组中的元素可以是不同数据类型(字符串、数字、布尔、对象、其他数组等)。
- 动态大小 (Dynamic Sizing):数组大小不是固定的,可以随时添加或删除元素。
- 索引与关联:
- 索引数组 (Indexed Array):键是整数,默认从 0 开始。
1
2$indexedArray = ['apple', 'banana', 'orange'];
// 等同于 $indexedArray = [0 => 'apple', 1 => 'banana', 2 => 'orange']; - 关联数组 (Associative Array):键是字符串。
1
$associativeArray = ['name' => 'Alice', 'age' => 30, 'city' => 'New York'];
- 索引数组 (Indexed Array):键是整数,默认从 0 开始。
- 多维数组 (Multidimensional Array):数组的元素可以是另一个数组。
1
2
3
4$multiArray = [
['name' => 'Alice', 'age' => 30],
['name' => 'Bob', 'age' => 25]
];
二、常用数组函数分类详解
PHP 数组函数数量众多,这里按功能进行分类讲解。
2.1 数组创建与初始化
array():创建新数组。PHP 7.4+ 推荐使用[]语法。1
2$arr1 = array('a', 'b', 'c');
$arr2 = ['x', 'y', 'z']; // 更简洁的语法range(mixed $start, mixed $end, int|float $step = 1):创建包含指定范围元素的数组。1
2
3$numbers = range(1, 5); // [1, 2, 3, 4, 5]
$letters = range('a', 'e'); // ['a', 'b', 'c', 'd', 'e']
$evens = range(2, 10, 2); // [2, 4, 6, 8, 10]array_fill(int $start_index, int $count, mixed $value):用指定值填充数组。1
$filled = array_fill(0, 5, 'hello'); // [0 => 'hello', 1 => 'hello', ...]
array_pad(array $array, int $size, mixed $value):将数组填充到指定长度。1
2$padded = array_pad([1, 2], 5, 0); // [1, 2, 0, 0, 0]
$paddedNeg = array_pad([1, 2], -5, 0); // [0, 0, 0, 1, 2] (负数从左侧填充)
2.2 数组元素访问与检查
count(mixed $array_or_countable, int $mode = COUNT_NORMAL)/sizeof():获取数组元素的数量。1
2$arr = [1, 2, 3];
echo count($arr); // 3array_key_exists(mixed $key, array $array):检查数组中是否存在指定的键。1
2
3$arr = ['name' => 'Alice', 'age' => 30];
var_dump(array_key_exists('name', $arr)); // bool(true)
var_dump(array_key_exists('gender', $arr)); // bool(false)in_array(mixed $needle, array $haystack, bool $strict = false):检查数组中是否存在指定的值。1
2
3
4$arr = [1, 'hello', true];
var_dump(in_array('hello', $arr)); // bool(true)
var_dump(in_array(1, $arr, true)); // bool(true) (严格模式,类型也要匹配)
var_dump(in_array('1', $arr, true)); // bool(false)isset(mixed ...$vars):检查变量是否已设置且非 NULL。对于数组元素,可用于检查键是否存在且值不为 NULL。1
2
3
4$arr = ['name' => 'Alice', 'age' => 30, 'city' => null];
var_dump(isset($arr['name'])); // bool(true)
var_dump(isset($arr['gender'])); // bool(false)
var_dump(isset($arr['city'])); // bool(false) (因为值为null)array_search(mixed $needle, array $haystack, bool $strict = false):在数组中搜索给定值,如果成功则返回对应的键。1
2
3$arr = ['a' => 1, 'b' => 'hello', 'c' => 1];
echo array_search(1, $arr); // a (返回第一个匹配的键)
echo array_search(1, $arr, true); // a
2.3 数组遍历与迭代
foreach结构是遍历数组最常用的方式。1
2foreach ($arr as $value) { /* ... */ }
foreach ($arr as $key => $value) { /* ... */ }array_map(callable $callback, array $array, array ...$arrays):对数组中的每个元素应用回调函数,返回新数组。1
2
3
4
5
6
7
8
9
10
11
12
13
14$numbers = [1, 2, 3];
$squared = array_map(function($n) { return $n * $n; }, $numbers); // [1, 4, 9]
$names = ['Alice', 'Bob'];
$ages = [20, 30];
$combined = array_map(function($name, $age) {
return ['name' => $name, 'age' => $age];
}, $names, $ages);
/*
[
['name' => 'Alice', 'age' => 20],
['name' => 'Bob', 'age' => 30]
]
*/array_filter(array $array, ?callable $callback = null, int $mode = 0):使用回调函数过滤数组中的元素。1
2
3
4
5$numbers = [1, 2, 3, 4, 5, 6];
$evens = array_filter($numbers, function($n) { return $n % 2 == 0; }); // [2, 4, 6]
// 默认行为:移除所有“空”值 (false, null, 0, '', [] 等)
$filtered = array_filter([0, 1, '', 'hello', false, true, null, []]); // [1, 'hello', true]array_reduce(array $array, callable $callback, mixed $initial_value = null):将数组归约为单一值。1
2
3
4$numbers = [1, 2, 3, 4, 5];
$sum = array_reduce($numbers, function($carry, $item) {
return $carry + $item;
}, 0); // 15array_walk(array &$array, callable $callback, mixed $userdata = null)/array_walk_recursive():对数组中的每个元素应用用户自定义函数。与array_map不同,array_walk直接修改原数组(如果回调函数修改了元素)。1
2
3
4
5$fruits = ['apple', 'banana'];
array_walk($fruits, function(&$value, $key) {
$value = strtoupper($value);
});
// $fruits 现在是 ['APPLE', 'BANANA']
2.4 数组添加、删除与修改
- 添加元素:
- 索引数组:
$arr[] = $value; - 关联数组:
$arr['key'] = $value; array_push(array &$array, mixed ...$values):将一个或多个元素压入数组的末尾(适用于索引数组,但会重置数字键)。1
2$fruits = ['apple'];
array_push($fruits, 'banana', 'orange'); // ['apple', 'banana', 'orange']
- 索引数组:
- 删除元素:
unset(mixed ...$vars):删除变量或数组中的元素。会破坏数字索引的连续性。1
2$arr = [0 => 'a', 1 => 'b', 2 => 'c'];
unset($arr[1]); // $arr 现在是 [0 => 'a', 2 => 'c']array_pop(array &$array):弹出数组最后一个元素(并返回)。1
2$fruits = ['apple', 'banana', 'orange'];
$last = array_pop($fruits); // $last = 'orange', $fruits = ['apple', 'banana']array_shift(array &$array):移除数组第一个元素(并返回)。1
2$fruits = ['apple', 'banana', 'orange'];
$first = array_shift($fruits); // $first = 'apple', $fruits = ['banana', 'orange']
- 插入与替换:
array_splice(array &$array, int $offset, ?int $length = null, mixed $replacement = []):移除数组的一部分并替换为其他元素。1
2
3$fruits = ['apple', 'banana', 'orange', 'grape'];
array_splice($fruits, 1, 2, ['kiwi', 'lemon']);
// $fruits 现在是 ['apple', 'kiwi', 'lemon', 'grape']array_replace(array $array, array ...$replacements)/array_replace_recursive():使用一个或多个数组的值替换原数组的值。1
2
3$base = ['a' => 1, 'b' => 2];
$replacements = ['b' => 3, 'c' => 4];
$result = array_replace($base, $replacements); // ['a' => 1, 'b' => 3, 'c' => 4]
2.5 数组排序
PHP 提供了多种排序函数,可以根据值、键或自定义规则进行排序。
sort(array &$array, int $flags = SORT_REGULAR):按值升序排序索引数组。会重置键。1
2$numbers = [3, 1, 4, 1, 5];
sort($numbers); // [1, 1, 3, 4, 5]rsort(array &$array, int $flags = SORT_REGULAR):按值降序排序索引数组。会重置键。asort(array &$array, int $flags = SORT_REGULAR):按值升序排序关联数组,保持键与值的关联。1
2$ages = ['Bob' => 30, 'Alice' => 25, 'Charlie' => 35];
asort($ages); // ['Alice' => 25, 'Bob' => 30, 'Charlie' => 35]arsort(array &$array, int $flags = SORT_REGULAR):按值降序排序关联数组,保持键与值的关联。ksort(array &$array, int $flags = SORT_REGULAR):按键升序排序关联数组。1
2$ages = ['Bob' => 30, 'Alice' => 25, 'Charlie' => 35];
ksort($ages); // ['Alice' => 25, 'Bob' => 30, 'Charlie' => 35] (键按字母序)krsort(array &$array, int $flags = SORT_REGULAR):按键降序排序关联数组。usort(array &$array, callable $callback):使用用户自定义的比较函数对数组按值排序。会重置键。1
2
3
4
5
6
7
8$users = [
['name' => 'Alice', 'age' => 30],
['name' => 'Bob', 'age' => 25],
];
usort($users, function($a, $b) {
return $a['age'] <=> $b['age']; // PHP 7+ 飞船操作符
});
// $users 按年龄升序排序uasort()/uksort():与usort类似,但uasort保持键值关联,uksort按键使用自定义函数排序。
排序标志 (Sorting Flags):
在许多排序函数中可以使用 flags 参数来改变排序行为:
SORT_REGULAR(默认):正常比较项目。SORT_NUMERIC:将项目视为数字进行比较。SORT_STRING:将项目视为字符串进行比较。SORT_LOCALE_STRING:根据当前区域设置(locale)进行字符串比较。SORT_NATURAL:使用“自然排序”算法比较字符串(如 foo10 < foo2)。SORT_FLAG_CASE:可以与SORT_STRING或SORT_NATURAL结合使用,进行不区分大小写的排序。
2.6 数组合并、拆分与差集/交集
array_merge(array ...$arrays)/+操作符:合并一个或多个数组。array_merge():- 数字键:会被重新索引。
- 字符串键:后面的值会覆盖前面的同名键值。
+操作符:- 数字键:不会重新索引,只会添加原数组中不存在的键。
- 字符串键:前面数组的键值会保留,后面的同名键值会被忽略。
1
2
3
4
5
6
7
8
9$arr1 = [0 => 'a', 1 => 'b'];
$arr2 = [1 => 'x', 2 => 'y'];
$merged = array_merge($arr1, $arr2); // ['a', 'x', 'y'] (键被重置)
$arr3 = ['a' => 1, 'b' => 2];
$arr4 = ['b' => 3, 'c' => 4];
$mergedAssoc = array_merge($arr3, $arr4); // ['a' => 1, 'b' => 3, 'c' => 4]
$plus = $arr3 + $arr4; // ['a' => 1, 'b' => 2, 'c' => 4] (arr3的'b'保留)array_combine(array $keys, array $values):通过合并两个数组来创建一个新数组,一个作为键,一个作为值。1
2
3$keys = ['name', 'age'];
$values = ['Alice', 30];
$combined = array_combine($keys, $values); // ['name' => 'Alice', 'age' => 30]array_slice(array $array, int $offset, ?int $length = null, bool $preserve_keys = false):从数组中取出一段。1
2
3$fruits = ['apple', 'banana', 'orange', 'grape'];
$slice = array_slice($fruits, 1, 2); // ['banana', 'orange']
$slicePreserveKeys = array_slice($fruits, 1, 2, true); // [1 => 'banana', 2 => 'orange']array_chunk(array $array, int $size, bool $preserve_keys = false):将数组分割成多个小数组(块)。1
2$numbers = [1, 2, 3, 4, 5, 6];
$chunks = array_chunk($numbers, 2); // [[1, 2], [3, 4], [5, 6]]array_diff(array $array, array ...$arrays):计算数组的差集(返回在第一个数组中存在,但在其他数组中不存在的值)。1
2
3$arr1 = ['a', 'b', 'c', 'd'];
$arr2 = ['b', 'd'];
$diff = array_diff($arr1, $arr2); // ['a', 'c']array_diff_assoc()/array_diff_key()/array_diff_uassoc()/array_diff_ukey():更精细的差集计算,分别比较键值、键。array_intersect(array $array, array ...$arrays):计算数组的交集(返回在所有数组中都存在的值)。1
2
3$arr1 = ['a', 'b', 'c', 'd'];
$arr2 = ['b', 'd', 'e'];
$intersect = array_intersect($arr1, $arr2); // ['b', 'd']array_intersect_assoc()/array_intersect_key()/array_intersect_uassoc()/array_intersect_ukey():更精细的交集计算。
2.7 数组键与值操作
array_keys(array $array, mixed $filter_value = null, bool $strict = false):返回数组的所有键或指定值的键。1
2
3$arr = ['a' => 1, 'b' => 2, 'c' => 1];
$keys = array_keys($arr); // ['a', 'b', 'c']
$keysOfOne = array_keys($arr, 1); // ['a', 'c']array_values(array $array):返回数组的所有值。会重置数字键。1
2$arr = ['a' => 1, 'b' => 2, 'c' => 1];
$values = array_values($arr); // [1, 2, 1]array_flip(array $array):交换数组中的键和值。如果值重复,最后一个值会覆盖之前的。1
2$arr = ['name' => 'Alice', 'age' => 30];
$flipped = array_flip($arr); // ['Alice' => 'name', 30 => 'age']array_unique(array $array, int $flags = SORT_STRING):移除数组中的重复值。1
2$numbers = [1, 2, 2, 3, 1, 4];
$unique = array_unique($numbers); // [1, 2, 3, 4] (原始键会被保留)
2.8 其他实用函数
current(array &$array)/next()/prev()/reset()/end():操作数组内部指针。1
2
3
4
5
6$fruits = ['apple', 'banana', 'orange'];
echo current($fruits); // apple
next($fruits);
echo current($fruits); // banana
reset($fruits);
echo current($fruits); // appleshuffle(array &$array):随机打乱数组的顺序。会重置键。array_rand(array $array, int $num = 1):从数组中随机取出一个或多个键。1
2
3$fruits = ['apple', 'banana', 'orange'];
$randomKey = array_rand($fruits); // 随机一个键 (0, 1, 或 2)
$randomFruits = $fruits[array_rand($fruits, 2)]; // 随机两个水果array_sum(array $array):计算数组中所有值的和。array_product(array $array):计算数组中所有值的乘积。extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ""):从数组中将键值对导入到当前符号表(创建变量)。谨慎使用,可能导致变量名冲突。1
2
3
4$data = ['name' => 'Alice', 'age' => 30];
extract($data);
echo $name; // Alice
echo $age; // 30compact(string ...$var_names):创建一个包含变量名和它们的值的数组。1
2
3$name = 'Bob';
$age = 25;
$info = compact('name', 'age'); // ['name' => 'Bob', 'age' => 25]
三、性能与最佳实践
- 选择合适的函数:理解每个函数的功能和副作用(如是否重置键、是否修改原数组)至关重要。例如,对于只需遍历每个元素并返回新数组的场景,
array_map通常比array_walk更合适。 - 避免不必要的循环:PHP 提供的许多内置数组函数都是用 C 语言实现的,通常比手写的
foreach循环更高效。能用内置函数解决的问题,尽量使用内置函数。 - 大型数组处理:对于非常大的数组,某些操作(如
array_push频繁添加元素,array_splice大量插入/删除)可能会带来性能开销。 - 键的类型:关联数组的键可以是整数或字符串。如果整数键看起来像数字字符串(如
'100'),PHP 可能会将其转换为整数。 - 内存使用:某些操作(如
array_merge拷贝大数组)会消耗较多内存。
四、总结
PHP 数组函数是其核心优势之一,为开发者提供了处理各种数据集合的强大工具集。从基本的增删改查到复杂的排序、过滤、集合运算,几乎所有常见的数组操作都有对应的内置函数支持。通过熟练掌握这些函数,并结合对数组特性的深入理解,开发者可以编写出更简洁、更高效、更易维护的 PHP 代码。在实际项目中,总是优先考虑使用内置数组函数来解决问题,以充分利用 PHP 引擎的优化能力。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 1024 维度!
