PHP 本質是弱型別語言,變數無需宣告型別且可隨時改變。但自 PHP 5/7 起,引入參數型別宣告與回傳值型別宣告,讓開發者能在關鍵介面處建立契約,提升程式碼可靠度與 IDE 支援。
| 型別分類 | 關鍵字 | 說明 | 支援版本 |
|---|---|---|---|
| 類別/介面 | ClassName / InterfaceName | 物件必須是該類別實例或實作該介面 | PHP 5.0+ |
| 陣列 | array | 必須為陣列 | PHP 5.1+ |
| 可呼叫物件 | callable | 函數、閉包、類別方法陣列等 | PHP 5.4+ |
| 標量型別 | int, float, bool, string | 基礎資料型別 | PHP 7.0+ |
| 可為 null | ?Type | 允許傳入 null | PHP 7.1+ |
| void 回傳 | void | 不回傳任何值 | PHP 7.1+ |
| never 回傳 | never | 函數不會正常返回(拋出例外/exit) | PHP 8.1+ |
| 混合型別 | mixed | 任意型別 | PHP 8.0+ |
| 聯合型別 | Type1|Type2 | 多種型別其中之一 | PHP 8.0+ |
| 交集型別 | Type1&Type2 | 同時滿足多個介面 | PHP 8.1+ |
// 參數型別宣告
function process(User $user, array $options, callable $callback) { /* ... */ }
// 回傳值型別宣告
function getUser(int $id): ?User {
// 回傳 User 物件或 null
}
function calculate(float $a, float $b): float {
return $a + $b;
}
// 嚴格模式(檔案最頂端宣告)
declare(strict_types=1);
function add(int $a, int $b): int {
return $a + $b;
}
add(1, 2); // 正常
add('1', '2'); // TypeError: 嚴格模式下字串不可自動轉換
| 模式 | 行為 | 適用場景 |
|---|---|---|
| 強制模式 (預設) | 允許相容型別自動轉換(如 int → float、數字字串 → int) | 一般應用、漸進式導入型別宣告 |
| 嚴格模式 (strict_types=1) | 型別必須完全匹配,否則拋出 TypeError | 核心庫、高可靠度要求、團隊規範 |
重要:declare(strict_types=1) 僅影響該檔案內的函數呼叫,不影響被呼叫函數的定義檔案。這設計讓庫作者與使用者能各自選擇模式。
composer.json 或專案規範要求所有檔案加上 declare(strict_types=1)?User 比 User|null 更簡潔(PHP 7.1+)string|Stringable 替代介面繼承interface Repository {
public function find(int $id): ?Entity;
}
class UserRepository implements Repository {
// 參數可擴大:int → int|string
// 回傳可縮小:?Entity → ?User
public function find(int|string $id): ?User { /* ... */ }
}