PHP 的 Array 比較特別的地方是,
它其實可以是其他語言的 MAP,也可以是 List、Hash Table、Dictionary!
在 PHP 中,通常把我們能在 Array 中使用 String key 與一組值對應的行為稱做 Associative Array。
在大多數時候,PHP 的 Associative array都能作為一種很優秀的 JSON 資料呈現、撰寫的方式~
比如下面的這段描述歌曲資料的 JSON 就能透過 Assoc array 的方式撰寫:
{
"status": "OK",
"message": "it's Ok I said",
"data": [
{
"id": "77390b1c949ec9f032d8cee769a2e04f",
"name": "五里霧中",
"artist": "康士坦的變化球",
"album": "擱淺的人"
},
{
"id": "299cddc93f2c7b2a7963e4b3be8db4f0",
"name": "Pensées",
"artist": "Mashk, Soul Button",
"album": "Pathos"
},
{
"id": "24b292eb83ff904e2efbb6494448f646",
"name": "Казался странным",
"artist": "Елена Темникова",
"album": "TEMNIKOVA II"
}
]
}
再來是對應的 PHP 語法:
(如果單純把 PHP 的 Array 當成其他語言的 List 來用就很可惜了。)
<?php
$data = [
'status' => 'OK',
'message' => 'it\'s Ok I said',
'data' => [
[
'id' => '77390b1c949ec9f032d8cee769a2e04f',
'name' => '五里霧中',
'artist' => '康士坦的變化球',
'album' => '擱淺的人',
],
[
'id' => '299cddc93f2c7b2a7963e4b3be8db4f0',
'name' => 'Pensées',
'artist' => 'Mashk, Soul Button',
'album' => 'Pathos',
],
[
'id' => '24b292eb83ff904e2efbb6494448f646',
'name' => 'Казался странным',
'artist' => 'Елена Темникова',
'album' => 'TEMNIKOVA II',
],
],
];
echo(json_encode($data));
Assoc Array 中自訂 String key 的地方其實就是在提供一個 Object;
而不特別指定 String key 的地方就是在提供一個單純的 Array~
注意 json_decode()
的第二個參數可以指定要把 Object 的部分轉成 stdClass 或是 Assoc Array。
這一點影響到你後續如何在 PHP 中查找你收到的資料。
『...可變參數函數是指一個函數擁有不定引數,即是它接受一個可變數目的參數。...』
~ 維基百科
這段話的意思是,
PHP 接受我們宣告一個能接受不恆等數量參數的 Function!
比如當我們不確定這個 function 後續會如何擴充它需要哪些變數,
就可以使用 ... 來宣告這個 function 的參數。
讓我們延續上一章的資料來舉例,
底下是一個能計算歌曲資料(用 Object 來計算)其 md5 的 function :
在這個章節我會使用到上個段落的
$data
但這章節的 $data 是透過 json_decode($data, FALSE) 輸出的
<?php
function calculateMd5ForObject(stdClass $row): String
{
/*
* 這邊我透過把 object 的資訊,
* 用 debug 時常用的 var_export 轉成 string,再拿 string 去計算 md5。
*
* @see http://php.net/manual/en/function.var-export.php
*/
return md5(var_export($row, TRUE));
}
$data = json_decode(json_encode($data), FALSE);
echo calculateMd5ForObject($data->data[0]);
上面這個 Function 被設計成只能一次計算一個 Object 的 md5,
如果我們想得到數筆資料的 md5 就只能用 foreach
或 array_map
依序執行。
但只要改寫一下 function 就能簡化掉使用 foreach
的麻煩:
<?php
function calculateMd5ForObjects(stdClass $rowA, stdClass $rowB, stdClass $rowC): array
{
$rows = [$rowA, $rowB, $rowC];
/*
* @see http://php.net/manual/en/function.array-map.php
*/
return array_map(function ($row) {
return md5(var_export($row, TRUE));
}, $rows);
}
$data = json_decode(json_encode($data), FALSE);
/*
* 使用 print_r 印出陣列的資料
* @see http://php.net/manual/en/function.print-r.php
*/
print_r(calculateMd5ForObjects(
$data->data[0],
$data->data[1],
$data->data[2]
));
上面這樣子寫,我們就能一次接受三筆資料了呢~
但是固定就是三筆,不能再多了!
不過有 ... 的幫助的話,我們可以做的更好的:
<?php
function calculateMd5ForObjects(stdClass ...$rows): array
{
/*
* @see http://php.net/manual/en/function.array-map.php
*/
return array_map(
function ($row) {
return md5(var_export($row, TRUE));
},
$rows
);
}
$data = json_decode(json_encode($data), FALSE);
print_r(calculateMd5ForObjects(
$data->data[0],
$data->data[1]
));
這樣子484看起來舒服很多呢~
而且現在這個 function 可以接受不等數量的資料輸入了,
所以在改寫 -1我是以傳入3筆資料舉例、在改寫 -2我索性就只傳兩筆資料了,
一樣可以正常運作喔~
讓我們承接改寫 -2的 function 並繼續
在改寫 -2中我們已經獲得一個可以接受不等數量變數的 function 了,
但我們可不可以也動態決定要傳幾筆資料給這個 function 計算呢?
可以的!
只要在 call function 的地方對 array
使用 ... 就可以了!
<?php
print_r(calculateMd5ForObjects(
...$data->data
));
目前$data->data
總共有 3 筆資料,所以這樣的語法等價於:
print_r(calculateMd5ForObjects(
$data->data[0],
$data->data[1],
$data->data[2]
));
這樣子的 PHP 是不是一下子變得特別動態的感覺了呢?