基本介绍
PHP中的数组是一种Keys
和Values
的组合,也就是键值对(官方称之为有序映射),其键可以是字符或整数型,其值可以是任意类型,因此可以存在多维数组。
在键Key
的实际使用上,会有如下的强制类型转换:
- 合法 十进制整数型 的字符串,会被转成整数型
- 浮点数将会去掉小数部分转成整数型
- 布尔值也会转成整数型,
TRUE = 1
、FALSE = 0
-
NULL
会被转成空字符串,即键名为''
使用count(array)
可以获取数组元素的个数。
定义数组
在定义上,可以使用[]
或是array()
函数,具体如下:
// 空数组
$array = [];
$array = array();
// 简约数组
$array = [1, '2', TRUE, NULL];
$array = array(1, '2', TRUE, NULL);
// 键值数组
$array = [0 => 'one', 1 => 2, 'three' => FALSE, 'four' => []];
$array = array(0 => 'one', 1 => 2, 'three' => FALSE, 'four' => []);
// 不一样的键
$array = [
// 布尔值会被转成0或1
FALSE => 'zero',
TRUE => 'one',
// 浮点型会被转成整数型 2
2.5 => 'two',
// 看起来像数字的字符串会被转成整数型 3
'3' => 'three',
// 重复的键会覆盖之前的定义
'3' => 'threes',
// 非整数型的字符串不会被转成整数
'3.3' => 'three 3.3',
// 键也可以是复数
-88 => 'eight',
// 我没有键,所以取之前索引中最大的整数型 + 1,即我的key为 4
'abc'
];
// 仅指定部分键
$array = [
'a', // key = 0
'b', // key = 1
'x' => 'c', // key = 'x'
'10' => 'd', // key = 10
'e', // key = 11
'f' // key = 12
];
操作数组
对于数组元素的操作可以通过[键]
或是{键}
来进行,两者效果相同
// 定义数组
$array = [
'one' => '111',
222 => '222',
'three' => [
'foo' => ['abc', 'efg'],
'bar' => [123, 456],
],
];
// 下面三个是获取元素
// 111
$array['one'];
// 222
$array[222];
// efg
$array['three']['foo'][1];
// 添加一个元素
$array[333] = 'three';
// 也可以不显示指定键,自动设置索引为已有数字索引+1,即334
$array[] = '334';
// 修改一个元素
$array[334] = '我就是334';
// 删除一个元素
unset($array[334]);
// 删除整个数组
unset($array);
数组索引
在给数组新建元素的时候,如果没有指定键,那么将会取当前数组中数字索引的最大值加一来作为索引,假如当前数组没有数字索引,则索引为0
。
但需要注意的是,当前数组中的数字索引会被记录下来,例如:
// Array ( [0] => 1 [1] => 2 [2] => 3 )
$array = [1, 2, 3];
// 循环删除
foreach ($array as $key => $value) {
unset($array[$key]);
}
// 添加一个值,此时该数组为Array ( [3] => 4 )
$array[] = 4;
如这个例子中,虽然数组中的元素都已经被删光了,但它曾经最大的数字索引是2
,已经被系统记录下来了,所以给它添加新值的时候,新值的索引为3
。
因此可知,unset()
函数虽然能删除数组元素,但并不能重新更新索引。
类型转换
可以对变量使用(array)
进行强制类型转换。
但大部分类型,如Integer
、Float
、String
、Boolean
、Resource
等类型,如果将其转成数组,得到的结果都将是只有一个元素的数组,该元素索引为0
,值为该类型的变量。
用下面的代码可以更清楚的理解这一点:
$string = 'hello world';
$array = (array)$string;
// array(1) { [0]=> string(11) "hello world" }
var_dump($array);
也可以将对象转成数组,数组的成员变量名会成为数组的键,其值为数组的值,不过有的时候也会有一些意想不到的问题。
class Base{
private $name = 'Base';
}
class Child extends Base{
private $name = 'Child';
protected $foo = 'Foo';
public $bar = 'Bar';
public function hello(){
return $this->bar;
}
}
$child = new Child();
$array = (array)$child;
/*
Array
(
// 其实Child的首尾有一个NULL字符,只是无法复制过来
[Childname] => Child
// *号的首尾也有NULL字符
[*foo] => Foo
// 只有公开属性是正常的
[bar] => Bar
// Base的首尾也有NULL字符
[Basename] => Base
)
*/
print_r($array);
如上例中注释内容所述,将对象转成数组的时候,只有该对象的公开属性才能正常的转成键值,其他属性多少有一些问题。
使用须知
自PHP5.4起,可以直接对函数或方法的结果使用数组形式来进行访问,在此之前需要将其结果保存到变量后再使用。
function iArray(){
return ['hello', 'world'];
}
// hello world
echo iArray()[0] . " " . iArray()[1];
对于数组的字符串键,一定要记得加上引号
$array = [
'foo' => 123,
'bar' => 456,
];
echo $array[foo] . '<br />';
echo $array['foo'];
如这个例子中,两个echo
语句虽然输出的内容是一样的,但实际上如果查看日志信息,会发现有错误信息。
原因是PHP以为第一个echo
中的foo
是一个常量,但却又没有找到这个常量,所以没办法只能将其转成字符串形式,即'foo'
,虽然代码能运行通过,却不建议这么搞。
在一个数组的循环中,如果想要修改数组的元素,可以使用引用传递,当然也可以直接通过键值修改。
$colors = ['red', 'blue', 'green'];
print_r($colors);
echo PHP_EOL;
foreach ($colors as &$color) {
$color = strtoupper($color);
}
print_r($colors);
echo PHP_EOL;
/*
// 通过键来修改
foreach ($colors as $key => $color) {
$colors[$key] = strtoupper($color);
}
print_r($colors);
echo PHP_EOL;
*/