阿里云新用户优惠

第五章 PHP数组

一、数组概述

1、数组的基本概念

数组是对大量数据进行有效组织和管理的手段之一,通过数组的强大功能,可以对大量性质相同的数据进行存储、排序、插入及删除等操作,从而可以有效地提高程序开发效率及改善程序的编写方式。

2、数组分类

在PHP中,数组既是一种数据类型,也是一种数据的组织与处理手段。数组有一维数组、二维数组、多维数组。但不管是一维数组还是多维数组都可以分为 数字索引数组关联数组

  • 索引数组
    数组的元素也可不定义键名,由PHP默认用索引号作为键名。
    例:$A=array(5,8,4,6,9,7);
    对于采用默认键名的数组,每个元素在数组中的索引号,也称为该元素的下标,数组的下标默认从0开始。
  • 关联数组
    数组中的每一个数据称为数组的一个元素,每一个元素都由两部分组成:元素名与元素值。其中,元素名称为“键名”,元素值称为“键值”。数组元素的键名由程序员自定义。
    例如:$A = array("A" => 3, "B" => 5, "C" => 7, "D" => 9);

二、数组的处理

1、数组的创建与初始化

  • 使用array()函数创建数组
    ① $数组变量名 = array(key1 => value1, key2 => value2, …, keyN => valueN);
    ② $数组变量名 = array(value1, value2, …, valueN);
    ③ $数组变量名 = array();
    ④ $数组变量名[下标] = 值;
    ⑤ $数组变量名[] = 值;
    例子
echo '<pre>';
//1
$array = array("name" => "张同学", "xuehao" =>20201111111 , "gender" => "男");
var_dump($array);
//2
$array = array("张同学", 20201111111 , "男");
var_dump($array);
//3
$array = array();
var_dump($array);
//4
$array[0] = "张同学";
$array[1] = 20201111111;
$array[2] = "男";
var_dump($array);
//5
$array[] = "张同学";
$array[] = 20201111111;
$array[] = "男";
var_dump($array);

//注意键名
$array = array( 1 => "张同学", 3 => 20201111111, "男");
var_dump($array);

//注意键名和值
$array = array(1, 1, 1, 1, 8 => 1, 10, 4 => 2, 3 => 13);
var_dump($array);

//使用值 $array["键名"]
echo "<br>";
echo $array[3];

注意:如果定义了两个完全一样的键名,则后面的值会覆盖前面的值

  • 使用range()定义数组
    若一个数组的所有元素的值,都明确在某一范围内,可以使用range()函数来定义一个指定范围的数组。
    其语法格式如下:
    $数组名=range($min,$max,[$step])
<?php
    echo '<pre>';
    $array = range(1, 5);
    var_dump($array);

    $array = range(2, 10, 2);
    var_dump($array);

    $array = range("a", "e");
    var_dump($array);
?>
  • 二维数组和多维数组
    二维数组和一维数组的声明方式一样,只是将数组中的一个或多个元素也声明成一个数组,同时也有直接为数组元素赋值和使用 array() 函数两种声明二维数组的方法。
<?php
    echo '<pre>';
    $array0 = array("name" => "张同学", "xuehao" =>20201111111 , "gender" => "男");
    $array1 = array("name" => "李同学", "xuehao" =>2020222222 , "gender" => "男");
    $array2 = array("name" => "赵同学", "xuehao" =>2020333333 , "gender" => "女");

    $array = array(
        array("name" => "张同学", "xuehao" =>20201111111 , "gender" => "男"),
        array("name" => "李同学", "xuehao" =>2020222222 , "gender" => "男"),
        array("name" => "赵同学", "xuehao" =>2020333333 , "gender" => "女")
    );
    var_dump($array);

    //获取二维数组中的元素也和一维数组类似,只需要注明每个维度的下标即可,示例代码如下:
    echo $array[0]['name'].'同学的学号是'.$array[0]['xuehao'].',性别是'.$array[0]['gender'];
?>

参考二维数组,举一反三,可以很容易地创建三维数组、四维数组或者其他更高维数的数组。
定义一个三维数组的示例如下:

<?php 
    echo '<pre>';
    $array = array(
        array(
            "name" => "张同学", 
            "xuehao" =>20201111111 , 
            "gender" => "男", 
            "score" => array(
                "yuwen" => 100, 
                "shuxue" => 90, 
                "yingyu" => 80, 
            )
        ),
        array(
            "name" => "李同学", 
            "xuehao" =>2020222222 , 
            "gender" => "男",
            "score" => array(
                "yuwen" => 95, 
                "shuxue" => 85, 
                "yingyu" => 75, 
            )
        ),
        array(
            "name" => "赵同学", 
            "xuehao" =>2020333333 , 
            "gender" => "女",
            "score" => array(
                "yuwen" => 80, 
                "shuxue" => 90, 
                "yingyu" => 100, 
            )
        )
    );
    var_dump($array);
    echo $array[1]["score"]["shuxue"]; //输出李同学的数学分数

    //打印数组长度
    echo count($array);
    echo count($array, 1);
?>
  • 数组的长度
    数组元素的个数,称为数组的长度。可以通过count()或sizeof()两个函数来获取数组的元素个数。
    • count() 函数其语法格式如下:
      count($array [, $mode = COUNT_NORMAL])
      参数说明如下:
      • $array:为待统计的数组或对象;
      • $mode:为可选参数,可以省略。
        • 如果省略 $mode 参数,或者将其设置为 COUNT_NORMAL 或者 0,count() 函数将不检测多维数组;
        • 如果 $mode 设置为 COUNT_RECURSIVE 或者 1,count() 函数将递归计算数组中元素的个数,对于计算多维数组的元素个数尤为有用。
    • sizeof() 函数
      sizeof() 函数是 count() 函数的别名,也就是所 sizeof() 函数的功能及使用方法与 count() 函数完全相同。

2、键名和值的操作

  • 存在性检查
    • 检查键名或索引是否存在:array_key_exists()
      语法格式如下:
      array_key_exists(mixed $key, array $array): bool
      数组里有键 key 时,array_key_exists() 返回 true。 key 可以是任何能作为数组索引的值。
      <?php 
      $array = array(
          "name" => "张同学", 
          "xuehao" =>20201111111 , 
          "gender" => "男", 
          "score" => array(
              "yuwen" => 100, 
              "shuxue" => 90, 
              "yingyu" => 80, 
          )
      );
      if(array_key_exists('name', $array)){
          echo '键名“name”存在<br>';
      }else{
          echo '键名“name”不存在<br>';
      }
      //array_key_exists() 函数仅能判断数组第一维的键名,不能判断多维数组里嵌套的键名。
      if(array_key_exists('shuxue', $array)){
          echo '键名“shuxue”存在<br>';
      }else{
          echo '键名“shuxue”不存在<br>';
      }
      if(array_key_exists('shuxue', $array['score'])){
          echo '键名“shuxue”存在<br>';
      }else{
          echo '键名“shuxue”不存在<br>';
      }
      //注意 isset()函数也可以用来检查数组中的键名是否存在
      if(isset($array['score']['shuxue'])){
          echo '键名“shuxue”存在<br>';
      }else{
          echo '键名“shuxue”不存在<br>';
      }
      ?>
      
      注意:isset()函数也可以用来检查数组中的键名是否存在,但如果检查的键名对应的值为NULL时,isset()函数返回FALSE
    • 检查值是否存在:in_array()
      语法格式如下: in_array($needle, $array[, $strict = FALSE])
      • 参数说明如下:
        • $needle:为待搜索的值,如果 $needle 是字符串,则在比较时区分大小写;
        • $array:为待搜索的数组;
        • $strict:为可选参数,默认为 FALSE。
          如果 $strict 为空或者 FALSE,则 in_array() 函数只会检查 $needle 的值是否和 $array 中的值相等;
          如果 $strict 的值为 TRUE,in_array() 函数除了会检查 $needle 和 $array 中的值之外,还会比较它们的类型是否相等。
      <?php 
      $array = array(
          "name" => "张同学", 
          "xuehao" =>20201111111 , 
          "gender" => "男", 
          "score" => array(
              "yuwen" => 100, 
              "shuxue" => 90, 
              "yingyu" => 80, 
          )
      );
      if(in_array('20201111111', $array)){
          echo '数组中包含“20201111111”<br>';
      }else{
          echo '数组中不包含“20201111111”<br>';
      }
      if(in_array('20201111111', $array, true)){
          echo '数组中包含“20201111111”<br>';
      }else{
          echo '数组中不包含“20201111111”<br>';
      }
      //in_array() 函数的第一个参数除了可以是一个具体的值外,还可以是一个数组。也就是说使用 in_array() 函数还可以判断一个数组是否包含另一个数组。
      $score = array(
          "yuwen" => 100, 
          "shuxue" => 90, 
          "yingyu" => 80, 
      );
      if(in_array($score, $array)){
          echo '数组 $array 中包含数组 $score';
      }else{
          echo '数组 $array 中不包含数组 $score';
      }
      //array_search()函数也可以用来判断值是否存在
      $key = array_search('20201111111', $array);
      if($key != null){
          echo '数组中包含“20201111111”<br>';
          echo $key;
      }else{
          echo '数组中不包含“20201111111”<br>';
      }
      ?>
      
      注意:array_search()函数当值存在时返回这个值的键名,不存在返回NULL
  • 获取和输出
    • array_keys()函数 可以取得数组中所有的键名
    • array_values()函数 可以取得数组中所有的值
    <?php
        $arr = array("red" => "红色", "blue" => "蓝色", "white" => "白色");
        $keyArrs = array_keys($arr);
        $valueArrs = array_values($arr);
        var_dump($keyArrs);
        var_dump($valueArrs);
    ?>
    

