首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP list()函數深度解析:陣列解構賦值完全指南

     編輯:PHP 相關知識

list() 是什麼?

list() 是PHP的語言構造(非函數),用於將數值索引陣列的值一次性賦值給多個變數。類似於現代語言的「解構賦值」,是處理固定結構陣列(如資料庫查詢結果、CSV行、爆炸字串)的利器。

基本語法與核心規則

list($var1, $var2, $var3) = $array;
// 等同於
$var1 = $array[0];
$var2 = $array[1];
$var3 = $array[2];

⚠️ 關鍵限制(必讀)

限制說明範例
僅支援數值索引關聯陣列(string key)無效list($a, $b) = ['x'=>1, 'y'=>2]; // $a=null, $b=null
索引必須從0開始連續缺失索引會導致對應變數為nulllist($a, $b) = [1=>'a', 2=>'b']; // $a=null
賦值順序:從右至左影響引用賦值與副作用操作見下文「陷阱」章節
PHP 7.1+ 支援指定鍵名list('key' => $var) = $arr下文有詳細範例

實戰範例全集

範例 1:基礎用法 - 完全解構

<?php
$info = ['coffee', 'brown', 'caffeine'];

// 一次賦值三個變數
list($drink, $color, $power) = $info;
echo "$drink is $color and $power makes it special.\n";
// 輸出: coffee is brown and caffeine makes it special.

範例 2:部分解構 - 跳過不需要的值

<?php
$info = ['coffee', 'brown', 'caffeine'];

// 只取第一、三個值(中間留空)
list($drink, , $power) = $info;
echo "$drink has $power.\n";
// 輸出: coffee has caffeine.

// 只取第三個值
list(, , $power) = $info;
echo "I need $power!\n";
// 輸出: I need caffeine!

範例 3:資料庫查詢結果處理(經典場景)

<?php
// 假設 $conn 為有效 mysqli 連線
$result = $conn->query("SELECT id, name, salary FROM employees");

echo "<table><tr><th>員工</th><th>薪資</th></tr>";

while (list($id, $name, $salary) = $result->fetch_row()) {
    echo "<tr>";
    echo "<td><a href='info.php?id=$id'>" . htmlspecialchars($name) . "</a></td>";
    echo "<td>" . number_format($salary) . "</td>";
    echo "</tr>";
}

echo "</table>";
$result->free();
?>

範例 4:CSV/爆炸字串處理

<?php
$csvLine = '2024-01-15,張三,工程師,80000,Taipei';
// 直接爆炸並解構
list($date, $name, $title, $salary, $city) = explode(',', $csvLine);

echo "姓名: $name, 職稱: $title, 薪資: $salary, 城市: $city";
// 輸出: 姓名: 張三, 職稱: 工程師, 薪資: 80000, 城市: Taipei

範例 5:PHP 7.1+ 新語法 - 指定鍵名解構(支援關聯陣列!)

<?php
// 僅 PHP 7.1+
$user = [
    'id' => 1001,
    'name' => '李四',
    'email' => 'lisi@example.com',
    'role' => 'admin'
];

// 指定鍵名提取,順序無關,支援關聯陣列!
list('name' => $name, 'email' => $email) = $user;
echo "Name: $name, Email: $email\n";
// 輸出: Name: 李四, Email: lisi@example.com

// 同時使用短陣列語法 []
['id' => $id, 'role' => $role] = $user;
echo "ID: $id, Role: $role";
// 輸出: ID: 1001, Role: admin

範例 6:巢狀解構(PHP 7.1+)

<?php
$data = [
    ['id' => 1, 'meta' => ['created' => '2024-01-01', 'ip' => '192.168.1.1']],
    ['id' => 2, 'meta' => ['created' => '2024-01-02', 'ip' => '10.0.0.1']]
];

foreach ($data as ['id' => $id, 'meta' => ['created' => $created, 'ip' => $ip]]) {
    echo "ID: $id, Created: $created, IP: $ip\n";
}

⚠️ 經典陷阱:從右至左賦值順序

官方文檔明確警告:list() 從最右邊參數開始賦值。對簡單變數無影響,但陣列索引賦值會產生反直覺結果:

<?php
$info = ['coffee', 'brown', 'caffeine'];

// ❌ 錯誤預期:$a[0]='coffee', $a[1]='brown', $a[2]='caffeine'
list($a[0], $a[1], $a[2]) = $info;

// ✅ 實際結果(從右至左賦值):
// 1. $a[2] = 'caffeine'
// 2. $a[1] = 'brown'  
// 3. $a[0] = 'coffee'
// 但 $a 陣列在賦值過程中被重建,最終順序顛倒!
var_dump($a);
/*
array(3) {
  [2]=> string(8) "caffeine"
  [1]=> string(5) "brown"
  [0]=> string(6) "coffee"
}
*/

正確做法:使用陣列合併或迴圈

<?php
// 方法 1:array_merge 保證順序
$a = array_merge([], $info); // [0=>'coffee', 1=>'brown', 2=>'caffeine']

// 方法 2:foreach 重建
$a = [];
foreach ($info as $k => $v) {
    $a[$k] = $v;
}

// 方法 3:PHP 7.1+ 指定鍵名(推薦)
[0 => $a[0], 1 => $a[1], 2 => $a[2]] = $info;

list() vs 現代替代方案

方案優點缺點適用場景
list()語法簡潔、無函數呼叫開銷、支援跳過值僅數值索引、賦值順序陷阱、無預設值機制固定結構數值陣列、資料庫fetch_row、explode結果
陣列解構
[$a, $b] = $arr
短語法、PHP 7.1+支援鍵名、行為一致需PHP 7.1+現代代碼庫、關聯陣列解構
extract()關聯陣列轉變數、支援前綴安全風險、變數污染、難除錯模板引擎變數注入(謹慎使用)
foreach + list迭代多維陣列解構語法較繁瑣多行資料處理

效能微基準測試

<?php
$arr = range(1, 1000000);
$iterations = 100;

// list()
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
    list($a, $b, $c) = $arr;
}
echo "list(): " . (microtime(true) - $start) . "s\n";

// 短陣列語法
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
    [$a, $b, $c] = $arr;
}
echo "[] syntax: " . (microtime(true) - $start) . "s\n";

// 直接索引
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
    $a = $arr[0]; $b = $arr[1]; $c = $arr[2];
}
echo "direct index: " . (microtime(true) - $start) . "s\n";
/*
典型輸出:
list(): 0.12s
[] syntax: 0.11s
direct index: 0.08s
差異微小,優先考慮可讀性
*/

總結

  • list() 是處理固定結構數值陣列的利器,特別適配 fetch_row()、explode()、fgetcsv() 等場景
  • PHP 7.1+ 短陣列語法 [] 更強大:支援關聯陣列鍵名指定、巢狀解構、行為更直觀
  • 避開陷阱:勿用於陣列索引賦值、注意關聯陣列不支援(舊版本)、理解從右至左賦值語義
  • 現代代碼優先使用 [] 語法,舊版本維護時使用 list()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved