2023年10月29日

PHP 8 Array 教學(下):10 個必學的 PHP Array 實用作法與方法

前一篇提到了 PHP 8 Array 的基本概念,對 PHP Array 還不熟悉的人,可以先閱讀前一篇哦。

這篇接著要來介紹 10 個 PHP Array 的實用方法,讓你對 PHP Array 有更深入的了解,知道 Array 可以用來解決什麼問題,也提高對 Array 應用的熟練度。

本篇將會依序說明及介紹以下十種作法與方法:

1. count

count 可以用來取得一個 Array 中有多少筆資料,用法如下:

$nums = [10, 20, 30];
$numCount = count($nums); 

echo $numCount; // 3 

可以搭配基本的邏輯判斷使用,例如:

if (count($nums) > 0 ) {
  echo "數量大於零";
}

2. for / foreach

說起 Array,最常見的應用就是迴圈 (loop) 了。 Array 通常是存放同質性高的資料,這些資料通常也會經過類似的操作。

透過迴圈,工程師可以不用重複寫同樣的程式,相當方便。在 PHP,透過迴圈操作 Array 有兩種常見的方式,分別是 for 跟 foreach,以下分別示範兩種做法。

一樣的示範資料:

$nums = [10, 20, 30];

for 版本。利用前面提到的 count 得到 $num 中總共有多少筆資料,這邊是 3。$i 透過 $i++ 一路遞增,所以 $i 依序為 0、1、2

$i 到 3 的時候,會因為不滿足 $i < count($nums),也就是 $i < 3 的條件,而離開迴圈。

for ($i = 0; $i < count($nums); $i++) {
   echo $nums[$i].PHP_EOL;
}

foreach 版本。foreach 會自動一個接一個,讀取完整個 array ,並把每筆資料的 value 塞到 as 後方的變數,例如範例中的 $num

foreach ($nums as $num) {
   echo $num.PHP_EOL;
}

as 後面的變數名稱可以任意,只要不要跟原本的 array 或其他變數撞名即可。

這兩個版本是相同的,都會印出:

10
20
30

補充一下 foreach 的用法,還記得 array 的每筆資料都是 key-value 成對的組合嗎?前面範例只有拿出 value,其實也可以拿出 key 喔。

foreach ($nums as $key => $num) {
   echo "$key: $num".PHP_EOL;
}

這樣會印出:

0: 10
1: 20
2: 30

當 key 是字串的時候,這種用法特別好用,因為字串沒辦法透過 $i++ 來取出下一個 value。

更多關於 for / foreach,可以參考另一篇文章→這邊

3. array_key_exists

有時候我們會需要找到某個 key 是否存在 array 中,這種時候就可以透過 array_key_exists 來做。

array_key_exists 的用法很簡單,先傳入想要找的 $key,再把目標 $array 傳入,找到的話,會回傳 true,否則 false

array_key_exists(string|int $key, array $array): bool

下面的範例中,我們先檢查 "age" 這個 key 是否存在,存在的話則印出。

$student = [
  "name" => "Steve",
  "age" => 18
];
if (array_key_exists("age", $student)) {
  echo $student["age"];
}

很多時候,資料來源可能是不穩定的,或是沒辦法控制的,那就可以透過這個方法,先檢查是否存在自己想要的資料。

數字 key 當然也可以用這個 function ,只是通常會用在字串 key。

4. in_array

與前面 array_key_exists 類似,只是 in_array 是用來找 value。

in_array 需要先傳入想要找的 value,再傳入目標 array。有找到就回傳 true,否則 false

in_array(mixed $value, array $array, bool $strict = false): bool

直接看看範例:

$nums = [10, 20, 30];

// 找到
if (in_array(10, $nums)) {
  echo "yes, 10!" . PHP_EOL;
} else {
  echo "Sad, no 10" . PHP_EOL;
}

// 找不到
if (in_array(40, $nums)) {
  echo "yes, 40!" . PHP_EOL;
} else {
  echo "Sad, no 40" . PHP_EOL;
}

結果是:

yes, 10!
Sad, no 40

另外,in_array 有第三參數 strict,預設為 false,若設為true則進行資料比對時,也會檢查資料的型別(也就是使用 ===進行比對的做法)。

更多關於 in_array / array_key_exists 可以看這篇文章

5. array_merge

想要把兩個 array 合併在一起,可以透過 array_mergearray_merge 可以合併不限數量的 array。

array_merge(array ...$arrays): array

值得注意的是,對於整數 key 跟字串 key,array_merge 的行為有點小差異。

整數 Key

整數 Key 的 array,使用 array_merge 的時候,後方的 array 的值,會直接串接在前方 array 之後,並且 key 會接續往下遞增。範例如下:

$nums1 = [10,20];
$nums2 = [40,50];
$nums3 = array_merge($nums1, $nums2);
$nums4 = array_merge($nums2, $nums1);

print_r($nums3);
print_r($nums4);

結果分別為:

// $nums3 = array_merge($nums1, $nums2);
Array
(
    [0] => 10
    [1] => 20
    [2] => 40
    [3] => 50
)
// $nums4 = array_merge($nums2, $nums1);
Array
(
    [0] => 40
    [1] => 50
    [2] => 10
    [3] => 20
)

字串 Key

整數 Key 的 array,使用 array_merge 的時候,後方的 array 會接在前方 array 之後。但是如果是重複的 key,後方的 value 則會蓋掉前方相同 key 的 value。

Ley 接續範例:

$student = [
  "name" => "Steve",
  "age" => 18
];
$student2 = array_merge($student, ["color" => "red"]);
print_r($student2);

