PHP 中的数组实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。
keys似于酒店的房间号,values类似于酒店房间里存储的东西。
如果你去某个酒店住店,服务员会告诉你房间号是多少,具体房间里有存储了什么,那就需要根据房间号进到房间里就知道了。
变量只能储存一个数据,而数组则是多个变量的集合,数组就是将多个相互关联的数据组织在一起形成一个整体,作为一个单元使用。
上面说了,数组是由键值对组成的,那么如何定义数组呢?
可以用 array() 或者 [] 的方式来新建一个数组。它接受任意数量用逗号分隔的 键(key) => 值(value)对。
array(
key => value
, ...
)
自 5.4 起可以使用短数组定义语法,用 [] 替代 array()。
$array = [
key => value
, ...
]
key 只可以是 integer 或者 string。value 可以是任意类型。
当 key 是其它类型时发生转换:
包含有合法整型值的字符串会被转换为整型。例如键名 "8" 实际会被储存为 8。但是 "08" 则不会强制转换,因为其不是一个合法的十进制数值。
浮点数也会被转换为整型,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
布尔值也会被转换成整型。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
Null 会被转换为空字符串,即键名 null 实际会被储存为 ""。
数组和对象不能被用为键名。坚持这么做会导致警告:Illegal offset type。
如果在数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了。例如:
<?php
$array = array(
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
);
var_dump($array);
?>
以上例程会输出:
array(1) { [1] => string(1) "d" }
上例中所有的键名都被强制转换为 1,则每一个新单元都会覆盖前一个的值,最后剩下的只有一个 "d"。
根据 键(key) 的类型可以将数组分为:
索引数组 - 带有数字索引的数组
关联数组 - 带有指定键的数组
索引数组赋值有三种方式:
第一种:用数组变量的名字后面跟一个中括号的方式赋值,当然,索引数组中,中括号内的键一定是整数。比如,$arr[0]='苹果';
第二种:用array()
创建一个空数组,使用=>
符号来分隔键和值,左侧表示键,右侧表示值。当然,索引数组中,键一定是整数。比如,array('0'=>'苹果');
第三种:用array()
创建一个空数组,直接在数组里用英文的单引号'
或者英文的双引号"
赋值,数组会默认建立从0开始的整数的键。比如array('苹果');
这个数组相当于array('0'=>'苹果');
PHP 数组可以同时含有 integer 和 string 类型的键名,因为 PHP 实际并不区分索引数组和关联数组。如:
<?php
$arr = array(
"one" => "hello",
6 => "world",
"hello world"
);
var_dump($arr);
以上例程会输出:
array(3) { ["one"]=> string(5) "hello" [6]=> string(5) "world" [7]=> string(11) "hello world" }
最后一个值 "d" 被自动赋予了键名 7。这是由于之前最大的整数键名是 6。
可以使用用方括号语法访问和赋值数组单元:
<?php
$array = array(
"foo" => "bar",
42 => 24,
"multi" => array(
"dimensional" => array(
"array" => "foo"
)
)
);
var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>
以上例程会输出:
string(3) "bar" int(24) string(3) "foo"
方括号和花括号可以互换使用来访问数组单元(例如 $array[42] 和 $array{42} 在上例中效果相同)。
我们也可以直接对一个数组原型进行数组引用。例如:
<?php
function getArray() {
return array(1, 2, 3);
}
$secondElement = getArray()[1];
$tmp = getArray();
$secondElement = $tmp[1];
// or
list(, $secondElement) = getArray();
?>
试图访问一个未定义的数组键名与访问任何未定义变量一样:会导致 E_NOTICE
级别错误信息,其结果为 NULL
。
如果给出方括号但没有指定键名,则取当前最大整数索引值,新的键名将是该值加上 1(但是最小为 0)。如果当前还没有整数索引,则键名将为 0。
注意这里所使用的最大整数键名不一定当前就在数组中。它只要在上次数组重新生成索引后曾经存在过就行了。以下面的例子来说明:
<?php
// 创建一个简单的数组
$array = array(1, 2, 3, 4, 5);
print_r($array);
// 现在删除其中的所有元素,但保持数组本身不变:foreach ($array as $i => $value) {
unset($array[$i]);
}
print_r($array);
// 添加一个单元(注意新的键名是 5,而不是你可能以为的 0)
$array[] = 6;
print_r($array);
// 重新索引:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>
PHP 遍历数组
遍历数组有三种常用的方法:
使用for语句循环遍历数组;
使用foreach语句遍历数组;
联合使用list()、each()和while循环遍历数组。
这三种方法中效率最高的是使用foreach语句遍历数组。
使用for语句循环遍历数组要求遍历的数组必须是索引数组。例如:
<?php
$fruit=array('苹果','香蕉','菠萝');
$nums = count($fruit);
for($i=0; $i<$nums; $i++){
echo '<br>数组第'.$i.'值是:'.$fruit[$i];
}
先计算出数组$fruit中元素的个数,然后才使用在for语句,更加高效的。因为如果是for($i=0;$i< count($arr);++$i)的话,每次循环都会计算数组$arr中元素的个数,而使用上面的方式可以减去这种开销。
上面结果会输出:
数组第0值是:苹果 数组第1值是:香蕉 数组第2值是:菠萝
使用foreach语句循环遍历数组有二种方式,介绍如下:
第一种方式:
foreach(array_expression as $value){
//循环体
}
该方式只获取到数组的值(value)
第二种方式:
foreach(array_expression as $key=>$value){
//循环体
}
该方式连同键(key)也获取出来了
联合使用list()、each()和while循环遍历数组
each()函数需要传递一个数组作为一个参数,返回数组中当前元素的键/值对,并向后移动数组指针到下一个元素的位置。
list()函数,这不是一个真正的函数,是PHP的一个语言结构。list()用一步操作给一组变量进行赋值。
<?php
$fruit=array('苹果','香蕉','菠萝');
while ( list($key,$val) = each($fruit) ){
echo $key.'=>'.$val.'<br />';
}
上面的代码会输出
0=>苹果 1=>香蕉 2=>菠萝
总结:上述三种循环遍历数组的方法中建议大家使用foreach语句循环遍历数组,效率更高。
数组只中注意事项:
key 只可以是 integer 或者 string。value 可以是任意类型。
应该始终在用字符串表示的数组索引上加上引号。
获得数组的长度 - count() 函数,count() 函数用于返回数组的长度(元素数):
数组排序:
sort() - 以升序对数组排序
rsort() - 以降序对数组排序
asort() - 根据值,以升序对关联数组进行排序
ksort() - 根据键,以升序对关联数组进行排序
arsort() - 根据值,以降序对关联数组进行排序
krsort() - 根据键,以降序对关联数组进行排序