----- 最后更新【2022-01-09】-----
本文目录结构预览:
- 一、简介
- 二、语法
1、定义数组
2、数组运算符 - 三、类型转换
- 四、数组解包
- 五、内部指针
- 六、数组遍历
1、for循环
2、foreach循环
3、while, list(), each()组合循环
4、三种遍历方式的区别
5、for, next(), key(), current()组合 - 七、常用函数
1、对数组进行排序
2、数组与字符串间的转换
3、数组的运算
4、数组的键与值
5、数组生成器
6、回调函数的应用 - 八、经典实例
- 九、参考
一、简介
PHP 中的数组实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量)、散列表(是映射的一种实现)、字典、集合、栈、队列以及更多可能性。由于数组元素的值也可以是另一个数组,树形结构和多维数组也是允许的。
可以用 array()语言结构来新建一个数组。自 5.4 起可以使用短数组定义语法,用 [] 替代 array()。
$array = array(
0 => "bar",
1 => "foo"
);
// 自 PHP 5.4 起
$array = [
0 => "bar",
1 => "foo"
];
本文内容可能会比较多,为了方面提前知道有哪些内容,这里先作一个简要的展示:
简介->语法->类型转换->数组解包->内部指针->数组遍历->常用函数->经典实例->参考
二、语法
1、定义数组
组成数组的 key 可以是 integer 或者 string,而 value 可以是任意类型。
此外 key 会有如下的强制转换:
1)String 中包含有效的十进制 int,除非数字前面有一个 + 号,否则将被转换为 int 类型。例如键名 "8" 实际会被储存为 8。另外, "08" 不会被强制转换,因为它不是一个有效的十进制整数。
2)Float 也会被转换为 int ,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
3)Bool 也会被转换成 int。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
4)Null 会被转换为空字符串,即键名 null 实际会被储存为 ""。
5)Array 和 object 不能 被用为键名。坚持这么做会导致警告:Illegal offset type。
如果在数组定义时多个元素都使用相同键名,那么只有最后一个会被使用,其它的元素都会被覆盖。
php > $array = array(
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
);
php > var_dump($array);
array(1) {
[1]=>
string(1) "d"
}
注意:
在 PHP 8.0.0 之前,方括号和花括号可以互换使用来访问数组单元(例如 $array[42] 和 $array{42} 在上例中效果相同)。 花括号语法在 PHP 7.4.0 中已弃用,在 PHP 8.0.0 中不再支持。
# php < 8.0
php > $arr = [ 'a'=>123 ];
php > echo $arr['a'];
123
php > echo $arr{'a'};
123
# php >= 8.0
php > $arr = [ 'a'=>123 ];
php > echo $arr['a'];
123
php > echo $arr{'a'}; # 致命错误
Fatal error: Array and string offset access syntax with curly braces is no longer supported in php shell code on line 1
注意:该始终在用字符串表示的数组索引上加上引号。例如用 $foo['bar'] 而不是 $foo[bar]。(但用不着给键名为 常量 或 变量 的加上引号,否则会使 PHP 不能解析它们。)
# php < 8.0
php > $arr[a]=1111111111111111; # Warning级错误
PHP Warning: Use of undefined constant a - assumed 'a' (this will throw an Error in a future version of PHP) in php shell code on line 1
# php >= 8.0
php > $arr[a]=11111111111; #致命错误
Warning: Uncaught Error: Undefined constant "a" in php shell code:1
Stack trace:
#0 {main}
thrown in php shell code on line 1
注意:但是在字符串中引用数组时则不需要加给索引加引号
php > $arr['a'] = 123;
php > echo "My array: $arr[a]."; # 正确,但不建议这种写法,容易与常量混淆
My array: 123.
php > echo "My array: $arr['a']."; # 语法错误
Parse error: syntax error, unexpected string content "", expecting "-" or identifier or variable or number in php shell code on line 1
php > echo "My array: {$arr['a']}."; # 正确,官方建议
My array: 123.
2、数组运算符
例子 | 名称 | 结果 |
---|---|---|
$a + $b | 联合 | $a 和 $b 的联合。 |
$a == $b | 相等 | 如果 $a 和 $b 具有相同的键/值对则为 TRUE。 |
$a === $b | 全等 | 如果 $a 和 $b 具有相同的键/值对并且顺序和类型都相同则为 TRUE。 |
$a != $b | 不等 | 如果 $a 不等于 $b 则为 TRUE。 |
$a <> $b | 不等 | 如果 $a 不等于 $b 则为 TRUE。 |
$a !== $b | 不全等 | 如果 $a 不全等于 $b 则为 TRUE。 |
+
运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略。
php > $a = array("a" => "apple", "b" => "banana");
php > $b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
php > $c = $a + $b;
php > var_dump($c);
array(3) {
["a"]=>
string(5) "apple"
["b"]=>
string(6) "banana"
["c"]=>
string(6) "cherry"
}
数组中的单元如果具有相同的键名和值则比较时相等。
php > $a = array("apple", "banana");
php > $b = array(1 => "banana", "0" => "apple");
php > var_dump($a == $b);
bool(true)
php > var_dump($a === $b);
bool(false)
三、类型转换
对于任意 integer
,float
,string
,boolean
和 resource
类型,如果将一个值转换为数组,将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值。换句话说,(array) $scalarValue
与 array($scalarValue)
完全一样。
如果一个 object
类型转换为 array,则结果为一个数组,其单元为该对象的属性。键名将为成员变量名,不过有几点例外: 私有变量前会加上类名作前缀;保护变量前会加上一个 '*' 做前缀。这些前缀的前后都各有一个 NUL 字节。 未初始化的类型属性将会被丢弃。如下:
php > class A {
private $B = 111;
protected $C = 222;
public $D = 333;
function __construct()
{
$E = 444;
$this->{1} = 555;
}
}
php > var_export((array) new A());
array (
'' . "\0" . 'A' . "\0" . 'B' => 111,
'' . "\0" . '*' . "\0" . 'C' => 222,
'D' => 333,
1 => 555,
)
php > var_dump((array) new A());
array(4) {
[" A B"]=>
int(111)
[" * C"]=>
int(222)
["D"]=>
int(333)
[1]=>
int(555)
}
将 NULL 转换为 array 会得到一个空的数组。
四、数组解包
在 array 定义时,用 ...
前缀的一个 array 可以被展开到当前位置。 只有实现了 Traversable(可以使用 foreach 进行遍历)的数组和对象才能被展开。 PHP 7.4.0 开始可以使用 ...
解包 array。
它可以多次使用,在 ...
操作符前后都可以添加常规元素:
php > $arr1 = [111, 222, 333];
php > $arr2 = ['apple','pear'];
php > $arr3 = [0,...$arr1,...$arr2,444];
php > var_dump($arr3);
array(7) {
[0]=>
int(0)
[1]=>
int(111)
[2]=>
int(222)
[3]=>
int(333)
[4]=>
string(5) "apple"
[5]=>
string(4) "pear"
[6]=>
int(444)
}
...
操作符解包 array 时也遵守函数 array_merge()
的语义。 也就是说,key 为字符时,后面的字符键会覆盖之前的字符键;key 为 integer 时则会重新编号:
注意:
在 PHP 8.1 之前,带有 string 键的 array 无法解包。如:
$arr1 = ['a'=>'apple', 'b'=>'pear']; $arr2 = ['cc', ...$arr1];
这样会报错,因为数组$arr1的存在字符串键。
最新版本的 PHP 8.1+ ,已经加入了对字符串键控数组的数组解包支持:
php > $arrayA = ['a' => 1];
php > $arrayB = ['b' => 2];
php > $result = ['a' => 0, ...$arrayA, ...$arrayB];
php > var_dump($result);
array(2) {
["a"]=>
int(1)
["b"]=>
int(2)
}
五、内部指针
方法 | 说明 |
---|---|
reset | 将数组的内部指针指向第一个单元,并返回第一个数组单元的值 |
current | 返回数组中的当前单元的值 |
next | 将数组中的内部指针向前移动一位,并返回下一个单元的值 |
prev | 将数组的内部指针倒回一位,并返回前一个单元的值 |
each | 返回数组中当前的 键/值 对,并将数组指针向前移动一步(本函数已废用) |
end | 将数组的内部指针指向最后一个单元,并返回最后一个数组单元的值 |
key | 返回数组中当前单元的键名 |
例1、
php > $array = array('step one', 'step two', 'step three', 'step four');
php > echo current($array);
step one
php > next($array);
php > next($array);
php > echo current($array);
step three
php > reset($array);
php > echo current($array);
step one
例2:
php > $foo = array("Robert" => "Bob", "Seppo" => "Sepi");
php > print_r(each($foo));
Array
(
[1] => Bob
[value] => Bob
[0] => Robert
[key] => Robert
)
php > print_r(each($foo));
Array
(
[1] => Sepi
[value] => Sepi
[0] => Seppo
[key] => Seppo
)
六、数组遍历
1、for循环
适用情况,数组的下标为从0开始的连续索引。
php > $arr = ['a','b','c','d','e','f','g'];
php > $count = count($arr);
php > for($i = 0; $i < $count; $i++){
echo $arr[$i] . "==";
}
a==b==c==d==e==f==g==
2、foreach循环
foreach为php遍历数组最常用的方法。
php > $arr = array( 12, 'a'=>8, 6=>10, 'b'=> 3, 80);
php > foreach($arr as $k=>$v){
echo " $k: $v ";
}
【0: 12 】【a: 8 】【6: 10 】【b: 3 】【7: 80 】
可以通过引用传递 array 的值来直接更改数组的值。
php > $colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as &$color) {
$color = strtoupper($color);
}
php > unset($color); /* 确保后面对 $color 的写入不会修改最后一个数组元素 */
php > print_r($colors);
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
3、while, list(), each()组合循环
php > $arr = array( 12, 'a'=>8, 6=>10, 'b'=> 3, 80);
php > while(list($key,$val) = each($arr)){
echo "【 $key: $val 】";
}
【 0: 12 】【 a: 8 】【 6: 10 】【 b: 3 】【 7: 80 】
注意:由于 list 方法的不确定性,不建议使用该方法遍历数组,了解一下即可。
4、三种遍历方式的区别
- for循环只能遍历索引数组
- foreach可以遍历索引和关联数组
- while、list()、each()组合循环同样可以遍历索引和关联数组
- while、list()、each()组合不会reset()
- foreach遍历会对数组进行reset()操作
5、for, next(), key(), current()组合
也是了解即可。
php > $arr = array( 12, 'a'=>8, 6=>10, 'b'=> 3, 80);
php > $count = count($arr);
php > for($i=0; $i<$count;$i++){
$key = key($arr);
$val = current($arr);
echo "$key: $val ==\n";
next($arr);
}
0: 12 ==
a: 8 ==
6: 10 ==
b: 3 ==
7: 80 ==
//注意,当循环结束后如果再去获取key和val,将不会成功,如:
$key = key($arr);
$val = current($arr);
var_dump($key,$val); //结果为:NILL、bool(false)
七、常用函数
1、对数组进行排序
函数名称 | 排序依据 | 索引键保持 | 排序的顺序 | 说明 |
---|---|---|---|---|
array_multisort | 值 | 键值关联(string)的保持,数字类型的不保持 | 第一个数组或者由选项指定 | 对多个数组或多维数组进行排序 |
sort | 值 | 否 | 由低到高 | 对数组从最低到最高重新排序 |
rsort | 值 | 否 | 由高到低 | |
asort | 值 | 是 | 由低到高 | |
arsort | 值 | 是 | 由高到低 | 对数组进行逆向排序并保持索引关系 |
natsort | 值 | 是 | 自然排序 | |
natcasesort | 值 | 是 | 自然排序,大小写不敏感 | |
ksort | 键 | 是 | 由低到高 | |
krsort | 键 | 是 | 由高到低 | |
usort | 值 | 否 | 由用户定义 | |
uasort | 值 | 是 | 由用户定义 | |
uksort | 键 | 是 | 由用户定义 | |
shuffle | 值 | 否 | 打乱数组 | 此函数会为数组中的元素赋与新的键名,这将删除原有的键名 |
注意:
以上的所有排序函数都是直接作用于数组本身, 而不是返回一个新的有序的数组。
使用 array_multisort 对多维数组或多个数组排序,原理类似于SQL语句中Order By
的多字段排序。但是提供给array_multisort 的多个数组数组和之前的数组要有相同数量的元素。
例:
// 多个数组排序
php > $ar1 = array(10, 100, 100, 0,100);
php > $ar2 = array(1, 5, 2, 4, 3); # 和第一个数组一样拥有5个元素
php > array_multisort($ar1, $ar2);
php >
php > print_r($ar1);
Array
(
[0] => 0
[1] => 10
[2] => 100
[3] => 100
[4] => 100
)
php > print_r($ar2);
Array
(
[0] => 4
[1] => 1
[2] => 2
[3] => 3
[4] => 5
)
2、数组与字符串间的转换
函数 | 说明 |
---|---|
implode | 将一个一维数组的值转化为字符串。别名:join |
explode | 使用一个字符串分割另一个字符串,返回数组 |
split | 用正则表达式将字符串分割到数组中 |
preg_split | 通过一个正则表达式分隔字符串,返回数组。通常是比 split() 更快的替代方案 |
str_split | 根据每一段的长度,将字符串转换为数组 |
php > $str ="hypertext language, programming";
php > $keywords = preg_split("/[\s,]+/", $str);
php > print_r($keywords);
Array
(
[0] => hypertext
[1] => language
[2] => programming
)
3、数组的运算
函数 | 说明 |
---|---|
array_unique | 移除数组中重复的值。返回过滤后的数组 |
array_merge | 合并一个或多个数组。返回合并后的结果数组。 |
array_merge_recursive | 递归地合并一个或多个数组 |
array_intersect | 计算数组的交集 |
array_intersect_assoc | 带索引检查计算数组的交集 |
array_diff | 计算数组的差集 |
array_diff_assoc | 带索引检查计算数组的差集 |
array_push | 将一个或多个单元压入数组的末尾(入栈)。返回处理之后数组的元素个数。 |
array_pop | 弹出数组最后一个单元(出栈)。返回 array 的最后一个值 |
array_pad | 以指定长度将一个值填充进数组 |
array_shift | 将 array 的第一个单元移出并作为结果返回 |
array_unshift | 将传入的单元插入到 array 数组的开头 |
array_replace | 使用传递的数组替换第一个数组的元素 |
array_replace_recursive | 使用传递的数组递归替换第一个数组的元素 |
list | 把数组中的值赋给一组变量 像 array() 一样,list()不是真正的函数,而是语言结构。 |
1)— 合并一个或多个数组——array_merge。该函数与数组解包运算符(...
)原理一样。
array_merge() 将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。
如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。
如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引。
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge($array1, $array2);
print_r($result);
//以上例程会输出:
Array
(
[color] => green
[0] => 2
[1] => 4
[2] => a
[3] => b
[shape] => trapezoid
[4] => 4
)
注意:
PHP 7.4.0+ 允许不带参数调用,之前版本至少需要一个参数。
如果你想完全保留原有数组并只想新的数组附加到后面,则可用 + 运算符。
2)计算数组的交集 — array_intersect
array array_intersect ( array $array1 , array $array2 [, array $... ] )
返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。
$array1 = array("a" => "green", "red", "blue");
$array2 = array("b" => "green", "yellow", "red");
$result = array_intersect($array1, $array2);
print_r($result);
// 以上例程会输出:
Array
(
[a] => green
[0] => red
)
3)计算数组的差集 — array_diff
array array_diff ( array $array1 , array $array2 [, array $... ] )
返回一个数组,该数组包括了所有在 array1 中但是不在任何其它参数数组中的值。注意键名保留不变。
如果需要得出简单差集,可以通过如下方法:
$difference = array_merge(array_diff($a, $b), array_diff($b, $a));
4)入栈 array_push 与 出栈 array_pop
array_push() 将 array 当成一个栈,并将传入的变量压入 array 的末尾。array 的长度将根据入栈变量的数目增加。和$array[] = $var;
效果相同。
Note: 如果用 array_push() 来给数组增加一个单元,还不如用 $array[] = ,因为这样没有调用函数的额外负担。
Note: 如果第一个参数不是数组,array_push() 将发出一条警告。这和 $var[] 的行为不同,后者会新建一个数组。
array_pop() 弹出并返回 array 数组的最后一个单元,并将数组 array 的长度减一。
5)array_pad — 以指定长度将一个值填充进数组
array array_pad ( array $array , int $size , mixed $value )
函数array_pad
返回 array 的一个拷贝,并用 value 将其填补到 size 指定的长度。如果 size 为正,则填补到数组的右侧,如果为负则从左侧开始填补。如果 size 的绝对值小于或等于 array 数组的长度则没有任何填补。有可能一次最多填补 1048576 个单元。
$input = array(12, 10, 9);
$result = array_pad($input, 5, 0);
// result is array(12, 10, 9, 0, 0)
4、数组的键与值
函数 | 说明 |
---|---|
array_count_values | 统计数组中所有的值。返回一个数组: 数组的键是 array 里单元的值; 数组的值是 array 单元的值出现的次数 |
count | 计算数组中的单元数目,或对象中的属性个数 |
array_values | 返回数组中所有的值,并给其建立数字索引。 |
array_keys | 返回数组中部分的或所有的键名 |
array_key_exists | 检查数组里是否有指定的键名或索引 |
in_array | 检查数组中是否存在某个值 |
array_search | 在数组中搜索给定的值,如果成功则返回首个相应的键名 |
例1:返回数组中所有的值并给其建立数字索引
$array = array("size" => "XL", "color" => "gold");
print_r(array_values($array));
//上例会输出:
Array
(
[0] => XL
[1] => gold
)
例2:返回数组中部分的或所有的键名
array array_keys ( array $array [, mixed $search_value = null [, bool $strict = false ]] )
如果指定了可选参数 search_value,则只返回该值的键名。否则 input 数组中的所有键名都会被返回。
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));
$array = array("blue", "red", "green", "blue", "blue");
print_r(array_keys($array, "blue"));
// 以上例程会输出:
Array
(
[0] => 0
[1] => color
)
Array
(
[0] => 0
[1] => 3
[2] => 4
)
例3:在数组中搜索给定的值,如果成功则返回首个相应的键名**
mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )
大海捞针,在大海(haystack)中搜索针( needle 参数)。
如果 needle
在 haystack
中出现不止一次,则返回第一个匹配的键。要返回所有匹配值的键,应该用 array_keys()
加上可选参数 search_value
来代替。
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
例4:检查数组里是否有指定的键名或索引**
bool array_key_exists ( mixed $key , array $array )
array_key_exists() 仅仅搜索第一维的键。 多维数组里嵌套的键不会被搜索到。
$search_array = array('first' => 1, 'second' => 4);
if (array_key_exists('first', $search_array)) {
echo "The 'first' element is in the array";
}
5、数组生成器
函数 | 说明 |
---|---|
array_fill | 用给定的值填充数组。生成数组 |
array_fill_keys | 使用指定的键和值填充数组 |
range | 根据范围创建数组,包含指定的元素 |
array_combine | 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值 |
例:
php > $a = array_fill(2, 5, 'banana');
php > print_r($a);
Array
(
[2] => banana
[3] => banana
[4] => banana
[5] => banana
[6] => banana
)
php > $b = range(10, 100, 20);
php > print_r($b);
Array
(
[0] => 10
[1] => 30
[2] => 50
[3] => 70
[4] => 90
)
php > $c = array_combine($b,$a);
php > print_r($c);
Array
(
[10] => banana
[30] => banana
[50] => banana
[70] => banana
[90] => banana
)
6、回调函数的应用
函数 | 说明 |
---|---|
array_map | 为数组的每个元素应用回调函数 |
array_filter | 用回调函数过滤数组中的单元 |
array_walk | 使用用户自定义函数对数组中的每个元素做回调处理 |
array_walk_recursive | 对数组中的每个成员递归地应用用户函数。 |
array_reduce | 用回调函数迭代地将数组简化为单一的值 |
例1:array_map — 为数组的每个元素应用回调函数
array array_map ( callable $callback , array $array1 [, array $... ] )
array_map():返回数组,是为 array 每个元素应用 callback函数之后的数组。 array_map() 返回一个 array,数组内容为 array1 的元素按索引顺序为参数调用 callback 后的结果(有更多数组时,还会传入 arrays 的元素)。 callback 函数形参的数量必须匹配 array_map() 实参中数组的数量。
function cube($n) {
return ($n * $n * $n);
}
$a = array(1, 2, 3, 4, 5);
$b = array_map("cube", $a);
print_r($b);
//结果如下:
Array
(
[0] => 1
[1] => 8
[2] => 27
[3] => 64
[4] => 125
)
注意:传入两个及以上的数组时,它们元素数量将会相同。因为回调函数会并行地处理相互对应的元素。 如果几个数组的元素数量不一致:空元素会扩展短那个数组,直到长度和最长的数组一样。
function show_Spanish($n, $m) {
return "The number {$n} is called {$m} in Spanish";
}
$a = [1, 2, 3, 4, 5];
$b = ['uno', 'dos', 'tres', 'cuatro'];
$c = array_map('show_Spanish', $a, $b);
print_r($c);
//结果如下:
Array
(
[0] => The number 1 is called uno in Spanish
[1] => The number 2 is called dos in Spanish
[2] => The number 3 is called tres in Spanish
[3] => The number 4 is called cuatro in Spanish
[4] => The number 5 is called in Spanish
)
例2:array_filter — 用回调函数过滤数组中的单元
array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )
依次将 array 数组中的每个值传递到 callback 函数。如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。
如果没有提供 callback 函数, 将删除 array 中所有等值为 FALSE 的条目。
function odd($var) {
return($var & 1); // 奇数会返回1,偶数会返回0
}
function even($var) {
return(!($var & 1));
}
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10);
echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
//以上例程会输出:
Odd :
Array
(
[a] => 1
[c] => 3
[e] => 5
)
Even:
Array
(
[0] => 6
[2] => 8
[4] => 10
)
callback 函数对于想保留的值返回true,对于不想保留的值返回false。
例3:array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
bool array_walk ( array &$array , callable $callback [, mixed $userdata = NULL ] )
成功时返回 TRUE, 或者在失败时返回 FALSE。
Note: 如果 callback 需要直接作用于数组中的值,则给 callback 的第一个参数指定为引用。这样任何对这些单元的改变也将会改变原始数组本身。
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
function test_alter(&$item1, $key, $prefix) {
$item1 = "$prefix : $item1";
}
function test_print($item2, $key) {
echo "$key. $item2 <br />\n";
}
echo "Before ...:\n";
array_walk($fruits, 'test_print');
array_walk($fruits, 'test_alter', 'fruit');
echo "... and after:\n";
array_walk($fruits, 'test_print');
?>
// 以上例程会输出:
Before ...:
d. lemon
a. orange
b. banana
c. apple
... and after:
d. fruit: lemon
a. fruit: orange
b. fruit: banana
c. fruit: apple
注意:
array_walk_recursive()
— 对数组中的每个成员递归地应用用户函数。array_walk_recursive函数只将非数组元素传递到回调函数,所以从array_walk切换时不需要修改回调。
八、经典实例
1、根据父ID获取所有下级的子ID(子ID下面上可能还有子ID))
//测试数据
$data = [
0=>['id'=>1,'name'=>'zhuangsan','pid'=>4],
1=>['id'=>2,'name'=>'zhuangsan','pid'=>3],
2=>['id'=>3,'name'=>'zhuangsan','pid'=>4],
3=>['id'=>4,'name'=>'zhuangsan','pid'=>6],
4=>['id'=>5,'name'=>'zhuangsan','pid'=>2],
5=>['id'=>6,'name'=>'zhuangsan','pid'=>9]
];
/**
* 递归获取所有子id
* @param $data 数据集
* @param $pid 父id
*/
function select_tree($data,$pid){
static $treeid = array();
foreach($data as $key=>$val){
if($pid==$val['pid']){
$treeid[] = $val['id'];
select_tree($data,$val['id']);
}
}
return $treeid;
}
$res = select_tree($data,4);
var_dump($res);
//运行结果:
root@Chan:~$ php demo11.php
array(4) {
[0] =>
int(1)
[1] =>
int(3)
[2] =>
int(2)
[3] =>
int(5)
}
注意: 此类型题数据中不允许出现层级循环,否则该递归方法将出现死循环,程序报错!
扩展: 要求不使用递归,写出一个解决上题的方法。
2、写一个函数,要求不使用array_merge完成多个数组的合并
$arr1 = ['2'=>'no',5=>100,3];
$arr2 = [1,2,3];
$arr3 = [1=>'a','b','c'];
function array_mer(){
$return = [];
$arrays = func_get_args();
foreach($arrays as $arr){
foreach($arr as $v){
$return[] = $v;
}
}
return $return;
}
$arr = array_mer($arr1,$arr2,$arr3);
var_dump($arr);
结果如下(与array_merge函数返回的结果一样):
array (size=9)
0 => string 'no' (length=2)
1 => int 100
2 => int 3
3 => int 1
4 => int 2
5 => int 3
6 => string 'a' (length=1)
7 => string 'b' (length=1)
8 => string 'c' (length=1)
九、参考:
1、官方文档:
- Array 数组类型:http://php.net/manual/zh/language.types.array.php
- 数组函数:http://php.net/manual/zh/ref.array.php
- 数组操作符:https://www.php.net/manual/zh/language.operators.array.php
- 对数组进行排序:https://www.php.net/manual/zh/array.sorting.php
2、相关书籍:
- 《PHP经典实例》 David Sklar & Adam Trachtenb
网友评论