3、数组的删除

  • 删除整个数组 删除整个数组的方法与释放一个变量的方法是一样的,使用unset()函数。
    语法格式如下:
    unset($array_name)
  • 删除数组元素 删除一个数组元素,也可以用unset()来实现。
    语法格式是:
    unset($arr[index] | $arr[key]);
    其中,$arr[index]是通过数组的下标来指定要删除的数组元素,$arr[key]是通过键名来指定要删除的数组元素。
    使用unset()删除数组元素后,被删除的数组下标或者键名,直接丢弃,PHP不会对数组进行重新索引。
  • 删除多个数组元素
    如果需要在删除某些数组元素以后,数组能够自动重新索引,可以使用array_splice()函数实现,并且该函数还可以一次性删除多个元素。
    其语法格式如下:
array_splice(
    array &$input,
    int $offset,
    int $length = count($input),
    mixed $replacement = array()
): array
-参数
input
    输入的数组。
offset
    如果 offset 为正,则从 input 数组中该值指定的偏移量开始移除。
    如果 offset 为负,则从 input 末尾倒数该值指定的偏移量开始移除。
length
    如果该值设置为正数,则移除该数量的元素。
    如果该值设置为负数,则移除从 offset 到数组末端倒数 length 为止中间所有的元素。
    如果该值未设置,则移除从 offset 参数设置的位置开始直到数组末端的所有元素。
    如果该值设置为零,则不会移除元素。
replacement
    如果给出了 replacement 数组,则被移除的单元被此数组中的单元替代。
    如果 offset 和 length 的组合结果是不会移除任何值,则 replacement 数组中的单元将被插入到 offset 指定的位置。
-返回值
返回由被提取元素组成的数组。
<?php
$a1=array("a"=>"red","b"=>"green","c"=>"blue","d"=>"yellow");
$a2=array("a"=>"purple","b"=>"orange");
print_r(array_splice($a1,0,2,$a2));
echo "<br>";
print_r($a1);
?>
  • 删除重复的数组元素
    一个数组中可能会存在多个相同键值的元素,如果需要将重复的元素删除,只保留一个,可以使用array_unique()函数。
    其语法格式如下:
    array_unique(array $array, int $sort_flags = SORT_STRING): array
    array_unique() 函数用于移除数组中重复的值。如果两个或更多个数组值相同,只保留第一个值,其他的值被移除。
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
var_dump($result);

//索引不会重排
$input = array(4, "4", "3", 4, 3, "3");
$result = array_unique($input);
var_dump($result);

$A = array("A", "A", "B", "C", "B");
$B = array_unique($A);
var_dump($A);
?>

注意: array_unique() 不能应用于多维数组。


三、数组的遍历

1、数组遍历相关函数

  • key():获取数组当前单元的键名
  • current():获取数组当前单元的值
  • pos():是 current() 函数的别名
  • end():将内部指针指向数组中的最后一个元素;
  • next():将内部指针指向数组中的下一个元素,如果成功则返回数组中下一个元素的值,如果没有更多的数组元素则返回 FALSE;
  • prev():将内部指针指向数组中的上一个元素;
  • reset():将内部指针指向数组中的第一个元素;
  • list(): 可以把一个数组中的值分别赋给一组变量;
  • each():返回当前元素的键名和键值,并将内部指针指向数组中的下一个元素。 (已废弃)
<?php
    $array = array(
        'PHP数组学习',
        'https://www.php.net/manual/zh/ref.array.php',
        'current() 函数'
    );
   
    echo current($array).'<br>';
    echo pos($array).'<br>';
    next($array);
    echo current($array).'<br>';
    next($array);
    next($array);
    var_dump(current($array));

    list($a, $b, $c) = $array;
    echo '$a = '.$a.'<br>$b = '.$b.'<br>$c = '.$c. '<br>';

    echo reset($array).'<br>';
    echo '数组的最后一个元素是:'.end($array).'<br>';
?>

2、数组的遍历

对数组中的每个元素按顺序逐个访问一次,称为数组的“遍历”。 对数组的遍历的方法主要是通过循环结构实现,具体可以因为访问数组元素的方法不同而不同。

  • while循环遍历数组
<?php
$arr = array(1, 2, 3, 4, 5, 6);
// 注意 each 自 PHP 7.2.0 起废弃
while(list($key, $value) = each($arr)){
    echo $value."<br>";
}
// 替代方案
do{
    echo current($arr)."<br>";
}while(next($arr) !== false && key($arr) != null);
?>
  • for循环遍历数组
  • foreach循环遍历数组
$arr = array(1, 2, 3, 4, 5, 6);
for($i = 0; $i < count($arr); $i++){
    echo $arr[$i];
    echo "<br>";
}
//注意for中的变量$i的作用域
echo $i;
foreach($arr as $value){
    echo $value."<br>";
}
foreach($arr as $key => $a){
    echo "key 是: ". $key . ";值是: ". $a;
    echo current($arr);
}
//注意foreach 中的变量$a的作用域
echo $a;

四、数组的排序

1、升序排序

  • sort() 函数
    sort()函数不仅对数组进行排序,同时删除了原来的键名,并重新分配自动索引的键名
  • asort() 函数
    asort()函数对数组的值进行升序排序,会保持键名与值之间的关联。
  • ksort() 函数
    ksort()函数对数组的键名进行升序排序,会保持键名与值之间的关联。
    <?php
        $arr = array("a" => 5, "x" => 3, 5 => 7, "e" => 1);
        sort($arr);
        var_dump($arr);
    
        $arr = array("a" => 5, "x" => 3, 5 => 7, "e" => 1);
        asort($arr);
        var_dump($arr);
    
        $arr = array("a" => 5, "x" => 3, 5 => 7, "e" => 1);
        ksort($arr);
        var_dump($arr);
    ?>
    

2、反向排序

  • rsort() 函数
    与sort()函数用法相同,降序排序,会重新分配自动索引的键名
  • arsort() 函数
    与asort()函数用法相同
  • krsort() 函数
    与ksort()函数用法相同
    <?php
        $arr = array("a" => 5, "x" => 3, 5 => 7, "e" => 1);
        rsort($arr);
        var_dump($arr);
    
        $arr = array("a" => 5, "x" => 3, 5 => 7, "e" => 1);
        arsort($arr);
        var_dump($arr);
    
        $arr = array("a" => 5, "x" => 3, 5 => 7, "e" => 1);
        krsort($arr);
        var_dump($arr);
    ?>
    

3、对多维数组排序

  • array_multisort() 函数
    array_multisort()函数可以一次对多个数组排序。
    • 第一个参数必须是数组
    • 多个数组排序,数组数量要一致
    • 如果是关联型数组,排序后键名不再重新索引
    • 如果是数字索引型数组,排序后键名会重新索引
    • 支持排序顺序标志
      • SORT_ASC 为默认值,按照升序排序
      • SORT_DESC 按照降序排序
      • 排序类型标志:
        • SORT_REGULAR 为默认值,按照通常方法比较
        • SORT_NUMERIC 按照数值比较
        • SORT_STRING 按照字符串比较
<?php    
    $base_code = array("0", "1", "2", "3", "4");
    $arr = ["a" => 8, "b" => 6, "c" => 9, "d" => 7];

    array_multisort($base_code, SORT_DESC);

    //多个数组排序,数组数量要一致
    array_multisort($base_code, SORT_DESC, $arr);
    var_dump($base_code);
    var_dump($arr);

    //多维数组排序,
    $arr = [
        [ 11, 10, 100, 2, 30],
        [1, 2, 2, 3, 1]
    ];
    array_multisort($arr[0], SORT_ASC, $arr[1], SORT_DESC);
    var_dump($arr);
?>

4、对数组重新排序

  • shuffle() 函数
    shuffle()函数是将数组用随机的顺序排列,并删除原有的键名,建立自动索引。
<?php
    //注意键名
    $arr = array("a" => 5, "x" => 3, 5 => 7, "e" => 1);
    shuffle($arr);
    var_dump($arr);

    //生成验证码
    $base_code = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F");
    shuffle($base_code);
    $iden_code = "";
    for ($i = 0; $i < 4; $i++) {
        $iden_code .= $base_code[$i];
    }
    echo $iden_code;
?>

五、数组常用操作

1、数组的合并与拆分

  • array_merge() 函数
    此函数是把一个或多个数组合并为一个新数组。
    语法结构:array_merge(array $... = ?): array
  • 如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将 不会 覆盖原来的值,而是附加到后面。
  • 如果输入的数组存在以数字作为索引的内容,则这项内容的键名会以连续方式重新索引。
<?php
    $a1 = array("a"=>"red","b"=>"green");           //定义键值为字符串的数组
    $a2 = array("c"=>"blue","b"=>"yellow");
    $a3 = array("c"=>"blue","d"=>"yellow");
    $a4= array("3"=>"blue","5"=>"yellow","7"=>"red","9"=>"green");  
    //键值为整数的数组
    echo "<br>合并数组含有相同的字符串键值:<br>";
    print_r(array_merge($a1,$a2));         
    //Array ( [a] => red [b] => yellow [c] => blue ) 
    echo "<br><br>合并数组没有相同的字符串键值:<br>";
    print_r(array_merge($a1,$a3));         
    //Array ( [a] => red [b] => green [c] => blue [d] => yellow )
    echo "<br><br>合并键名为整数的单个数组:<br>";
    print_r(array_merge($a4));   
    //Array ( [0] => blue [1] => yellow [2] => red [3] => green )
?>

2、数组的入栈与出栈

先入后出工作机制的数据结构成为栈,先入先出工作机制的称为堆。

  • array_push() 函数
    array_push — 将一个或多个单元压入数组的末尾(入栈) 语法:array_push(array &$array, mixed $value1, mixed $... = ?): int
    array_push() 将 array 当成一个栈,并将传入的变量压入 array 的末尾。array 的长度将根据入栈变量的数目增加。和$array[] = $var;效果相同。
<?php
    $stack = array("orange", "banana");
    array_push($stack, "apple", "raspberry");
    print_r($stack);
?>
  • array_pop() 函数
    array_pop — 弹出数组最后一个单元(出栈)
    语法:array_pop(array &$array): mixed array_pop() 弹出并返回 array 数组的最后一个单元,并将数组 array 的长度减一。
    注意: 使用此函数后会重置(reset())array 指针。
<?php
    $stack = array("orange", "banana", "apple", "raspberry");
    $fruit = array_pop($stack);
    print_r($stack);
?>

在 PHP 开发过程中,有相当大的部分是与数组打交道,例如入库的内容、统计相关内容等操作都离不开数组,很多信息都是用数组作为载体的。所以数组的操作在 PHP 编程中占有很大的比重,只有熟练地操作数组才能更好的编写 PHP 程序。
除了前面我们介绍到的一些函数外,PHP 中还提供了很多特定功能的数组函数,有兴趣的同学可以访问 https://www.php.net/manual/zh/ref.array.php 来查看更详细的内容。


六、综合案例

1、王者荣耀数组输出

<?php
$heros = [
    "安琪拉" => [
        "皮肤" => ["暗夜萝莉", "玩偶对对碰", "魔法小厨娘"],
        "技能" => [
            "火球术" => [350, 390, 430],
            "混沌火种" => [130, 145, 160],
            "炽热光辉" => [700, 1050, 1400],
        ],
        "语音" => ["知识就是力量", "一不小心就干掉了个大家伙!", "生命就像人家的魔法师~涂涂改改又是一年!"]
    ],
    "亚瑟" => [

    ]
];

//过程式编程
$key = "安琪拉";
$hero = $heros[$key];

//random_int(0, 2)是生成随机数,随机数最小值是0,最大值是2
$pifu = $hero["皮肤"][random_int(0, 2)];

//array_keys是获取数组的中的key值,并组成一维数组,此处的结果是 ["火球术", "混沌火种", "炽热光辉"]
$jinengArrs = array_keys($hero["技能"]);

$jineng = $jinengArrs[random_int(0, 2)];
$shanghai = $hero["技能"][$jineng][random_int(0, 2)];

$yuyin = $hero["语音"][random_int(0, 2)];

echo "【".$pifu."】的【".$key."】对你使用了【".$jineng."】,造成了【".$shanghai."】点伤害,并对你说出了【".$yuyin."】";

?>

2、接收用户输入的学生学号、姓名、成绩等信息,排序显示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>学生成绩</title>
</head>
<body>
    <form action="" method="POST" style="width: 70%;margin-left:15%;">
        <div id="items">
            <div>
                <span>学号:<input type="text" name="XH[]" placeholder="请输入学号"></span>
                <span>姓名:<input type="text" name="XM[]" placeholder="请输入姓名"></span>
                <span>成绩:<input type="text" name="CJ[]" placeholder="请输入成绩"></span>
            </div>
        </div>
        <a id="add" href="javascript:;">+添加一行</a>
        <input type="submit" value="提交" name="postSubmit" style="margin-top:30px;">
    </form>
</body>
<script>
   let add = document.getElementById("add");
   add.onclick = function(){
        let node = document.createElement("div");
        node.innerHTML = `<div>
                <span>学号:<input type="text" name="XH[]" placeholder="请输入学号"></span>
                <span>姓名:<input type="text" name="XM[]" placeholder="请输入姓名"></span>
                <span>成绩:<input type="text" name="CJ[]" placeholder="请输入成绩"></span>
            </div>`;
        let items = document.getElementById("items");
        items.appendChild(node);
   }
</script>
</html>
<?php
if(isset($_POST['postSubmit'])){
    $XH = $_POST["XH"];
    $XM = $_POST["XM"];
    $CJ = $_POST["CJ"];
    
    array_multisort($CJ, SORT_DESC, $XH, $XM);

    echo "<hr>";
    echo "成绩排序<br>";
    for($i = 0; $i < count($CJ); $i++){
        echo "学号:{$XH[$i]}  姓名:{$XM[$i]}  成绩:{$CJ[$i]}";
        echo "<br>";
    }
}
?>

关注微信公众号,与我交流吧~

分享