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

PHP 入門筆記(二):函數、陣列與進階資料結構操作

     編輯:PHP 相關知識

前言

PHP 函數與陣列是寫出高效、優雅代碼的核心工具。PHP 函數支援預設參數、參考傳遞、可變參數、匿名函數等現代特性;而 PHP 陣列更是「有靈魂的陣列」——融合了有序陣列、關聯陣列、堆疊、佇列、集合於一身。本文深度解析函數進階特性與陣列完整操作 API。

一、函數進階特性

1. 參考傳遞


function addPrefix(&$str, $prefix = 'PRE_') {
    $str = $prefix . $str;
}

$name = 'PHP';
addPrefix($name);        // $name 變為 'PRE_PHP'
addPrefix($name, 'NEW_'); // $name 變為 'NEW_PRE_PHP'

用途:修改呼叫端變數、大型資料避免複製開銷(PHP 7+ 寫時複製機制已優化,較少需要)。

2. 預設參數值


function greet($name = 'Guest', $greeting = 'Hello') {
    echo "$greeting, $name!";
}

greet();              // Hello, Guest!
greet('Alice');       // Hello, Alice!
greet('Bob', 'Hi');   // Hi, Bob!
// greet(greeting: 'Hey', name: 'Tom'); // PHP 8.0+ 命名參數

規則:預設參數必須在非預設參數之後;預設值必須是常數表達式(不可為變數、函式呼叫)。

3. 遞迴函數


function factorial(int $n): int {
    if ($n <= 1) return 1;
    return $n * factorial($n - 1);
}

echo factorial(5); // 120

注意:PHP 無尾呼叫優化,深度遞迴會耗盡記憶體(預設 `memory_limit` 128M),大數據遞迴改用迭代。

4. 可變參數 (`...`)


function sum(...$numbers): float {
    return array_sum($numbers);
}

echo sum(1, 2, 3);       // 6
echo sum(...[4, 5, 6]);  // 15 (解包陣列)

5. 匿名函數 / 閉包


$multiply = function($a, $b) {
    return $a * $b;
};

echo $multiply(3, 4); // 12

// 閉包捕獲外部變數
$factor = 10;
$scale = function($n) use ($factor) {
    return $n * $factor;
};
echo $scale(5); // 50

// 箭頭函數 (PHP 7.4+)
$scale = fn($n) => $n * $factor;

二、陣列:PHP 的「瑞士刀」

建立陣列


// 短語法 (PHP 5.4+)
$indexed = ['apple', 'banana', 'cherry'];           // 索引陣列 0,1,2
$assoc = ['name' => 'Alice', 'age' => 25, 'city' => 'Taipei']; // 關聯陣列

// array() 傳統語法
$mixed = array(0 => 'first', 'key' => 'value', 2 => 'third');

// 陣列鍵特性:整數鍵自動遞增、字串鍵共存
$weird = [
    0 => '零',
    '2' => '字串鍵2',   // 注意:'2' 會被轉為整數 2!
    'key' => '值',
    10 => '十',
    11 => '十一'        // 自動遞增從最大整數鍵+1 開始
];
// $weird[2] 覆蓋 '零' 變 '字串鍵2'!
// $weird[11] = '十一' (自動遞增鍵)

關鍵鍵值轉換規則

輸入鍵實際儲存鍵說明
`0``0` (int)整數保持
`'0'``0` (int)數值字串轉整數
`'00'``'00'` (string)前導零保持字串
`'2'``2` (int)數值字串轉整數
`'key'``'key'` (string)非數值字串保持
`true``1` (int)布林轉整數
`false``0` (int)布林轉整數
`null``''` (string)Null 轉空字串
`[]`觸發 Warning,鍵為 `''`陣列不可為鍵

三、陣列核心操作 API 速查

1. 增:尾部/頭部插入


$arr = [1, 2, 3];

// 尾部插入(佇列 push)
$arr[] = 4;              // 最快、最常用
array_push($arr, 5, 6);  // 可一次推入多個,回傳新長度

// 頭部插入(堆疊 unshift)
array_unshift($arr, 0);  // [0, 1, 2, 3, 4, 5, 6],回傳新長度

2. 刪:尾部/頭部移除


// 尾部移除(堆疊 pop)
$last = array_pop($arr);  // 回傳移除的值,$arr 變短

// 頭部移除(佇列 shift)
$first = array_shift($arr); // 回傳移除的值,鍵值重新索引(整數鍵從 0 開始)

3. 查:存在性檢查與搜尋


$arr = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 2];

// 鍵存在
isset($arr['a']);           // true (最快,檢測 null 視為不存在)
array_key_exists('a', $arr); // true (檢測鍵是否存在,包含 null 值)

// 值存在
in_array(2, $arr);          // true (嚴格模式 in_array(2, $arr, true) 檢查型別)
array_search(2, $arr);      // 'b' (回傳第一個找到的鍵)
array_keys($arr, 2);        // ['b', 'd'] (回傳所有匹配的鍵)

// 取得所有鍵/值
array_keys($arr);   // ['a', 'b', 'c', 'd']
array_values($arr); // [1, 2, 3, 2] (重新索引 0,1,2,3)

4. 迭代遍歷


$arr = ['a' => 1, 'b' => 2, 'c' => 3];

