PHP 数组:索引数组与关联数组

在静态语言(C、Java、Go)中,数组的定义通常是同一类型数据的连续序列,PHP 的数组从功能角度来说更加强大,可以包含任何数据类型,支持无限扩容,并且将传统数组和字典类型合二为一,在 PHP 中,传统的数组对应的是索引数组,字典类型对应的是关联数组,这得益于 PHP 底层通过哈希表实现数组功能。下面,我们就来简单介绍下 PHP 索引数组和关联数组的基本使用。

索引数组

基本使用

所谓索引数组指的是数组的键为隐式数字,并且会自动维护,就像静态语言的数组一样。我们在 php_learning/basic 目录下创建 array.php 来存放本教程编写的代码,初始化两个 PHP 索引数组如下:

<?php

$nums = [2, 4, 8, 16, 32];
$lans = ['PHP', 'Golang', 'JavaScript'];

此时,我们不必显式设置数组的键,它们会自动维护,如果通过 var_dump 函数打印它们的话:

var_dump($nums);
var_dump($lans);

输出如下:

-w561

PHP 索引数组的索引值和其他语言一样,都是从 0 开始。

对于数组而言,还可以通过 print_r 函数打印:

print_r($nums);
print_r($lans);

对应输出如下,与 var_dump 相比,隐去了数据类型,更加简洁:

-w496

增删改查

除了像上述代码那样通过指定初始值进行数组初始化,还可以初始化一个空数组,在 PHP 中,初始化空数组时不必指定数组大小,也不必指定数据类型:

$fruits = [];

然后我们可以依次往数组中追加元素:

$fruits[] = 'Apple';
$fruits[] = 'Orange';
$fruits[] = 'Pear';

此时,通过 print_r($fruits) 打印该数组,输出如下:

-w492

我们可以通过 count 函数获取数组长度。

如果要获取指定索引对应的元素值,可以通过如下这种方式:

$fruit = $fruits[0];

要更新指定索引位置对应的元素值,可以通过如下方式:

$fruits[2] = 'Banana';

要删除指定索引位置对应的元素值,可以通过 unset 函数:

unset($fruits[1]);

此时,再通过 print_r($fruits) 函数打印函数,输出结果如下:

-w482

可以看到,PHP 数组并没有自动重新编排索引,而是留出了一个「空洞」,打印 var_dump($fruits[1]) 将会报错,提示对应元素值不存在:

-w883

如果你想要获得重新编排索引的新数组,可以调用 PHP 内置数组函数 array_values 来实现:

$fruits = array_values($fruits);

再通过 print_r($fruits) 打印数组,输出如下:

-w709

要删除整个数组,可以用 unset($fruits) 实现,删除之后,$fruits 值变为 NULL并且不可用。

动态类型

到目前为止,除了初始化时无需指定数组大小和数据类型,PHP 的索引数组和传统静态语言的数组表现完全一致,接下来,我们就要来点不一样的了,PHP 数组支持任意类型数据,以上篇教程中举的例子「Laravel 精品课」这本书为例,我们可以将其所有属性都存放到一个数组里面:

$book = [
    'Laravel精品课',
    '学院君',
    2020,
    99.0,
    false
];

可以看到其中包含了所有的基本类型数据,此外,还支持数组、对象等更复杂的数据类型,如果我们试图通过 print_r($book) 打印该数组的话,输出如下:

-w588

再打印布尔类型时,false 会被转化为空字符串,true 会被转化为 1,另外浮点型数字也会被转化为对应的字符串格式数据。

另外,PHP 数组底层是哈希表驱动,所以支持无限扩容。

通过以上这两点对比,PHP 索引数组就要比传统静态语言的数组灵活的多,因为摆脱了数据类型和初始大小这两把枷锁。

关联数组

基本使用

PHP 没有字典(map/dict)这种数据类型,而是将其融入到数组中以关联数组的方式提供支持,与索引数组不同,关联数组通常需要显式指定数组元素的键,还是以「Laravel 精品课」这本书为例,如果以关联数组形式表示的话,就会是这样子:

$book = [
    'name' => 'Laravel精品课',
    'author' => '学院君',
    'publish_at' => 2020,
    'price' => 99.0,
    'published' => true
];

通过 print_r($book) 打印的话效果如下:

-w581

此时的键就不再是连续数字,而是初始化时设置的键名了。除了指定所有元素的键名外,还可以部分指定:

$book = [
    'name' => 'Laravel精品课',
    'author' => '学院君',
    'publish_at' => 2020,
    'price' => 99.0,
    'published' => true,
    '掌握 Laravel 和 Vue 技术栈,成为合格的 PHP 全栈工程师!',
    'https://xueyuanjun.com/books/master-laravel',
];

通过 print_r($book) 打印结果如下:

-w575

可以看到 PHP 会自动维护索引数组的数字索引值,非常灵活。

增删改查

关联数组的增删改查和索引数组类似,我们以 $book 为例,先初始化一个空数组:

$book = [];

然后通过指定键值对来新增元素:

$book['name'] = 'Laravel精品课';
$book['author'] = '学院君';
$book['publish_at'] = 2020;
$book['price'] = 99.0;
$book['published'] = false;
$book['desc'] = '掌握 Laravel 和 Vue 技术栈,成为合格的 PHP 全栈工程师!';
$book['url'] = 'https://xueyuanjun.com/books/master-laravel';

要获取某个元素值,比索引数组更加方便,因为可以直接通过可读性更强的键名来获取对应元素值:

$name = $book['name'];

要更新某个元素值,也可以通过指定键名来修改:

$book['price'] = 199.0

要删除某个数组元素值,依然可以通过 unset 函数:

unset($book['url']);

此时,通过 print_r($book) 打印数组,输出如下:

-w684

好了,关于 PHP 数组的基本使用学院君就简单介绍到这里,下一篇教程,我们来学习 PHP 中的运算符和控制结构。如果你对 PHP 数组底层实现感兴趣,可以参考这篇教程:https://xueyuanjun.com/post/20996

上一篇: PHP 基本数据类型

下一篇: PHP 运算符