在 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() 用於在單一操作中指派一組變數。 字串無法被 unpack,且 list() 運算式不能完全為空。
注意:
在 PHP 7.1.0 之前,list() 僅適用於數字索引陣列,並假設數字索引從 0 開始。
從 PHP 7.1.0 開始,list() 也可以包含明確的鍵,允許解構具有非整數或非連續鍵的陣列。更多關於陣列解構的細節,請參閱陣列解構章節。
var
一個變數。
vars
更多變數。
回傳被賦值的陣列。
版本 | 說明 |
---|---|
7.3.0 | 新增了在陣列解構中支援參考賦值。 |
7.1.0 | 現在可以在 list() 中指定鍵。這使得可以解構具有非整數或非連續鍵的陣列。 |
範例 #1 list() 範例
<?php
$info = array('coffee', 'brown', 'caffeine');
// 列出所有變數
list($drink, $color, $power) = $info;
echo "$drink 是 $color 的,$power 讓它很特別。\n";
// 列出其中一些
list($drink, , $power) = $info;
echo "$drink 含有 $power。\n";
// 或者我們只取第三個
list( , , $power) = $info;
echo "我需要 $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
$someArray = ['color' => 'orange'];
['color' => $color, 'size' => $size] = $someArray + ['color' => null, 'size' => null];
?>
這樣可以避免遇到 `未定義的陣列鍵 "size"` 警告。
<?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 7 以後簡化的陣列模式匹配功能。
<?php
[$a] = ['hello!'];
var_dump($a); // 'hello!'
$arr = [4 => 50];
[4 => $fifty] = $arr;
var_dump($fifty); // 50
$multidimensionalArray = [['id' => 15, 'email' => 'diyor024@gmail.com']];
[['id' => $id, 'email' => $email]] = $multidimensionalArray;
var_dump($id, $email); // 15 diyor024@gmail.com
?>
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'
設定成像 <?php list($var1,$varN) = null ?> 並_不會_引發 E_NOTICE(或其他錯誤),而且就我所見,實際上等同於對 $var1、$varN 使用 https://php.dev.org.tw/function.unset。
我注意到這一點與 PHP 會針對「未定義的偏移量」觸發 E_NOTICE 的情況形成對比,「如果沒有足夠的陣列元素來填滿 list()」,就像 attow 在 https://php.dev.org.tw/control-structures.foreach#control-structures.foreach.list 中所記錄的,而這裡只有 Mardaneus 在 https://php.dev.org.tw/function.list#122951 中提到。
為了完整性,以下是一個 bash(1)(macOS 10.13 上的 v5.0 或 4.3)命令列測試,在我的所有 PHP 版本(透過 macports.org 安裝)中產生相同的結果。也使用 Debian 10 上的 bash 5.0 和 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()
注意:第 1 行命令列程式碼中的未定義偏移量:0
array(0) {
}
# ... 到
php73 …=null:NULL
如果您的陣列比定義的 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 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 的邏輯
}
自 7.1.0 版本起,您可以直接使用陣列,無需使用 list()
<?php
[$test, $test2] = explode(",", "hello, world");
echo $test . $test2; // hello, world
?>
一個簡單的變數交換範例
$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);
自 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() 時指定鍵值,否則它預期傳入的陣列索引從 0 開始。
因此,以下程式碼將導致通知級別的警告「未定義的偏移量: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($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($day,$month,$year,$hour,$minute,$second) = explode('-',date('d-m-Y-G-i-s'));
echo "$day-$month-$year $hour".":".$minute.":".$second;
從 PHP 7.3 開始,list() 現在支援陣列解構 - 參考:https://php.dev.org.tw/manual/en/migration73.new-features.php