# PHP数组操作

## 数组转换为字符串（序列化、持久化）

**为什么要序列化？**

* Api接口通信
* 数据缓存
* 数组数据持久化（例：保存到数据库中）

**序列化的方法？**

* 方法一：函数 serialize() 可以实现
* 方法二：函数 json\_encode ()可以实现
* 方法三：函数 var\_export($items, true);
* 方法四：xml、其他自定义文件格式…
* 方法五：mcpack、protobuffer等二进制序列化方式

## 合并两个数组

通常我们会用到`+`运算符 或者`array_merge`函数。

**数组合并中**`+`**运算符 与** `array_merge` **的区别？**

**array\_merge**

* 一个数组中的值附加在前一个数组的后面
* 字符串键名，则该键名后面的值将覆盖前一个值
* 数字键名，后面的值将不会覆盖原来的值，而是附加到后面。
* **数字键名将会被重新编号。**
* 也可以是一个参数，并且该数组是数字索引的，则键名会以连续方式重新索引

**+运算符**

把右边的数组元素附加到左边的数组后面，**两个数组中都有的键名（索引和数字），则只用左边数组中的，右边的被忽略。**

**区别：**

* array\_merge ：覆盖，相同数字键追加。
* +运算符：补充，相同数字键忽略。

**示例：**

通常我们的用法是有字符串键值，去覆盖

```php
$a = array('id' => 1, 'name' => 'kitt', 'sku' => '123456');
$b = array('name' => 'kitt1', 'title' => 'hello');

print_r($a+$b);
print_r(array_merge($a,$b));
```

结果：

```php
Array ( [id] => 1 [name] => kitt [sku] => 123456 [title] => hello ) 
Array ( [id] => 1 [name] => kitt1 [sku] => 123456 [title] => hello )
```

## 数组运算符

![](https://1303647163-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT30woYyQ9bJF96Hh%2F-LfnTB5KYnkOx0V3e4EY%2F-LfnTHfGyfmhoDojBBMg%2F%E6%95%B0%E7%BB%84%E8%BF%90%E7%AE%97%E7%AC%A6.png?generation=1558862967774544\&alt=media)

## PHP数组元素查找

* 判断key是否存在：array\_key\_exists() 和 isset()
* 判断值是否存在： in\_array() 和 array\_search()
* 依据键返回值： $items\[$key]
* 依据值返回键： array\_keys ($items,$value);
* 依据给定值进行模糊查找：preg\_grep();

## PHP数组元素的过滤和移除

* 方法1：直接用unset移除元素
* 方法2：**array\_slice**从数组中取出一段
* 方法3：array\_splice把数组中的一部分去掉并用其它值取代
* 方法4：用array\_filter过滤元素
* 方法5：用array\_shift()将开头的元素移出数组
* 方法6：用array\_pop ()将最后一个元素弹出

## PHP数组排序的原理

由于数组排序并不会改变数组中的元素，而只是改变了数组中元素的位置，因而，对底层而言，实际上只是对全局的**双链表进行排序。**

申请n个额外的空间（n是数组元素个数）

然后遍历双链表，将双链表的每个节点存储到临时空间

调用排序函数zend\_qsort（内部是**快速排序算法**）对数组进行排序

排序之后，双链表中节点的位置发生了变化，因而需要调整指针的指向。

遍历数组，分别设置每一个节点的pListLast和pListNext

最后设置HashTable的pListTail

![](https://1303647163-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT30woYyQ9bJF96Hh%2F-LfnTB5KYnkOx0V3e4EY%2F-LfnTHfICCiO3dRSRY4s%2Fphp%E6%95%B0%E7%BB%84%E6%8E%92%E5%BA%8F%E5%8E%9F%E7%90%861.png?generation=1558862975219544\&alt=media)

![](https://1303647163-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT30woYyQ9bJF96Hh%2F-LfnTB5KYnkOx0V3e4EY%2F-LfnTHfKLY0usIYK-MXY%2Fphp%E6%95%B0%E7%BB%84%E6%8E%92%E5%BA%8F%E5%8E%9F%E7%90%862.png?generation=1558862971476841\&alt=media)

**PHP数组排序函数的一般特点：**

* 需要额外的空间，**因而应该尽量避免对很大的数组排序.**
* 底层使用快速排序。

## PHP数组排序函数对比

![](https://1303647163-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT30woYyQ9bJF96Hh%2F-LfnTB5KYnkOx0V3e4EY%2F-LfnTHfMfxENlEknsWif%2Fphp%E6%95%B0%E7%BB%84%E6%8E%92%E5%BA%8F%E5%87%BD%E6%95%B0%E5%AF%B9%E6%AF%94.png?generation=1558862969115160\&alt=media)

## 与PHP数组相关的其他函数

* count
* is\_array
* print\_r
* explode
* implode（join）
* extract  从数组中将变量导入到当前的符号表
* http\_build\_query 生成 URL-encode 之后的请求字符串
* parse\_str

## PHP数组函数分类

* 数组遍历相关函数：如prev, next, current, end,reset, each等
* 数组排序相关：如sort, rsort, asort, arsort, ksort, krsort, uasort, uksort
* 数组查找相关: 如in\_array, array\_search, array\_key\_exists等
* 数组分割、合并相关： array\_slice, array\_splice, implode, array\_chunk, array\_combine等
* 数组交并差：如array\_merge, array\_diff, array\_diff\_\*, array\_intersect, array\_intersect\_\*
* 作为stack/queue容器的数组： 如array\_push, array\_pop, array\_shift
* 其他的数组操作：array\_fill, array\_flip, array\_sum, array\_reverse等
