函數是代碼復用與模組化的基本單元。PHP 支援用戶自定義函數,提供豐富的參數機制、類型聲明、可變參數等現代特性。
function 函數名(參數列表) : 返回類型 {
函數體;
return 返回值;
}
funcs.php
<?php
function jisuan(float $num1, float $num2, string $oper) : float {
switch ($oper) {
case '+': return $num1 + $num2;
case '-': return $num1 - $num2;
case '*': return $num1 * $num2;
case '/':
if ($num2 == 0) throw new Exception('除數不能為零');
return $num1 / $num2;
default:
throw new InvalidArgumentException("不支援的運算符: $oper");
}
}
?>
test.php
<?php
require 'funcs.php';
$num1 = 56; $num2 = 44; $oper = '+';
try {
$res = jisuan($num1, $num2, $oper);
echo "計算結果是:$res"; // 100
} catch (Exception $e) {
echo "錯誤:" . $e->getMessage();
}
?>
| 模式 | 語法 | 特性 | 適用場景 |
|---|---|---|---|
| 值傳遞 | function($a) | 複製副本,原值不變 | 預設,標量/陣列 |
| 引用傳遞 | function(&$a) | 操作原變量 | 需修改外部變量 |
| 預設值 | function($a = 10) | 可選參數 | 提供預設行為 |
| 類型聲明 | function(int $a) | 強制型別檢查 | PHP 7+,嚴格模式 |
| 可變參數 | function(...$args) | 接收任意數量參數 | PHP 5.6+ |
| 命名參數 | func(name: 'value') | 按名稱傳遞 | PHP 8+ |
<?php
function addPrefix(&$str, $prefix = 'Mr. ') {
$str = $prefix . $str;
}
$name = 'John';
addPrefix($name);
echo $name; // Mr. John
?>
<?php
function sum(...$numbers) {
return array_sum($numbers);
}
echo sum(1, 2, 3, 4, 5); // 15
$arr = [10, 20, 30];
echo sum(...$arr); // 60 (解包陣列)
?>
<?php
// 返回類型聲明 (PHP 7+)
function add(int $a, int $b) : int {
return $a + $b;
}
// 可空返回類型 (PHP 7.1+)
function find(int $id) : ?User {
return $user ?? null;
}
// void 返回類型 (PHP 7.1+)
function log(string $msg) : void {
error_log($msg);
}
// 生成器返回 (PHP 5.5+)
function generator() : Generator {
yield 1; yield 2; yield 3;
}
?>
| 作用域 | 範圍 | 關鍵字 |
|---|---|---|
| 區域 | 函數內部 | 預設 |
| 全域 | 腳本全域 (不含函數內) | global $var 或 $GLOBALS['var'] |
| 靜態 | 函數內部,跨調用保持值 | static $var |
| 超全域 | 所有範圍自動可用 | $GLOBALS, $_GET, $_POST 等 |
<?php
$multiply = function($a, $b) { return $a * $b; };
echo $multiply(3, 4); // 12
// 閉包綁定外部變量 (use)
$factor = 10;
$scale = function($x) use ($factor) { return $x * $factor; };
echo $scale(5); // 50
// 箭頭函數 (PHP 7.4+,自動捕獲外部變量)
$scale = fn($x) => $x * $factor;
?>
declare(strict_types=1)getUser()、calculateTotal()、isValid()函數設計質量直接決定代碼可維護性,遵循 SOLID 原則中的單一職責與介面隔離,構建清晰的抽象層次。