自 PHP 5.2 引入 Filter 擴展以來,filter_input() 和 filter_var() 成為處理用戶輸入的標準方式。它們內置了豐富的過濾器與驗證器,能以聲明式方式完成 XSS 防護、類型轉換、格式驗證等任務,大幅減少樣板代碼與安全漏洞風險。
mixed filter_input ( int $type, string $var_name [, int $filter = FILTER_DEFAULT [, mixed $options ]] )
| 常量 | 對應超全局變量 | 說明 |
|---|---|---|
| INPUT_GET | $_GET | URL 查詢參數 |
| INPUT_POST | $_POST | 表單提交數據 |
| INPUT_COOKIE | $_COOKIE | Cookie 數據 |
| INPUT_SERVER | $_SERVER | 服務器環境變量 |
| INPUT_ENV | $_ENV | 環境變量 |
<?php
// 獲取名為 "page" 的 GET 參數,驗證為整數,範圍 1-1000
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 1000]
]);
if ($page === false || $page === null) {
// 參數缺失 或 驗證失敗
$page = 1; // 默認值
}
echo "當前頁碼: $page";
?>
| 類別 | 常量前綴 | 行為 | 典型用例 |
|---|---|---|---|
| 驗證器 | FILTER_VALIDATE_* | 通過返回值,失敗返回 false | FILTER_VALIDATE_EMAIL, _INT, _URL, _BOOLEAN, _IP, _REGEXP |
| 過濾器 | FILTER_SANITIZE_* | 清理並返回處理後的字符串 | FILTER_SANITIZE_STRING, _EMAIL, _URL, _NUMBER_INT, _FULL_SPECIAL_CHARS |
<?php
// 1. 郵箱驗證
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
// 2. 整數範圍驗證
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, ['options' => ['min_range' => 18, 'max_range' => 120]]);
// 3. URL 驗證
$url = filter_input(INPUT_POST, 'website', FILTER_VALIDATE_URL);
// 4. 去除 HTML 標籤(防 XSS)
$comment = filter_input(INPUT_POST, 'comment', FILTER_SANITIZE_STRING); // PHP 8.1+ 棄用
// 推薦現代寫法:
$comment = filter_input(INPUT_POST, 'comment', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
// 5. 只保留數字字符
$phone = filter_input(INPUT_POST, 'phone', FILTER_SANITIZE_NUMBER_INT);
// 6. 布爾值轉換(注意陷阱!)
var_dump(filter_var('abc', FILTER_VALIDATE_BOOLEAN)); // false
var_dump(filter_var('0', FILTER_VALIDATE_BOOLEAN)); // false
var_dump(filter_var('1', FILTER_VALIDATE_BOOLEAN)); // true
var_dump(filter_var('on', FILTER_VALIDATE_BOOLEAN)); // true
var_dump(filter_var('yes', FILTER_VALIDATE_BOOLEAN)); // true
var_dump(filter_var('true',FILTER_VALIDATE_BOOLEAN)); // true
?>
它只認可 '1', 'true', 'on', 'yes' 為 true,其餘(包括 '0', 'false', 'off', 'no', '')均為 false。這與 JS/Python 的真值判斷不同,極易導致邏輯錯誤。建議:明確業務語義時改用自定義驗證或 FILTER_VALIDATE_REGEXP。
<?php
// 驗證中國大陸手機號
$mobile = filter_input(INPUT_POST, 'mobile', FILTER_VALIDATE_REGEXP, [
'options' => ['regexp' => '/^1[3-9]\d{9}$/']
]);
// 驗證用戶名:字母數字下劃線 4-16 位
$username = filter_input(INPUT_POST, 'username', FILTER_VALIDATE_REGEXP, [
'options' => ['regexp' => '/^[a-zA-Z0-9_]{4,16}$/']
]);
?>
filter_input(..., FILTER_SANITIZE_STRING) → 進一步 FILTER_VALIDATE_...FILTER_SANITIZE_STRING 已棄用,改用 FILTER_SANITIZE_FULL_SPECIAL_CHARS 或 htmlspecialchars()。結語:Filter 擴展是 PHP 內置的「輸入防火牆」,掌握它能讓你用極少代碼構建健壯的輸入層,將安全風險消滅在搖籃裡。