歡迎來到《21天學會PHP 8.4》的第六天!在前五天中,我們已經接觸過數組(比如用 foreach 遍歷),但今天我們將全面深入 PHP 的核心數據結構——數組。無論你是處理表單數據、讀取數據庫結果,還是構建 API 響應,數組都是你最親密的夥伴。

今日目標

  1. 理解 PHP 數組的本質:有序映射(Ordered Map)
  2. 掌握索引數組、關聯數組和多維數組的創建與操作
  3. 熟練使用常用數組函數:array_maparray_filterarray_merge
  4. 瞭解 PHP 8.4 對數組解包(...)和類型安全的增強

一、PHP 數組:不只是“列表”

在許多語言中,數組是同類型元素的線性集合。但在 PHP 中,數組是一種靈活的“有序映射”,可以同時作為:

  • 列表(List)
  • 字典(Hash/Map)
  • 集合(Set)
  • 棧或隊列(配合 array_push / array_shift

創建數組的三種方式

<?php
// 1. 使用 [](推薦,PHP 5.4+)
$fruits = ['蘋果', '香蕉', '橙子'];

// 2. 使用 array()(兼容舊版本)
$colors = array('紅', '綠', '藍');

// 3. 關聯數組(鍵值對)
$user = [
    'name' => '王芳',
    'age'  => 28,
    'city' => '上海'
];

最佳實踐:始終使用 [] 語法,簡潔且現代。


二、數組類型詳解

1. 索引數組(Indexed Array)

鍵為整數,自動從 0 開始遞增:

$days = ['週一', '週二', '週三'];
echo $days[0]; // 週一

⚠️ 注意:PHP 不要求連續索引!

$sparse = [10 => 'A', 20 => 'B'];
// $sparse[0] 不存在!

2. 關聯數組(Associative Array)

鍵為字符串(或整數),類似字典:

$config = [
    'debug' => true,
    'lang'  => 'zh-CN',
    'limit' => 100
];

echo $config['lang']; // zh-CN

3. 多維數組(Multidimensional Array)

數組的元素本身也是數組:

$students = [
    ['name' => '李雷', 'score' => 92],
    ['name' => '韓梅梅', 'score' => 88],
    ['name' => '張偉', 'score' => 76]
];

echo $students[1]['name']; // 韓梅梅

三、常用數組操作

添加/修改元素

$cart = [];
$cart[] = '牛奶';        // 自動追加到末尾
$cart['snack'] = '薯片'; // 添加關聯鍵值
$cart[0] = '麪包';       // 修改第一個元素

刪除元素

unset($cart['snack']); // 刪除指定鍵
array_pop($cart);      // 彈出最後一個元素
array_shift($cart);    // 彈出第一個元素

檢查是否存在

if (isset($user['email'])) {
    echo "郵箱已設置";
}

if (array_key_exists('phone', $user)) {
    echo "電話存在(即使值為 null)";
}

🔍 區別:isset() 返回 false 如果值為 nullarray_key_exists() 只看鍵是否存在。


四、強大內置函數:讓數組操作更高效

1. array_map():對每個元素應用函數

$numbers = [1, 2, 3];
$squares = array_map(fn($n) => $n ** 2, $numbers);
// [1, 4, 9]

2. array_filter():篩選符合條件的元素

$words = ['apple', 'hi', 'banana', 'a'];
$longWords = array_filter($words, fn($w) => strlen($w) > 2);
// ['apple', 'banana']

3. array_merge():合併數組

$a = ['x' => 1, 'y' => 2];
$b = ['z' => 3];
$merged = array_merge($a, b); // ['x'=>1, 'y'=>2, 'z'=>3]

⚠️ 注意:關聯數組合並時,相同鍵會被覆蓋!

4. array_keys() / array_values()

$user = ['name' => 'Tom', 'age' => 30];
print_r(array_keys($user));   // ['name', 'age']
print_r(array_values($user)); // ['Tom', 30]

五、PHP 8.4 新特性:數組解包(Spread Operator)增強

PHP 7.4 引入了 ... 解包操作符,PHP 8.4 進一步優化其性能與類型推斷:

<?php
$first = [1, 2, 3];
$second = [4, 5, 6];

// 合併數組(比 array_merge 更快、更清晰)
$combined = [...$first, ...$second];
// [1, 2, 3, 4, 5, 6]

// 在函數調用中解包
function sum(int $a, int $b, int $c): int {
    return $a + $b + $c;
}

$values = [10, 20, 30];
echo sum(...$values); // 60

✅ 優勢:避免 call_user_func_array,代碼更直觀。


六、實戰:處理用户訂單數據

假設你從數據庫獲取了以下訂單列表:

$orders = [
    ['id' => 101, 'amount' => 299.99, 'status' => 'paid'],
    ['id' => 102, 'amount' => 49.50,  'status' => 'pending'],
    ['id' => 103, 'amount' => 199.00, 'status' => 'paid'],
];

任務:計算所有已支付訂單的總金額。

<?php
declare(strict_types=1);

$paidOrders = array_filter($orders, fn($order) => $order['status'] === 'paid');
$total = array_sum(array_column($paidOrders, 'amount'));

echo "已支付總額: ¥" . number_format($total, 2); // ¥498.99

💡 array_column() 是提取多維數組某一列的神器!


今日小練習

  1. 創建一個關聯數組表示你的個人信息(姓名、年齡、愛好等),並用 foreach 打印。
  2. 編寫一個函數 flattenArray(array $arr): array,將二維數組展平為一維(如 [[1,2],[3,4]] → [1,2,3,4])。
  3. (挑戰)使用 array_reduce() 計算數組 [1, 2, 3, 4] 的乘積(結果應為 24)。

明日預告:第7天 —— 作用域、全局變量與超全局數組

明天我們將深入變量的作用域機制,並學習 PHP 內置的超全局數組(如 $_GET, $_POST, $_SERVER),這是 Web 開發的基礎!

內容包括:

  • 局部 vs 全局作用域
  • global$GLOBALS 的使用與風險
  • 七大超全局數組詳解
  • 如何安全處理用户輸入

準備好進入 Web 交互的世界了嗎?我們明天見!


結語

數組是 PHP 的靈魂。掌握它,你就掌握了數據組織的核心能力。今天的內容可能信息量較大,但每一條都是實戰中高頻使用的技巧。


#PHP84 #數組 #array_map #array_filter #多維數組 #編程入門 #Web開發