// foreach (最常用、支援引用修改)
foreach ($arr as $key => &$value) {
    $value *= 2;  // 修改原陣列值
}
unset($value); // 重要:解除引用,避免後續誤用

// 內部指標操作 (罕見,特定演算法需求)
while ($key = key($arr)) {  // 取得當前鍵
    $value = current($arr); // 取得當前值
    next($arr);             // 移動指標到下一個
}
// 重置指標
reset($arr);  // 指向第一個
end($arr);    // 指向最後一個
prev($arr);   // 上一個

5. 統計資訊


$arr = [1, 2, 2, 3, 3, 3, 'a', 'a'];

count($arr);              // 8 (元素總數)
count($arr, COUNT_RECURSIVE); // 遞迴計數 (多維陣列)

array_count_values($arr); // [1=>1, 2=>2, 3=>3, 'a'=>2] (值頻率統計)

6. 去重與排序


$arr = [3, 1, 2, 2, 'a', 'A', 'a'];

// 去重 (保留第一次出現的鍵值)
$unique = array_unique($arr); // [3, 1, 2, 'a', 'A'] (注意:'a' 和 'A' 不同)

// 排序 (修改原陣列、回傳 bool)
sort($arr);           // 升序,重新索引鍵 0,1,2...
rsort($arr);          // 降序,重新索引
asort($arr);          // 升序,**保持鍵值關聯**
arsort($arr);         // 降序,保持鍵值關聯
ksort($arr);          // 按鍵升序
krsort($arr);         // 按鍵降序

// 自然排序 (人類直覺:a1, a2, a10)
$files = ['img1.png', 'img10.png', 'img2.png'];
natsort($files);      // ['img1.png', 'img2.png', 'img10.png']
natcasesort($files);  // 不分大小寫自然排序

// 自定義排序
usort($arr, function($a, $b) {
    return $a <=> $b; // 太空船運算子 (PHP 7+)
});

7. 陣列運算:合併、交集、差集、切片


$a = ['a' => 1, 'b' => 2];
$b = ['b' => 3, 'c' => 4];

// 合併 (字串鍵:後者覆蓋;整數鍵:重新索引附加)
$merged = array_merge($a, $b);        // ['a'=>1, 'b'=>3, 'c'=>4]
$mergedRec = array_merge_recursive($a, $b); // ['a'=>1, 'b'=>[2,3], 'c'=>4] (同鍵合併為陣列)

// 交集 (保留 $a 的鍵值)
$intersect = array_intersect($a, $b); // ['b' => 2] (比較值)
$intersectKey = array_intersect_key($a, $b); // ['b' => 2] (比較鍵)

// 差集 ($a 有、$b 沒有)
$diff = array_diff($a, $b);           // ['a' => 1] (比較值)
$diffKey = array_diff_key($a, $b);    // ['a' => 1] (比較鍵)

// 切片 (不修改原陣列)
$slice = array_slice($arr, 2, 3);     // 從索引 2 取 3 個元素
$slice = array_slice($arr, -3);       // 最後 3 個元素

// 隨機打亂
shuffle($arr); // 修改原陣列,重新索引鍵

// 陣列求和
$sum = array_sum([1, 2, 3.5]); // 6.5

四、進階陣列函數 (函數式風格)


$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 過濾
$evens = array_filter($numbers, fn($n) => $n % 2 === 0); // [2,4,6,8,10]

// 映射
$squares = array_map(fn($n) => $n ** 2, $numbers); // [1,4,9,16,25,36,49,64,81,100]

// 歸約
$sum = array_reduce($numbers, fn($carry, $n) => $carry + $n, 0); // 55

// 鍵值同時操作 (PHP 7.4+)
$result = array_reduce($assoc, fn($carry, $value, $key) => $carry + "$key=$value;", '');
// 注意:array_map/filter 不直接傳遞鍵,需用 array_keys 配合或 foreach

五、常見陷阱與最佳實踐

陷阱原因解決方案
陣列鍵自動轉換導致覆蓋`'2'` → `2`,與整數鍵 `2` 衝突避免混用數值字串與整數鍵;必要時用 `serialize()` 序列化鍵
`foreach` 引用殘留導致最後元素被修改`&$value` 參考未解除迴圈結束後 `unset($value)`
`in_array` 型別鬆散比較`in_array('1', [true])` 為 true嚴格模式:`in_array($needle, $haystack, true)`
`array_merge` 整數鍵重新索引預設行為需保持鍵用 `+` 運算子:`$a + $b` ($a 鍵優先)
大陣列 `count()` 在迴圈條件中重複呼叫效能浪費預先存入變數:`$len = count($arr); for($i=0;$i<$len;$i++)`

六、總結

PHP 函數與陣列是語言表達力的核心:

  • 函數:掌握參考傳遞、預設參數、可變參數、匿名函數/閉包、箭頭函數,寫出靈活可復用的邏輯單元
  • 陣列:理解「有序映射」本質、鍵值轉換規則、內部指標、豐富操作 API (`push/pop/shift/unshift`, `map/filter/reduce`, `sort/intersect/diff/slice`)
  • 避坑:嚴格比較、引用清理、鍵值衝突、效能優化

熟練運用這些工具,能讓你用最少代碼解決最複雜的資料處理問題——這正是 PHP 「快速開發」能力的來源。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved