摘要訊息 : 學習如何使用 PHP 中的陣列.

0. 前言

本文于 2022 年 3 月 18 日进行一次更新和修正. 修正之后本文已经归档, 不再享受更新.

1. 索引数组

使用 array 声明数组, PHP 中的数组和 C 一样都是默认从 0 开始计数 : $arr = array("0" => value1, "1" => value2, ...);. 这种数组的声明其实和 $arr = array(value1, value2, ...);$arr = [value1, value2, ...] 是一样的.. 通过 arr[1] 读取到的值同样都是 value1. 当然也可以分别赋值 :

$arr[0] = value1;
$arr[1] = value2;

2. 关联数组

除去普通的数组之外, PHP 也有关联数组. 其实 PHP 中的关联数组和 Swift 中的字典十分类似. 关联数组可以不从 0 开始计数, 而是直接通过键索引直接得到对应的索引值

<?php
    $arr = array("key1" => 1, "key2" => 2);
    echo $arr['key1'];    // 结果 : 1
?>

3. 多维数组

不管是普通的数组还是关联数组, 都是支持相互嵌套的, 也就是俗称的多维数组

<?php
    $arr = array(array(1, 2), array("key1" => 3, "key2" => 4));
    echo $arr[0][0];    // 结果 : 1
    echo $arr[1]['key1'];    // 结果 : 3
?>

4. 常量数组

在 PHP 5.6 的时候, PHP 仅支持使用 const 关键字定义常量数组, 方式和数组的宣告方式相同 : const arr = array();. 在 PHP 7 之后, PHP 还支持使用 define() 定义常量数组, 当然也支持常量多维数组和常量关联数组 :

<?php
    define('学生', ['学生1', '学生2']);
    echo 学生[0];    // 结果 : 学生1
?>

5. 数组遍历

n 维数组的遍历使用 n 个循环语句. 不过, PHP 还提供了 foreach 语句对数组进行便利, 在之前《PHP 第四课 : 循环控制》当中已经讲过了, 这里就不再累赘.

7. 数组的基本操作

7.1 数组排序

PHP 提供了多种数组的排序方式, 关联数组还可以通过自定义排序函数的方式进行排序. 假设我们把数组定义为 $arr = array("key" => "value") :

  • sort : 默认排序, 升序;
  • asort : 根据 value 值排序, 升序;
  • ksort : 根据 key 值排序, 升序;
  • rsort : 默认排序, 降序;
  • arsort : 根据 value 值排序, 降序;
  • krsort : 根据 key 值排序, 降序;
  • usort : 自定义排序.

这里需要特别讲明 usort, 它需要你自己定义排序方法, 然后会根据你定义的排序方式对数组进行排序, 这个在多维关联数组中特别有用 :

<?php
    $arr = array(array("name" => "stu1", "class" => 1), array("name" => "stu2", "class" => 8), array("name" => "stu3", "class" => 5));
    function compare($x, $y) {
        if($x["class"] == $y["class"]) {
            return 0;
        }else if($x["class"] < $y["class"]) {
            return 1;
        }else {
            return -1;
        }
    }
    usort($arr, 'compare');
    for($i = 0; $i < count($arr); $i++) {
        echo $arr[$i]["name"];
        echo "\n";
    }
?<
/* 结果 :
    stu2
    stu3
    stu1
*/

7.2 将字符串转换为数组

有时候, 我们需要把一串有规律的字符串转换为数组的形式, 方便后续的操作. 这个时候, 可以用到 PHP 提供的 explode 函数 :

<?php
    $str = "1.2.3";
    $arr = explode('.', $str);
    print_r($arr);
?>
/* 结果 :
    Array(
        [0] => 1
        [1] => 2
        [2] => 3
    )
*/

7.3 将数组转换为字符串

可以从字符串转换为数组, 当然可以从数组转换为字符串. 这要通过 implode 函数实现 :

<?php
    $arr = array(1, 2, 3);
    $str = implode("个人\n", $arr);
    echo $str;
?>
/* 结果 :
    1个人
    2个人
    3
*/

你可以发现, 数组的最后一个元素不会被转换. 这就需要我们手动去转换.

如果是关联数组 $arr = array("key" => "value"), 那么 implode 函数是转换 "value" 值.

7.4 向数组中添加元素

PHP 提供了两个函数来向数组中添加元素 :

  • array_push(数组, 元素1, 元素2, ...);
  • array_unshift(数组, 元素1, 元素2, ...).

这两个函数的添加涉及到在原数组最前面添加还是最后面开始添加 :

  • array_push : 从原数组最后一个元素开始向后添加新元素;
  • array_unshift : 从原数组第一个元素开始添加新元素.

7.5 从数组中删除元素

和添加元素一样, PHP 提供了两个函数来删除数组中的默认元素. 不过和 Swift 不同的是, PHP 并没有提供直接删除数组某一个元素的函数. 不过值得庆幸的是, PHP 有提供间接删除某一个元素的函数 :

  • array_pop(数组);
  • array_shift(数组);
  • array_splice(待删除元素数组, 删除元素起始位置, 删除元素个数);
  • unset(数组第 i 个元素).

实际上, unset 函数会直接释放内存, 让数组这个索引指向空地址, 即 null. 从下面的例子中, 我们就可以得到证明 :

<?php
    $arr = [1, 2, 3];
    unset($arr[1]);
    if($arr[1] == null) {
        echo "1";
    }
?>
/* 结果 :
    1
*/

我们讲回 PHP 提供的删除数组元素的函数 :

  • array_pop : 删除数组最后一个元素;
  • array_shift : 删除数组第一个元素;
  • array_splice : 从数组指定元素开始删除指定个数.

7.6 查询数组

PHP 提供了三个函数分别用于查询数组中的不同项目 :

  • in_array(查询字符串, 数组) : 查询常规数组的值;
  • array_key_exists(查询字符串, 数组) : 查询关联数组的 "key" 值;
  • array_search(查询字符串, 数组) : 查询关联数组的 "value" 值.

值得注意的是, 当这些函数适用于多维数组的时候, 就不是太合适. 这些函数只会去处理最外围的函数, 而无法获得嵌套在内的数组的具体元素.

7.7 获得数组元素

现在假设有数组 $arr = ("key" => "value"), PHP 提供了两个函数分别用于获得数组的 "key" 和 "value"

  • array_keys(数组) : 获得一个数组中全部的 "key" 值;
  • array_values(数组) : 获得一个数组中全部的 "value" 值.

和查询函数一样, 这些函数同样不适用于多维数组, 否则只会处理最外围的函数, 而不会获得内部元素的相关元素值.

7.8 数组元素统计

PHP 提供了 count 函数来统计数组元素的个数. 当需要统计数组中 "value" 值出现的次数时, 可以使用 array_count_value 函数来计算. 不过这个函数返回的是一个数组, 索引为原数组的元素索引值, 索引值为原数组该索引对应的元素索引值出现的次数. 不过同样, array_count_value 不适用于多维数组.

7.9 删除重复元素

PHP 提供了 array_unique 函数来删除数组中重复出现的元素.

7.10 调换关联数组的 key 与 value

PHP 提供了 array_flip 函数, 用于调换关联数组的键和值.

7.11 数组的序列化与反序列化

PHP 提供了 serialize 函数来对数组进行序列化为字符串, 同样提供了 unserialize 函数对字符串进行反序列化为数组. 这里对于这两个函数不多介绍, 暂时只讲运用在数组上 :

<?php
    $arr = ["a", "dsfdsafsfs", "dfas", "cdscwwe"];
    echo serialize($arr)."\n";
    print_r(unserialize(serialize($arr)));
?>
/*结果 :
    a:4:{i:0;s:1:"a";i:1;s:10:"dsfdsafsfs";i:2;s:4:"dfas";i:3;s:7:"cdscwwe";}
    Array(
        [0] => a
        [1] => dsfdsafsfs
        [2] => dfas
        [3] => cdscwwe
    )
*/

特别提及一下 $str, 第一个冒号后面的数组为数组的元素个数, i 为该元素的索引, s 为该元素的字符个数统计, 再后面的为元素本身.