/**
結果:
Array
(
    [name] => Steve
    [age] => 18
    [color] => red
)
**/

Key 覆蓋範例,可以看到重複出現的 "age" key,它的 value 20 覆蓋掉了原本的 18。而沒有重複的 "color" 則接續在後方。

$student = [
  "name" => "Steve",
  "age" => 18
];
$student3 = array_merge($student, [
  "color" => "red",
  "age" => 20,
]);
print_r($student3);

/**
結果:
Array
(
    [name] => Steve
    [age] => 20
    [color] => red
)
**/

6. array_push

新增一個組值到 array 中,這個用法過去很常用,但目前已經被 [] 取代了。

$nums = [10, 20, 30];
array_push($nums, 40);

print_r($nums);

/**
結果:
Array (
    [0] => 10
    [1] => 20
    [2] => 30
    [3] => 40
))
**/

這段程式等同於:

$nums = [10, 20, 30];
$nums[] = 40;

官方文件建議使用 [],效能更好。

7. array_slice

想要把 array 分段就要靠這個方法。array_slice 的用法很靈活,可以有很多種不同的切割方式。

array_slice(
    array $array,
    int $offset,
    ?int $length = null,
    bool $preserve_keys = false
): array

使用 array_slice 時,我們會給予指定的 array,並設定 $offset$length

array_slice 會從指定的位置($offset)取得指定數目($length)的筆數。也可以不指定 $length,那就會全拿。

$nums = [10,20,30,40,50,60];

// 從第 2 個位置取 3 筆
$nums2 = array_slice($nums, 2, 3);
/* $nums2 為 [30,40,50] */

// 從第 3 個位置取 5 筆
$nums3 = array_slice($nums, 3, 5);
/* 
  5大於剩餘數目,所以拿到沒有為止,
  $nums3 為 [40,50,60] 
*/

// 從第 3 個位置取取全部
$nums4 = array_slice($nums, 3);
/* 
  未提供 length,從指定位置拿到最後,
  $nums4 為 [40,50,60] 
*/

別忘了,array 是從 0 開始編號。

$offset 可以使用負數,這樣位置會從 array 的最後開始往回推。array 最後一筆資料是 -1,一路往前遞減。

[ 0] [ 1] [ 2] [ 3] [ 4] [ 5]
              ↓
[-6] [-5] [-4] [-3] [-2] [-1]
// 從第 -4 個位置取 2 筆資料
$nums5 = array_slice($nums, -4, 2);
/* 
  -4 等同於位置 2,也就是 30,所以結果為
  $nums5 為 [30, 40] 
*/

8. sort

把資料排順序是常見的需求,PHP array 當然也內建了好用的 sort 方法。

直接看範例吧。先準備一個順序亂掉的 array,再把這個 array 傳入 sort 中,就會排好順序了,就是這麼簡單。

$nums = [30,10,40,20];
sort($nums);
print_r($nums);

/*
結果:Array (
    [0] => 10
    [1] => 20
    [2] => 30
    [3] => 40
)
*/

當然,排序是一個複雜的問題,因為有各種排序的方式,可以按照你的需求進行不一樣的排序。

PHP Array 當然也有提供這些選項,只是方法太多,會講不完,所以這邊先簡單整理。

  • sort:正向,依照 value,由小到大排序。
  • rsort:反向,依照 value,由大到小排序。
  • arsort / asort:依照 value 排序,但保留原本的 key。
  • ksort/ krsort:依照 key 排序。
  • usort / uasort / uksort:使用者自訂排序方式

大致是這樣,可以自行閱讀 PHP 官方文件查閱更詳細的用法哦。

9. implode

這個方法可以將 array 中的值串接起來,成為一個字串。要將 array 資料存入資料庫,或提供給前端使用時,這是個非常實用的方法。

implode(string $separator, array $array): string

其中 $separator 就是用來連接資料的任意字串,直接來看看範例。

$nums = [10, 20, 30];

implode('', $nums);
// 空字串,結果:"102030"

implode(',', $nums);
// 單字,結果:"10,20,30"

implode('---', $nums);
// 多字,結果:"10---20---30"

可以看到用法相當簡單,效果也十分顯著。不需要自己在撰寫迴圈來把資料串接起來,相當方便。

這個方法會配合另一個常用的字串處理 function,也就是:explode,是 implode
的反向處理,這邊簡單帶過。

$nums = explode('-', '10-20-30');
// $nums 為 [10, 20, 30]

10. array_map

終於到最後一個,這個是最近比較流行的 functional programming 的概念,對 PHP 開發者來說也是比較進階的用法。

array_map 被用來針對 array 中的每一筆資料做類似的操作,並回傳一個全新的 array。

在下方的範例中,我們有一個 function,叫做 square,做簡單的平方數的運算。透過 array_map,可以讓 array 中的每個值,都傳入 square 中做運算。

運算的結果,會被儲存成另一個相同資料數目的 array 回傳。

function square($n) {  
  return ($n * $n);  
}  
  
$nums = [10, 20, 30];  
$nums2 = array_map('square', $nums);  
print_r($nums2);  

結果為:

Array (
    [0] => 100
    [1] => 400
    [2] => 900
)

小結

以上是 10 個我認為實用且一定要會用的 PHP Array 的使用方法。

大部分都只有提到大概用法,其中還有很多細節需要學習,例如 array 其實也有 call by reference 跟 call by value的一些小差異。或是一些效能優化的議題,例如 copy-on-write 機制,但是這對於初學者來說還太遠了。

並且礙於篇幅,一口氣說明太多讀者會難以吸收,預期之後會再慢慢補完內容。對 PHP Array 的基本概念還不熟悉的,可以往前閱讀前一篇哦!