在 PHP 7.1 中,我们可以执行以下操作
<?php
[$a, $b, $c] = ['a', 'b', 'c'];
?>
之前,我们必须执行以下操作
<?php
list($a, $b, $c) = ['a', 'b', 'c'];
?>
(PHP 4, PHP 5, PHP 7, PHP 8)
list — 将变量分配为数组
与 array() 类似,这实际上不是一个函数,而是一个语言结构。 list() 用于在一个操作中分配一组变量。字符串无法解包, list() 表达式也不能完全为空。
注意:
在 PHP 7.1.0 之前, list() 仅适用于数值数组,并假设数值索引从 0 开始。
var
一个变量。
vars
更多变量。
返回分配的数组。
版本 | 描述 |
---|---|
7.3.0 | 添加了对数组解构中的引用分配的支持。 |
7.1.0 | 现在可以在 list() 中指定键。这使得能够解构具有非整数或非顺序键的数组。 |
示例 #1 list() 示例
<?php
$info = array('coffee', 'brown', 'caffeine');
// 列出所有变量
list($drink, $color, $power) = $info;
echo "$drink is $color and $power makes it special.\n";
// 列出其中一些
list($drink, , $power) = $info;
echo "$drink has $power.\n";
// 或者只跳到第三个
list( , , $power) = $info;
echo "I need $power!\n";
// list() 不适用于字符串
list($bar) = "abcde";
var_dump($bar); // NULL
?>
示例 #2 list() 的一个使用示例
<?php
$result = $pdo->query("SELECT id, name FROM employees");
while (list($id, $name) = $result->fetch(PDO::FETCH_NUM)) {
echo "id: $id, name: $name\n";
}
?>
示例 #3 使用嵌套的 list()
<?php
list($a, list($b, $c)) = array(1, array(2, 3));
var_dump($a, $b, $c);
?>
int(1) int(2) int(3)
示例 #4 list() 和索引定义的顺序
要由 list() 使用的数组的索引定义顺序无关紧要。
<?php
$foo = array(2 => 'a', 'foo' => 'b', 0 => 'c');
$foo[1] = 'd';
list($x, $y, $z) = $foo;
var_dump($foo, $x, $y, $z);
给出以下输出(注意元素的顺序,与它们在 list() 语法中写入的顺序相比)
array(4) { [2]=> string(1) "a" ["foo"]=> string(1) "b" [0]=> string(1) "c" [1]=> string(1) "d" } string(1) "c" string(1) "d" string(1) "a"
示例 #5 list() 带有键
从 PHP 7.1.0 开始, list() 现在还可以包含显式键,这些键可以作为任意表达式给出。整数键和字符串键的混合是允许的;但是,不能混合带键和不带键的元素。
<?php
$data = [
["id" => 1, "name" => 'Tom'],
["id" => 2, "name" => 'Fred'],
];
foreach ($data as ["id" => $id, "name" => $name]) {
echo "id: $id, name: $name\n";
}
echo PHP_EOL;
list(1 => $second, 3 => $fourth) = [1, 2, 3, 4];
echo "$second, $fourth\n";
上面的示例将输出
id: 1, name: Tom id: 2, name: Fred 2, 4
在 PHP 7.1 中,我们可以执行以下操作
<?php
[$a, $b, $c] = ['a', 'b', 'c'];
?>
之前,我们必须执行以下操作
<?php
list($a, $b, $c) = ['a', 'b', 'c'];
?>
从 PHP 7.1 开始,可以指定键
例如
<?php
$array = ['locality' => 'Tunis', 'postal_code' => '1110'];
list('postal_code' => $zipCode, 'locality' => $locality) = $array;
print $zipCode; // 输出 1110
print $locality; // 输出 Tunis
?>
示例显示了
$info = array('kawa', 'brązowa', 'kofeina');
list($a[0], $a[1], $a[2]) = $info;
var_dump($a);
输出
array(3) {
[2]=>
string(8) "kofeina"
[1]=>
string(5) "brązowa"
[0]=>
string(6) "kawa"
}
需要注意的是,如果在前面定义了数组,例如:
$a = [0, 0, 0];
索引将保持正确的顺序
array(3) {
[0]=>
string(4) "kawa"
[1]=>
string(8) "brązowa"
[2]=>
string(7) "kofeina"
}
我认为有必要提一下。
如前所述,如果输入数组太短,list() 将会报错。可以通过使用 array_merge() 合并一些默认值来避免这种情况。例如
<?php
$parameter = 'name';
list( $a, $b ) = array_merge( explode( '=', $parameter ), array( true ) );
?>
但是,你必须使用 array_merge() 合并一个足够长的数组,以确保有足够的元素(如果 $parameter 为空,上面的代码仍然会报错)。
另一种方法是使用 array_pad() 来确保数组的长度(如果所有需要添加的默认值都相同)。
<?php
$parameter = 'bob-12345';
list( $name, $id, $fav_color, $age ) = array_pad( explode( '-', $parameter ), 4, '' );
var_dump($name, $id, $fav_color, $age);
/* 输出
string(3) "bob"
string(5) "12345"
string(0) ""
string(0) ""
*/
?>
<?php
/**
* 似乎可以跳过列出的值。
* 这是一个展示我的意思的示例。
*
* 顺便说一下,PHP 7.1 简写列表语法也能正常工作。
* 已在 PHP 5.6.30、7.1.5 上测试
*/
$a = [ 1, 2, 3, 4 ];
// 这是 list 的常见用例
echo "解包所有值\n";
list($v1, $v2, $v3, $v4) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);
// 这就是我的意思:
echo "跳过中间\n";
list($v1, , , $v4) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);
echo "跳过开头\n";
list( , , $v3, $v4) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);
echo "跳过结尾\n";
list($v1, $v2, , ) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);
echo "保留中间\n";
list( , $v2, $v3, ) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);
示例说明了以下内容
<?php
// list() 不适用于字符串
list($bar) = "abcde";
var_dump($bar);
// 输出:NULL
?>
然而,如果字符串位于变量中,似乎使用 list() 会将字符串视为数组
<?php
$string = "abcde";
list($foo) = $string;
var_dump($foo);
// 输出:string(1) "a"
?>
如果列表中缺少元素,可以在指定默认值时使用运算符 +
<?php
$someArray = ['color' => 'orange'];
['color' => $color, 'size' => $size] = $someArray + ['color' => null, 'size' => null];
?>
这将避免出现警告“未定义的数组键“size””。
不要错过自 PHP 7 以来简单的数组模式匹配
<?php
[$a] = ['hello!'];
var_dump($a); // 'hello!'
$arr = [4 => 50];
[4 => $fifty] = $arr;
var_dump($fifty); // 50
$multidimensionalArray = [['id' => 15, 'email' => '[email protected]']];
[['id' => $id, 'email' => $email]] = $multidimensionalArray;
var_dump($id, $email); // 15 [email protected]
?>
list() 可以与 foreach 一起使用
<?php
$array = [[1, 2], [3, 4], [5, 6]];
foreach($array as list($odd, $even)){
echo "$odd 是奇数; $even 是偶数", PHP_EOL;
}
?>
输出
===
1 是奇数; 2 是偶数
3 是奇数; 4 是偶数
5 是奇数; 6 是偶数
list 结构似乎在寻找顺序索引列表,而不是按顺序获取元素。这段难以理解的语句的意思是,如果你取消设置一个元素,list 不会简单地跳到下一个元素并将其赋值给变量,而是将缺失的元素视为 null 或空变量
$test = array("a","b","c","d");
unset($test[1]);
list($a,$b,$c)=$test;
print "\$a='$a' \$b='$b' \$c='$c'<BR>";
结果是
$a='a' $b='' $c='c'
而不是
$a='a' $b='c' $c='d'
如果数组的长度超过了定义的 list 长度,list() 定义不会报错。
<?php
list($a, $b, $c) = array("a", "b", "c", "d");
var_dump($a); // a
var_dump($b); // b
var_dump($c); // c
?>
像这样设置 <?php list($var1,$varN) = null ?> 不会引发 E_NOTICE(或其他错误),而且据我所知,它等同于对 $var1,$varN 执行 https://php.net/function.unset。
我注意到这一点,因为与 PHP 触发 E_NOTICE 关于 “Undefined offset” “如果数组元素不足以填满列表()” 相比,这是相反的,正如 attow 为 https://php.net/control-structures.foreach#control-structures.foreach.list 记录的那样,并且这里只在 https://php.net/function.list#122951 中由 Mardaneus 提到。
为了完整起见,以下是一个 bash(1)(macos10.13 上的 v5.0 或 4.3)cli 测试,它为我所有 PHP 版本(通过 macports.org 安装)产生了相同的结果。它也使用 bash5.0 在 Debian10 上的 php7.3 中进行了测试。
bash --noprofile --norc -c 'for php in php{{53..56},{70..73}};do for literal in "array()" null;do echo -n $php …=$literal:&&$php -n -d error_reporting=E_ALL -r "var_dump(list(\$var)=$literal);";done;done'
# 上面的代码为每个版本产生相同的成对结果
php53 …=array()
Notice: Undefined offset: 0 in Command line code on line 1
array(0) {
}
# ... 到
php73 …=null:NULL
对于 PHP 7.1 及更高版本,文档指出整数和字符串键可以混合使用,但有键和无键的元素不能混合使用。以下是一个使用来自 getimagesize() 的数据的混合键示例。
<?php
$data=[
0=> 160,
1 => 120,
2 => 2,
3 => 'width="160" height="120"',
'mime' => 'image/jpeg'
];
list(0=>$width,1=>$height,2=>$type,3=>$dimensions,'mime'=>$mime)=$data;
?>
在这里,需要指定数字键,就好像整个数组被视为关联数组一样。
正如其他地方提到的,list() 运算符可以用数组格式编写
<?php
[0=>$width,1=>$height,2=>$type,3=>$dimensions,'mime'=>$mime]=$data;
?>
这是我在文档中没有看到的东西。
从 PHP 7.1 开始,你可以使用方括号来进行简写列表解包,就像简写数组声明一样
<?php
$foo = ['a', 'b', 'c'];
// 简写数组定义
[$a, $b, $c] = $foo;
echo $a; // 显示 "a"
// 它与以下代码相同:
list($x, $y, $z) = $foo;
echo $x; // 显示 "a"
?>
list($a, $b, $c) = ["blue", "money", 32];
简写
[$a, $b, $c] = ["blue", "money", 32];
从 PHP 7.1 开始,你可以在 list() 或者它的新简写语法 [] 中指定键。这使得解包具有非整数或非连续键的数组成为可能。
<?php
$data = [
["id" => 1, "name" => 'Tom'],
["id" => 2, "name" => 'Fred'],
];
// list() 风格
list("id" => $id1, "name" => $name1) = $data[0];
// [] 风格
["id" => $id1, "name" => $name1] = $data[0];
// list() 风格
foreach ($data as list("id" => $id, "name" => $name)) {
// 使用 $id 和 $name 执行逻辑
}
// [] 风格
foreach ($data as ["id" => $id, "name" => $name]) {
// 使用 $id 和 $name 执行逻辑
}
一个简单的使用示例,用于交换两个变量
$a = 'hello';
$b = 'world';
list($a, $b) = [$b, $a];
echo $a . ' ' . $b; // 显示 "world hello"
另一个示例
function getPosition($x, $y, $z)
{
// ... 执行一些操作,例如 $x++...
return [$x, $y, $z];
}
list($x, $y, $z) = getPosition($x ,$y, $z);
从 7.1.0 开始,你可以直接使用数组,而无需使用 list()
<?php
[$test, $test2] = explode(",", "hello, world");
echo $test . $test2; // hello, world
?>
从 PHP 7.1 开始,[] 可以作为现有 list() 语法的替代方案
<?php
[$number, $message] = explode('|', '123|Hello World!');
?>
如果你希望使用你所期望的未定义行为,例如,如果你想要
$b = ['a','b']; list($a, $b) = $b;
得到 $a=='a' 和 $b=='b' 的结果,那么你可以将 $b 转换为数组(即使它已经是数组)来创建一个副本。例如
$b = ['a','b']; list($a, $b) = (array)$b;
并获得预期的结果。
未记录的行为
list($a,$b,$c) = null;
实际上等效于
$a = null; $b = null; $c = null;
...因此,相应的
list($rows[]) = null;
将增加 count($rows),就像你执行了 $rows[] = null; 一样。
注意这一点(例如)当你从数据库中检索整个表时,例如
while (list($rows[]) = $mysqlresult->fetch_row());
这将在 $rows 的最后一个元素中留下一个额外的 'null' 条目。
除非你在使用 list() 时指定键,否则它会期望传入的数组从 0 开始。
因此,如果使用以下代码,将导致通知级警告 “Undefined offset: 0”,并且变量将无法按预期填充
<?php
list($c1, $c2, $c3) = array [1 =>'a', 2 => 'b', 3 => 'c'];
var_dump($c1); // NULL
var_dump($c2); // string(1) "a"
var_dump($c3); // string(1) "b"
?>
在变量中获取实际日期和时间值的简便方法。
list($day,$month,$year,$hour,$minute,$second) = explode('-',date('d-m-Y-G-i-s'));
echo "$day-$month-$year $hour".":".$minute.":".$second;
['a' => $x, 'b' => $y] = ['a' => 1, 'b' => 2];
echo $x . '-' . $y; // 1-2