
第5章 PHP数组
(视频讲解:1小时7分钟)
数组是对大量数据进行有效组织和管理的手段之一。通过数组,可以对大量性质相同的数据进行存储、插入、排序及计算等操作,从而可以有效地提高程序开发效率及改善程序的编写方式。PHP作为市面上最为流行的Web开发语言之一,凭借其代码开源、升级速度快等特点,对数组的操作能力更加强大,尤其是PHP为程序开发人员提供了大量方便、易懂的数组操作函数,更使PHP深受广大Web开发人员的青睐。
学习摘要:
数组的定义
创建数组
数组的类型
多维数组
遍历数组
统计数组元素个数
查询数组中指定元素
获取数组中最后一个元素
向数组中添加元素
其他常用数组函数
5.1 什么是数组

视频讲解
数组,顾名思义,本质上就是一系列数据的组合。在这个组合中,每个数据都是独立的,可以对每个单独的数据进行分配和读取,然而这一系列数据必须是同一种类型,不能属于不同类型。在程序设计中引入数组可以更有效地管理和处理数据。我们可以单独定义a、b、c、d、e这5个变量,也可以定义一个数组,包含这5个变量,如图5.1所示。

图5.1 变量和一维数组的概念图
数组中的每个实体都包含两项:键(也称为下标)和值。可以通过键值来获取相应数组元素。这就像篮球球员和球衣号码一样,如NBA芝加哥公牛队乔丹球衣号码是23号,那么,公牛队就是一个数组,23就是数组的键,乔丹就是键对应的值。我们可以通过球衣号码对应找到球员。例如,2017年NBA全明星西部首发阵容可以用数组表示,如图5.2所示。

图5.2 NBA全明星西部首发数组键值对
5.2 创建数组

视频讲解
在PHP中创建数组的方式主要有两种:一种是应用array()函数创建数组,另一种是直接通过为数组元素赋值的方式创建数组。
5.2.1 使用array()函数创建数组
可以用array()函数来新建一个数组,该数组接受任意数量用逗号分隔的key(键)=>value(值)对,格式如下:

说明
键(key)可以是一个整数(integer)或字符串(string),如果省略了索引,则会自动产生从0开始的整数索引。如果索引是整数,则下一个产生的索引将是目前最大的整数索引+1。如果定义了两个完全一样的索引,则后面一个会覆盖前一个。值(value)可以是任意类型的值,如果是数组类型时,就是二维数组。
应用array()函数声明数组时,数组下标既可以是数值索引也可以是关联索引。下标与数组元素值之间用“=>”进行连接,不同数组元素之间用逗号进行分隔。
应用array()函数定义数组比较灵活,可以在函数体中只给出数组元素值,而不必给出键名。例如:

运行结果如下:

注意
自PHP 5.4起可以使用短数组定义语法,用[]替代array(),如$array=[“asp”, “php”, “jsp”];。
在使用array()函数创建的数组中的数据时,可以直接利用它们在数组中的排列顺序取值,这个顺序称为数组的下标。例如:

运行结果如下:

注意
使用这种方式定义数组时,下标默认从0开始,而不是1,然后依次增加1。所以下标为2的元素是指数组的第3个元素。
例如,下面将通过array()函数创建数组,代码如下:

运行结果如下:

5.2.2 通过赋值方式创建数组
PHP中另一种比较灵活的数组创建方式是直接为数组元素赋值。如果在创建数组时不知道所创建数组的大小,或在实际编写程序时数组的大小可能发生改变,采用这种数组创建的方法较好。
为了加深读者对这种数组声明方式的理解,下面通过具体实例对该种数组声明方式进行讲解,代码如下:

运行结果如下:

注意
通过直接为数组元素赋值方式创建数组时,要求同一数组元素中的数组名相同,例子中都赋值给$array。
5.3 数组的类型

