数组是一组键和值的集合,值可以是任何一种类型
创建数组
索引数组 :键为整数,键无特殊意义,自动分配键值,从0开始
$arr = array("春","夏","秋","冬");
print_r($arr); // Array ( [0] => 春 [1] => 夏 [2] => 秋 [3] => 冬 )
关联数组 :键为字符串,键本身具有一定的意义,人工分配,如age – 年龄
$arr = array("name"=>"小张", "age"=>"18");
print_r($arr); // Array ( [name] => 小张 [age] => 18 )
多维数组 :多维数组是包含一个或多个数组的数组。
$arr = array(0=>"a", 1=>array("小张"=>"18", "小李"=>array("age"=>18,"gender"=>"男")));
print_r($arr); // Array ( [0] => a [1] => Array ( [小张] => 18 [小李] => Array ( [age] => 18 [gender] => 男 ) ) )
键的规则
键值总结
- 键是唯一的,键名相同会覆盖
- 键可以是整数【称为索引数组】 也可以是字符串【称为关联数组】
- 键只有两种类型,数字和字符串,如果不是则会强制转换
- 值可以是任意数据类型
键的自动数据类型转换
// 浮点数会自动转为整数 如:3.8会转为3
// 字符串整数会自动转为整数 如:"2"会转为2
// bool型会自动转换为0或1 如:true会转为1
// null会自动转换为空字符串
// 不能用数组和对象作为键
$arr = array(3.8=>"春",'2'=>"夏",false=>"秋",null=>"冬");
print_r($arr); // Array ( [3] => 春 [2] => 夏 [0] => 秋 [] => 冬 )
如果不声明键,自动分配键值,从0开始
$arr = array("春","夏","秋","冬");
print_r($arr); // Array ( [0] => 春 [1] => 夏 [2] => 秋 [3] => 冬 )
如果已经存在某一个或几个数字键(包括字符串类数字),则从最大的数字键递增生成数字键
$arr = array(3=>"春","夏","秋","冬");
print_r($arr); // Array ( [3] => 春 [4] => 夏 [5] => 秋 [6] => 冬 )
$arr = array("3"=>"春","夏","秋","冬");
print_r($arr); // Array ( [3] => 春 [4] => 夏 [5] => 秋 [6] => 冬 )
$arr = array(2=>"春","夏",5=>"秋","冬");
print_r($arr); // Array ( [2] => 春 [3] => 夏 [5] => 秋 [6] => 冬 )
$arr = array(2=>"春",1=>"夏","秋","冬");
print_r($arr); // Array ( [2] => 春 [1] => 夏 [3] => 秋 [4] => 冬 ) 体现了几个数字键 从最大的键开始递增
$arr = array("春","x"=>"夏","秋","冬");
print_r($arr); // Array ( [0] => 春 [x] => 夏 [1] => 秋 [2] => 冬 )
如果指定的键名已经有了值,则该值会被覆盖
// 并不报错,覆盖了重复的键值
$arr = array(3=>"春","夏","秋",3=>"冬");
print_r($arr); // Array ( [3] => 冬 [4] => 夏 [5] => 秋 )
操作数组单元
增删改查(基础)
$arr = array("a","b","c");
// 增1个单元
$arr[] = "d";
$arr[99] = "e";
$arr["stu"] = array("zy","hl");
print_r($arr); // Array ( [0] => a [1] => b [2] => c [3] => d [99] => e [stu] => Array ( [0] => zy [1] => hl ) )
// 读取单元值
echo $arr[3]; // d
echo $arr["stu"][1]; // hl
// 改单元值
$arr[0] = "A";
print_r($arr); // Array ( [0] => A [1] => b [2] => c [3] => d [99] => e [stu] => Array ( [0] => zy [1] => hl ) )
// 删除某个单元
unset($arr["0"]); // 注意不会重建索引
print_r($arr); // Array ( [1] => b [2] => c [3] => d [99] => e [stu] => Array ( [0] => zy [1] => hl ) )
遍历数组
对于索引数组 因为键是 0.1.2…的递增的 用for循环或foreach循环
// 方法一:for循环
$arr = array("a","b","c","d");
for ($i=0; $i<count($arr); $i++){ // count($arr)获取数组长度
echo $arr[$i],"<br>"; // abcd
}
// 方法二:foreach循环(推荐)
foreach ($arr as $key=>$value){
echo $value;
}
对于关联数组 用foreach循环
// 循环取出每一个单元的键和值赋给$key和$value($key和$value只是起变量的作用可以随便改)
$arr = array("name"=>"zy", "age"=>18, "gender"=>"man");
foreach ($arr as $key=>$value){
echo $key,"~",$value,"<br>";
}
// 如果只想遍历取value值 可以简化写法
foreach ($arr as $value){ // $value写成 $a都行,只是一个变量
echo $value;
}
二维数组遍历
如果是更多维数组要用递归
$arr = array(1, 2, 3, array(10, 20, 30));
foreach ($arr as $value){
if (is_array($value)){
foreach ($value as $v){
echo $v;
}
}else{
echo $value;
}
}
foreach遍历数组练习题
// 练习 使用foreach替代语法 显示导航模板
$arr = array("首页","资源","下载","反馈");
include '../html.html';
/*
<?php foreach($arr as $value):?>
<a href="#"><?php echo $value; ?></a>
<?php endforeach; ?>
*/
// 练习 使用foreach替代语法 打印水浒英雄表格 二维数组
$arr = array('a'=>array('宋江','男','及时雨'), 'b'=>array('鲁智深','男','花和尚'), 'c'=>array('林冲','男','豹子头'));
include '../html.html';
/*
<table>
<tr>
<th>姓名</th>
<th>性别</th>
<th>外号</th>
</tr>
<?php foreach($arr as $key=>$value):?>
<tr>
<?php foreach($arr[$key] as $v):?>
<td><?php echo $v; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
*/
数组指针操作
数组指针操作相关函数 current next end prev reset each
// current()函数 返回当前指针指向的数组单元的值
$arr = array("a","b","c","d");
echo current($arr);
// next()函数 将指针往后移一个单元
next($arr);
echo current($arr);
// end()函数 将指针指向数组中的最后一个单元
end($arr);
echo current($arr);
// prev()函数 将指针指往前移一个单元
prev($arr);
echo current($arr);
// reset()函数 将指针指向数组中的第一个单元(复位)
reset($arr);
echo current($arr);
使用while配合数组函数遍历数组
while ($z = current($arr)){
echo $z,"<br>";
next($arr);
}
但是碰到 false/0 等情况就会出问题
$arr = array(1,2,3,false,4,5,6);
while ($z = current($arr)){ // 括号里是个赋值操作
echo $z,"<br>"; // 1 2 3 后边不会输出 因为 $z=false
next($arr);
}
each() 函数返回当前元素的键名和键值,并将指针向后移动。
each() 函数在 PHP 7.2.0 中被弃用了。
数组运算符
$a + $b | 联合 | $a 和 $b 的联合 |
---|---|---|
$a == $b | 相等 | 如果 $a 和 $b 具有相同的键/值对则为 TRUE |
$a === $b | 全等 | 如果 $a 和 $b 具有相同的键/值对并且顺序和类型都相同则为 TRUE |
$a != $b | 不等 | 如果 $a 不等于 $b 则为 TRUE |
$a !== $b | 不全等 | 如果 $a 不全等于 $b 则为 TRUE |
细节讨论
- +运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略
- 用 == 或 != 进行比较时,会先进行自动数据类型转换
- 用 === 或 !== 进行比较时不进行类型转换,因为此时类型和数值都要比对
// + 运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略
// 注意和 array_merge函数 的区别
$arr1 = array(1, 2, 'age'=>'18');
$arr2 = array(3, 4, 'age'=>'88');
$arr3 = $arr1 + $arr2;
var_dump($arr3); // Array ([0] =>1 [1] =>2 [age] =>18)
print_r($arr3);
// 用 == 或 != 进行比较时,会先进行自动数据类型转换
// 用 === 或 !== 进行比较时不进行类型转换,因为此时类型和数值都要比对
$arr1 = array(1, 2, 3);
$arr2 = array(true, '2', 3);
var_dump($arr1 == $arr2); // boolean true
var_dump($arr1 === $arr2); // boolean false
数组的内存分配机制 (了解)
memory_get_usage — 返回分配给 PHP 的内存量
range — 建立一个包含指定范围单元的数组
echo memory_get_usage(),'<br>'; // 404560
$arr = range(1,200000);
echo memory_get_usage(),'<br>'; // 10890400
// 此处值传递, 占用内存理应变大很多,但是并没变多少
// 原因,php很聪明,当一个数组赋值给另一个数组后,新的数据空间并没有马上分配 (怕你拷贝后不用 浪费),当修改了$arr1的元素时,才会真正分配
$arr1 = $arr;
echo memory_get_usage(),'<br>'; // 10890400
// 修改了新数组元素,占用内存增加很多
$arr1[0] = 2;
echo memory_get_usage(),'<br>'; // 21376240