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'];
  • 多维数组 (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); // 3
  • array_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
    2
    foreach ($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); // 15
  • array_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_STRINGSORT_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); // apple
  • shuffle(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; // 30
  • compact(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 引擎的优化能力。