视频讲解
PHP支持两种数组:索引数组(indexed array)和关联数组(associative array),前者使用数字作为键,后者使用字符串作为键。
5.3.1 数字索引数组
PHP数字索引一般表示数组元素在数组中的位置,它由数字组成,数字索引数组默认索引值从数字0开始,不需要特别指定,PHP会自动为索引数组的键名赋一个整数值,然后从这个值开始自动增量,当然,也可以指定从某个位置开始保存数据。我们可以使用数字索引定义5.1节中的2017年NBA全明星西部首发数组,如图5.3所示。

图5.3 NBA全明星西部首发数组数字索引
例如,创建两个数组$project1和$project2,具体代码如下:

运行结果如下:

5.3.2 关联数组
关联数组(associative array)的键名可以是数值和字符串混合的形式,而不像数字索引数组的键名只能为数字,在一个数组中,只要键名中有一个不是数字,那么这个数组就称为关联数组。以水果名称和价格的数组为例,键为水果名称,值为水果价格,如图5.4所示。

图5.4 关联数组示意图
创建一个关联数组,代码如下:

运行结果如下:

多学两招
关联数组的键名可以是任何一个整数或字符串。如果键名是一个字符串,则不要忘了给这个键名或索引加上一个定界修饰符——单引号(')或双引号(")。
5.4 多维数组

视频讲解
数组不一定就是一个键和值的简单列表,数组中的每个位置还可以保存另一个数组。使用这种方法,可以创建一个二维数组。以某酒店的楼层和房间号为例,如图5.5所示,每一个楼层都是一个一维数组,楼层数本身又构成了一个数组,这样一间酒店就构成了一个二维数组。

图5.5 二维表结构的楼层房间号
二维数组常用于表示表,表中的信息以行和列的形式表示,第一个下标代表元素所在的行,第二个下标代表元素所在的列。下面使用具体的实例来创建一个二维数组,代码如下:

运行结果如图5.6所示。

图5.6 输出二维数组运行结果
5.5 遍历数组

视频讲解
遍历数组中的所有元素是常用的一种操作,在遍历的过程中可以完成查询等功能。在生活中,如果想要去商场买一件衣服,就需要在商场中逛一遍,看是否有想要的衣服,逛商场的过程就相当于遍历数组的操作。在PHP中遍历数组的方法有多种,下面介绍最常用的foreach遍历数组。
【例5.01】 通过foreach结构遍历数组获取数据信息,代码如下:(实例位置:资源包\源码\05\5.01)

运行结果如图5.7所示。

图5.7 foreach遍历数组运行结果图
在上面的代码中,PHP为$url的每个元素依次执行循环体(echo语句)一次,将$link赋值给当前元素的值,其中$key为数组的键值。各元素按数组内部顺序进行处理。
5.6 统计数组元素个数

视频讲解
在PHP中,使用count()函数对数组中的元素个数进行统计。语法格式如下:

参数及返回值说明如下。
array:必要参数。输入的数组。
mode:可选参数。COUNT_RECURSIVE(或1),如选中此参数,本函数将递归地对数组计数。对计算多维数组的所有单元尤其有用。此参数的默认值为0。
返回值:返回array中的单元数量。
例如,使用count()函数统计数组元素的个数,代码如下:

运行结果如下:

例如,使用count()函数递归地统计数组中图书数量并输出,代码如下:

运行结果如下:

注意
在统计二维数组时,如果直接使用count()函数只会显示一维数组的个数,所以参数设为COUNT_RECURSIVE(或1),对计算多维数组的所有单元尤其有用。
5.7 查询数组中指定元素

视频讲解
array_search()函数可以在数组中搜索给定的值,找到后返回键名,否则返回false。语法格式如下:

参数及返回值说明如下。
needle:指定在数组中搜索的值。
haystack:指定被搜索的数组。
strict:为可选参数,默认值为false。如果值为true,还将在数组中检查给定值的类型。
返回值:如果找到了needle则返回它的键,否则返回false。
【例5.02】 明日学院图书效率排行榜中,排名前四位的PHP书籍分别是《零基础学PHP》《PHP项目开发实战入门》《PHP从入门到精通》《PHP开发实战》,其对应的价格依次是69.80元、69.80元、62.90元、55.90元。使用array_search()函数查询图书《PHP从入门到精通》的价格。代码如下:(实例位置:资源包\源码\05\5.02)

上述代码中,使用array_search()函数查询$book_name变量在$book数组中的下标,根据该下标获取$price价格数组中对应的值。运行结果如图5.8所示。

图5.8 查询数组中元素的值
5.8 获取数组中最后一个元素

视频讲解
通过函数array_pop()获取数组中的最后一个元素。语法格式如下:

参数及返回值说明如下。
array:输入的数组。
返回值:返回数组的最后一个单元,并将原数组的长度减1,如果数组为空(或者不是数组)将返回null。
例如,应用array_pop()函数获取数组中的最后一个元素,代码如下:

运行结果如下:

5.9 向数组中添加元素

视频讲解
通过array_push()函数向数组中添加元素。array_push()函数将数组当成一个栈,将传入的变量压入该数组的末尾,该数组的长度将增加入栈变量的数目,返回数组新的元素总数。语法格式如下:

参数及返回值说明如下。
array:指定的数组。
var:压入数组中的值。
返回值:数组新的单元总数。
例如,应用array_push()函数向数组中添加元素,代码如下:

运行结果如下:

5.10 其他常用数组函数

视频讲解
由于篇幅有限,本章不能将数组函数逐一介绍,在此列举出其他常用数组函数,使读者先简单了解一下函数用途。在遇到问题需要使用时,可查找PHP手册,查找相应函数的用法,实现自己的功能。
5.10.1 数组排序函数
常用的数组排序函数如表5.1所示。
表5.1 数组排序函数

【例5.03】 明日学院网站的社区中,有一个热帖功能,即根据帖子的回复数量由多到少作为热帖的排名顺序。帖子数组如下所示:

实现根据reply_num由多到少进行排序的功能,代码如下:(实例位置:资源包\源码\05\5.03)

运行结果如图5.9所示。

图5.9 帖子排序运行结果
5.10.2 数组计算函数
常用的数组计算函数如表5.2所示。
表5.2 数组计算函数

【例5.04】 模拟淘宝多条件筛选商品的功能,根据手机品牌筛选出商品数组$brand,根据手机颜色筛选出商品数组$color。现选择品牌为iPhone,颜色为“土豪金”的手机。使用array_intersect()函数实现该功能。代码如下:(实例位置:资源包\源码\05\5.04)

运行结果如图5.10所示。

图5.10 array_intersect()函数获取交集
5.11 小结
本章的重点是数组的常用操作,这些操作在实际应用中经常使用。另外,PHP提供了大量的数组函数,完全可以在开发任务中轻松实现所需要的功能。希望通过本章的学习,读者能够举一反三,对所学知识进行灵活运用,开发实用的PHP程序。
5.12 实战
5.12.1 使用foreach遍历课程列表
实例位置:资源包\源码\05\实战\01
在明日学院网站的课程分类中,有如下数组:

使用foreach嵌套foreach,输出该课程列表,运行结果如图5.11所示。

图5.11 foreach循环嵌套
5.12.2 使用foreach生成标签链接
实例位置:资源包\源码\05\实战\02
在博客首页中,左侧通常会有一个标签栏。当用户单击相应的标签后,页面即跳转到该标签下文章列表页。根据标签数组,使用foreach生成标签链接,如图5.12所示。

图5.12 遍历标签列表
5.12.3 使用array_unique()函数去除重复数据
实例位置:资源包\源码\05\实战\03
在明日学院网站的后台,可以添加相应版块的版主功能。每个版块可以有多个版主,用“,”分隔版主名称,如PHP版块的版主有“张三,李四,王五,赵六,张三”。试着使用array_unique()函数去除重复的版主名称。运行结果如图5.13所示。

图5.13 使用array_unique()函数去除重复数据