数组可通过下标即键获取值,键可以是数值键或关联键,数值键与值没有真正关系,它们只是表示值在数组中的位置。
遍历数组时无论使用关联键还是数值键,都依赖于数组指针,它如同书签,告诉你当前的数组位置,但你并不直接操作数组指针,而是使用内置的语言特性或函数遍历数组。
php数组不需要在创建时指定其大小,甚至不用在使用数组前先声明。
只需建立引用即可创建数组:
如果索引值是数值索引且是递增的,可以在创建时省略索引值:
使用array函数创建数组更加正式:
使用它:
list函数可在一次操作中从一个数组内提取多个值,同时为多个变量赋值:
从users.txt中读取以|分隔的以下内容:
$user = fopen("users.txt", "r");
while ($line = fgets($user, 4096)) { // fgets函数从文件中读取内容直到碰到换行符(包括在返回值中)、EOF或者已经读取了length - 1字节后停止
list($name, $occupation, $color) = explode("|", $line); // 以"|"分隔字符串,并以数组形式返回
printf("Name: %s", $name);
printf("Occupation: %s", $occupation);
printf("Favorite color: %s", $color);
}
fclose($users);
会以以下格式输出:
range函数可返回从low到high范围内(包含头尾值)的整数值组成的数组:
使用它:
以上使用小写字母也行,并且可以传入step参数设置步长:
$arr = range("a", "f", 2); // array("a", "c", "e")
测试一个变量是否为数组:
输出数组:
可使用vprintf函数输出一个数组:
$arr = range("a", "f");
vprintf("1: %s\n2: %s\n3: %s", $arr); // 将数组中的前三个值输出
运行以上程序:
如果想将以上格式化的结果发给字符串而非输出,可用vsprintf函数。
将内容发送到标准输出:
成功时返回true。它可将数组或对象的内容组织为可读性很强的格式。
使用print等普通打印函数打印数组时,只会输出Array。
$arr = ["a" => 1, "b" =>2];
print_r($arr);
运行它:
class a {
public $public_v;
private $private_v = 3;
public function func() { }
}
$aObj = new a();
print_r($aObj);
运行它:
而如果是用print等函数打印对象会报错不能转化为字符串。
如果可选参数为true,则将函数打印的输出以string形式返回而非发送到标准输出。
以下函数在数组头添加元素,所有已有的数值键都会相应更改,以反映其在数组中的新位置,但关联键不受影响:
$arr = ["a" => 1, 6 => 200];
array_unshift($arr, 3, 4);
print_r($arr);
运行它:
以下函数向数组尾添加元素,并返回添加元素后数组中的元素总数:
$arr = ["a" => 1, 6 => 200];
array_push($arr, 3, 4);
print_r($arr);
运行它:
以下函数删除数组中的第一个元素,数组中的数值键向下移,关联键不变:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4];
array_shift($arr);
print_r($arr);
运行它:
以下函数删除并返回数组的最后一个元素:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4];
array_pop($arr);
print_r($arr);
运行它:
在数组中搜索一个值,如果找到返回true:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4];
var_dump(in_array("1", $arr));
var_dump(in_array("1", $arr, true));
运行它:
可见,当第三个参数省略时默认值为false,使用==比较;为true时使用===比较。
查找数组中是否有特定键值:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4];
var_dump(array_key_exists("3", $arr));
运行它:
搜索键值时总是忽略类型的比较。
在数组中搜索一个值,找到时返回该值的键,否则返回false:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4];
var_dump(array_search("1", $arr));
var_dump(array_search("1", $arr, true));
运行它:
可见,当第三个参数省略时默认值为false,使用==比较;为true时使用===比较。
返回数组的键值组成的数组:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4, "c" => 3];
print_r(array_keys($arr));
print_r(array_keys($arr, "3"));
print_r(array_keys($arr, "3", true));
print_r(array_keys($arr, 3, true));
运行它:
第二个参数指定时,只会返回该值的键,此时,第三个参数省略时默认值为false,使用==比较;为true时使用===比较。
获取数组中所有值,下标以数值索引:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4, "c" => 3];
print_r(array_values($arr));
运行它:
获取数组中当前指针所在位置的键:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4, "c" => 3];
while($k = key($arr)) {
print("$k\n");
next($arr);
}
运行它:
函数next的作用为将数组的内部指针移动到下一个位置。
获取数组当前指针指向位置的值:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4, "c" => 3];
while($v = current($arr)) {
print("$v\n");
next($arr);
}
运行它:
返回数组当前指针指向位置的键值对,并将指针推进一个位置:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4, "c" => 3];
while($kvArray = each($arr)) {
print_r($kvArray);
}
运行它:
执行each函数时,如果当前指针位于数组末尾,则返回false。
each函数已自PHP 7.2.0起废弃,强烈建议不要使用此函数。
将数组指针指向下一个位置,并返回下一位置的值,如果当前位置是数组尾,则返回false:
将指针移动到前一个位置,并返回前一个位置的值,如果当前位置已经是数组首,则返回false:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4, "c" => 3];
print(next($arr) . "\n");
print(prev($arr));
运行它:
将数组内部指针指向第一个元素,并返回数组首元素值,数组为空时返回false:
$arr = ["a" => 1, 6 => 200, "b" => 3, 3 => 4, "c" => 3];
next($arr);
next($arr);
next($arr);
print(reset($arr)); // 输出1
将指针移动到最后一个位置,并返回数组尾值,当数组为空时,返回false:
$arr = ["a" => "", 6 => 200, "b" => 3, 3 => 4, "c" => 3];
print(end($arr)); // 输出3
以上使用数组内部指针返回值的函数可能会返回false,数组值也可能是false的,如空串""
,因此在判断返回值时最好使用===
符号,但如果数组值是布尔值的false,就会分不清是值为false还是函数返回了false:
$arr = ["a" => "", 6 => 200, "b" => 3, 3 => 4, "c" => 3];
while(current($arr) !== false) {
print(current($arr) . "\n");
next($arr);
} // 会打印整个数组
$arr = ["a" => false, 6 => 200, "b" => 3, 3 => 4, "c" => 3];
while(current($arr) !== false) {
print(current($arr) . "\n");
next($arr);
} // 不会打印任何内容
将数组各个元素传递给用户自定义函数:
用户自定义的函数必须接受两个参数,第一个参数表示数组当前值,第二个参数表示数组当前键。如果使用了array_walk函数的可选参数userdata,则将该值作为第三个参数传给函数:
function func($v, $k, $appendix) {
print("$k => $v, $appendix\n");
}
$arr = ["a" => "", 6 => 200, "b" => 3, 3 => 4, "c" => 3];
array_walk($arr, "func", "appendix");
运行它:
获取数组中值的总数:
当可选的mode参数为1时,函数递归地计算元素总数,即其中的二维数组中的元素数也会被计算。
$arr = ["a" => [1, 2], "b" => [3, [4, 5]]];
print(count($arr) . "\n"); // 输出2
print(count($arr, 1)); // 输出8
sizeof函数是count函数的别名,它们的功能是一样的。
统计每个值出现的次数:
$arr = ["a", "b", "a"];
print_r(array_count_values($arr));
运行它:
以下函数返回将参数array中的重复元素删除到只剩一个的数组,参数array是按值传递,原数组不受影响:
$arr = [1 => "a", "second" => "b", "third" => "a", "b"];
print_r(array_unique($arr));
运行它:
可见它是保留下重复元素的第一对键值对。
该函数的可选参数sort_flags = SORT_STRING
确定如何对数组值排序,默认情况下值会被作为字符串排序,但也可按数值排序(SORT_NUMERIC),或使用php默认方法排序(SORT_REGULAR),还可以根据本地化环境排序(SORT_LOCALE_STRING)。本地化环境指按法语(本地化环境为法国)或德语(本地化环境为德国)等进行排序,php默认按英语规则排序,可使用setlocale函数设置本地化环境。
逆置数组元素顺序:
$arr = ["5" => "fifth", "first" => "a", "meddle" => "b", "c"];
print_r(array_reverse($arr));
print_r(array_reverse($arr, true));
运行它:
如果可选参数preserve_keys不为true,则数字键值会从0开始重新排,否则会保留原数组的数值键值。关联键总会保持键映射。
交换数组中的键和值:
$arr = [5 => "fifth", "first" => "a", "meddle" => "b", "c"];
print_r(array_flip($arr));
运行它:
以下对数组排序的函数在php 7中排序成功时返回true,失败返回false。
对数组进行排序,不返回排序后的数组,就地对数组排序:
$arr = [5,8,3,1,4,5,9];
sort($arr);
print_r($arr);
sort函数的第二个参数取值:
1.SORT_NUMERIC:将元素转换为数值排序。
2.SORT_REGULAR:默认排序方法,按ASCII值对元素排序。ASCII排序时先大写后小写。
3.SORT_STRING:元素被转换为字符串排序。
4.SORT_LOCALE_STRING:根据当前的区域(locale)设置来把单元当作字符串比较,当前区域可以用 setlocale() 来改变。
5.SORT_NATURAL:和 natsort() 类似对每个单元以“自然的顺序”对字符串进行排序。PHP 5.4.0中新增的。
6.SORT_FLAG_CASE:不区分大小写排序字符串,能够与SORT_STRING或SORT_NATURAL通过位运算符|
合并。
sort函数是不稳定排序。
sort函数排序后的数组,其中的键全部变为数值键从0开始,关联键也一样。
函数asort可保持键的关联,不管是数值键还是关联键:
$arr = [5,8,3,1,4,5,9];
asort($arr);
print_r($arr);
运行它:
asort函数的可选参数sort_flags与sort函数的相同。
当对含有混合类型值的数组排序时可能产生不可预知的结果。
以降序对数组元素排序:
rsort函数的可选参数sort_flags与sort函数的相同。
rsort函数排序后数组的键值以数值重新排序。
保持键值对对数组进行逆序排序:
arsort函数的可选参数sort_flags与sort函数的相同。
以人们平常使用的排序机制排序:
$arr = ["a1", "a2", "a10", "a20"];
sort($arr);
print_r($arr);
natsort($arr);
print_r($arr);
运行它:
不区分大小写的自然排序:
$arr = ["a1", "A2", "a10", "a20"];
natsort($arr);
print_r($arr);
natcasesort($arr);
print_r($arr);
运行它:
按数组的键排序:
以降序对数组键排序:
根据用户自定义规则排序:
用户自定义函数接受两个输入参数,然后返回负整数(自定义函数的第一个参数小于第二个参数)、0(自定义函数的两个输入参数相等)、正整数(自定义函数的第一个参数大于第二个参数)。
$dates = array('10-10-2011', '2-17-2010', '2-16-2011', '1-01-2013', '10-10-2012'); // m-d-y形式日期
sort($dates);
print_r($dates);
natsort($dates);
print_r($dates);
function DateSort($a, $b) {
if ($a == $b) return 0;
list($amonth, $aday, $ayear) = explode('-', $a);
list($bmonth, $bday, $byear) = explode('-', $b);
// 给日期和月份补前置0,防止最后比较时数字与'-'比较
$amonth = str_pad($amonth, 2, "0", STR_PAD_LEFT);
$bmonth = str_pad($amonth, 2, "0", STR_PAD_LEFT);
$aday = str_pad($aday, 2, "0", STR_PAD_LEFT);
$aday = str_pad($aday, 2, "0", STR_PAD_LEFT);
$a = $ayear . $amonth . $aday;
$b = $byear . $bmonth . $bday;
return ($a > $b) ? 1 : -1;
}
usort($dates, 'DateSort');
print_r($dates);
运行它:
将数组合并:
返回的数组以第一个数组参数的元素开始,后面的数组中的元素依次追加到前面数组元素的后面。如果前面数组中有键已经存在,则后面同名的键的值将覆盖前面数组中相同键的值,但此行为不适用于数值键,数值键会重新顺序索引,不会覆盖前面数组中数值相同键的值:
$arr1 = [5 => "five", "a" => 1];
$arr2 = [5 => "six", "a" => 2];
print_r(array_merge($arr1, $arr2));
运行它:
合并数组时相同关联键的值放到一个数组中返回,数字索引值重新顺序排序:
$arr1 = [5 => "five", "a" => 1];
$arr2 = [5 => "six", "a" => 2];
print_r(array_merge_recursive($arr1, $arr2));
运行它:
提交一组键和值组合成数组,键和值数组数量必须相等:
$arr1 = ["first", "second"];
$arr2 = [1, 2];
print_r(array_combine($arr1, $arr2));
运行它:
返回数组中一部分:
$arr = [1, 2, 3, 4, 5, 6, 7];
print_r(array_slice($arr, 4));
print_r(array_slice($arr, -4)); // 从倒数第4个元素开始打印
print_r(array_slice($arr, 4, 2)); // 下标范围为4~6,左闭右开
print_r(array_slice($arr, 4, -1)); // 下标范围同上,左闭右开
print_r(array_slice($arr, 4, -3)); // 下标范围为4~4,左闭右开,为空
运行它:
可将可选参数preserve_keys(php 5.0.2新增)设置为true,会在返回的数组中保持键值对不变。如该可选参数不为true,该函数返回数组中数值键被改为从0开始的顺序索引,关联键保持不变。
删除数组中特定范围的元素,并返回被删除的元素:
array_splice函数的offset和length参数与array_slice函数的相同,可选参数replacement可取代被删除的部分。
返回的被删除元素组成的数组的数值键会从0开始重新索引,关联键不变。
求数组交集,以第一个数组中键值对为基准,如果后面的数组中有值相等(值都转换为字符串比较)的元素时,则返回第一个数组中的对应键值对:
$arr1 = ["first" => 1, "second" => 2, "third" => 3, "a"=> 4, "b" => 5, "c" => 6, 4 =>7];
$arr2 = ["h" => 1, 2 => 7, 4 => "2"];
print_r(array_intersect($arr1, $arr2));
运行它:
求数组键的交集:
$arr1 = ["first" => 1, "second" => 2, "third" => 3, "a"=> 4, "b" => 5, "c" => 6, 4 =>7];
$arr2 = ["h" => 1, 2 => 7, 4 => "2"];
print_r(array_intersect_key($arr1, $arr2));
运行它:
用用户自定义的方式比较数组中的键:
$arr1 = [1 => 'a', 2 => 'b'];
$arr2 = [2 => 'c', 3 => 'd', 4 => 'e'];
function com($a, $b) { // 当后边数组比第一个数组键值多1时,认为键值相等
if ($a + 1 > $b) {
return 1;
} else if ($a + 1 < $b) {
return -1;
} else {
return 0;
}
}
print_r(array_intersect_ukey($arr1, $arr2, 'com'));
运行它:
同时考虑键值对求数组交集:
$arr1 = [1 => 'a', 2 => 'b', 3 => 'e'];
$arr2 = [4 => 'a', 2 => 'b', 3 => 'd'];
print_r(array_intersect_assoc($arr1, $arr2));
运行它:
求数组值的差集,相对于第一个数组参数:
$arr1 = [1 => 'a', 2 => 'b', 3 => 'e'];
$arr2 = [4 => 'a', 2 => 'b', 3 => 'd'];
print_r(array_diff($arr1, $arr2));
运行它:
用用户自定义函数比较数组值:
$array1 = array(new stdclass, new stdclass,
new stdclass, new stdclass,
);
$array2 = array(
new stdclass, new stdclass,
);
// Set some properties for each square object
$array1[0]->width = 11; $array1[0]->height = 3;
$array1[1]->width = 7; $array1[1]->height = 1;
$array1[2]->width = 2; $array1[2]->height = 9;
$array1[3]->width = 5; $array1[3]->height = 7;
$array2[0]->width = 7; $array2[0]->height = 5;
$array2[1]->width = 9; $array2[1]->height = 2;
function compare_by_area($a, $b) {
$a = $a->width * $a->height;
$b = $b->width * $b->height;
if ($a < $b) {
return -1;
} elseif ($a > $b) {
return 1;
} else {
return 0;
}
}
print_r(array_udiff($array1, $array2, 'compare_by_area'));
运行它:
该函数测试时发现以下问题:
$arr1 = [1,2,3];
$arr2 = [1,2,5];
function comp1($a, $b) {
if ($a == $b) {
return 0;
}
return $a > $b ? 1 : -1;
}
print_r(array_udiff($arr1, $arr2, 'comp1'));
$arr1 = [0,1,2];
$arr2 = [1,2,5];
function comp2($a, $b) {
if (($a + 1) == $b) {
return 0;
}
return ($a + 1) > $b ? 1 : -1;
}
print_r(array_udiff($arr1, $arr2, 'comp2'));
以上两个运行结果不同,暂时不清楚原因:
但该函数不能实现数组值的比较:
$arr1= ['a', [1,2]];
$arr2= ['b', [1,3]];
print_r(array_diff($arr1, $arr2));
运行它:
求数组的差集,同时考虑键值对:
$arr1 = [1 => "a", 2 => "b", 3 => "c"];
$arr2 = [1 => "d", 2 => "b", 5 => "c"];
print_r(array_diff_assoc($arr1, $arr2));
运行它:
随机返回数组中的一个或多个键:
$arr = [1 => "a", 2 => "b", 3 => "c"];
print(array_rand($arr) . PHP_EOL);
print_r(array_rand($arr, 2));
多次运行它:
重新对数组元素排序:
$arr = ["first" => "a", 2 => "b", 3 => "c"];
shuffle($arr);
print_r($arr);
运行它:
可见所有的键都被重新顺序索引了。
函数shuffle在php 7中执行成功时返回TRUE,在失败时返回FALSE。
对数组中的值转换为数字求和:
$arr = ["first" => "23.4a", 2 => "1b", 3 => 23.5];
print(array_sum($arr));
运行它:
由上图,所有数组中元素都被转换为了数字。
将一个数组划分为多个多维数组,每个数组含参数size个元素:
array_chunk函数的可选参数preserve_keys的默认值为false,含义为不保持结果的键值对。
$arr = ["first" => 23.4, 2 => "1b", 3 => 23.5, 1, 2];
print_r(array_chunk($arr, 2));
print_r(array_chunk($arr, 2, true));
运行它: