PHP 陣列的解構賦值

October 24, 2017

在 JavaScript 的 ES6 中,我們可以對物件或者是陣列使用解構賦值 (a.k.a Destructuring Assignment):

const github = {
  username: 'neighborhood999',
  repo: 50,
  star: 100,
  followers: 60,
  following: 10
};

const { username, repo, star, followers, following } = github;
console.log(username) // neighborhood999
console.log(repo) // 50


const [item1, item2, ...items] = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
console.log(item1); // A
console.log(items); // ['C', 'D', 'E', 'F', 'G']

在 JavaScript 使用解構賦值後,我們可以減少命名變數這件事,對於物件我們可以使用物件內的 key,對於陣列我們可以根據我們的需求來做解構賦值。

若在 PHP 中,我們可以使用類似的函數做到這樣的需求嗎?答案是可以的!

list()

在 PHP 我們可以使用 list() 這個函式將一個陣列給解構賦值:

$someArray = ['A', 'B', 'C'];

list($a, $b, $c) = $someArray;

使用這個函式有個需要注意的地方:

在 PHP 5 中,賦值是「由右往左」,在 PHP 7 中則是「由左往右」, 如果你在陣列內使用索引來解構賦值時,你可能是希望由左往右賦值,但 PHP 5 實際上,它的結果是反轉過來的。 更多請閱讀 PHP 的 list

以下範例在 PHP 5 和 PHP 7 不同環境下執行會得到不同的結果:

$someArray = ['A', 'B', 'C'];

list($newArray[0], $newArray[1], $newArray[2]) = $someArray;

var_dump($newArray);

在 PHP 5 的結果:

array(3) {
  [2]=>
  string(1) "C"
  [1]=>
  string(1) "B"
  [0]=>
  string(1) "A"
}

在 PHP 7 的結果:

array(3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}

list() 其他的使用方式

$someArray = ['A', 'B', 'C'];

list($a, , $c) = $someArray;

某些情況下,或許我們只需要 AC 這兩個元素,那麼我們就可以直接忽略其中一個變數的賦職, 另外,如果我們賦值超過了原來陣列的索引,會拋出一個錯誤:

$someArray = ['A', 'B', 'C'];

list($a, $b, $c, $d) = $someArray; // Undefined offset: 3

關於 list 還有一些小技巧,例如:

$services = [
  ['name' => 'Github'],
  ['name' => 'TravisCI'],
  ['name' => 'Codecov']
];

$serviceNames = [];

foreach ($services as $service) {
  list('name' => $serviceNames[]) = $service;
}

var_dump($serviceNames);

在 PHP 7.1 版本後,我們可以寫得更簡潔了,不需要 list 這個 keyword:

$someArray = ['A', 'B', 'C'];

[$a, $b , $c] = $someArray;

我們只要使用 []「中括號」,就可以完成賦值了。

Reference

🔗 The List Function & Practical Uses of Array Destructuring in PHP