在處理表單提交時,isset() 和 empty() 常因處理超全域變數行為差異導致誤判。filter_has_var() 專門檢查指定輸入來源中是否存在變數,不受值內容影響,是精確驗證參數完整性的標準工具。
filter_has_var(int $type, string $variable): bool
| 常數 | 來源 |
|---|---|
| INPUT_GET | 查詢字串參數 |
| INPUT_POST | POST 表單資料 |
| INPUT_COOKIE | Cookie 值 |
| INPUT_SERVER | 伺服器變數 |
| INPUT_ENV | 環境變數 |
注意:INPUT_SESSION、INPUT_REQUEST 尚未實作。
true:變數存在於指定來源(即使值為空字串)false:變數不存在於該來源| 情境 | filter_has_var(INPUT_POST, 'x') | isset($_POST['x']) | empty($_POST['x']) |
|---|---|---|---|
| 未送欄位 | false | false | true |
| 送欄位但值為空 | true | true | true |
| 送欄位值為 "0" | true | true | true |
| 送欄位值為 "test" | true | true | false |
<?php
// API 端點:要求必須提供 user_id
if (!filter_has_var(INPUT_GET, 'user_id')) {
http_response_code(400);
echo json_encode(['error' => '缺少必要參數 user_id']);
exit;
}
$userId = filter_input(INPUT_GET, 'user_id', FILTER_VALIDATE_INT);
if ($userId === false) {
http_response_code(400);
echo json_encode(['error' => 'user_id 必須為整數']);
exit;
}
echo "處理用戶 ID:$userId";
?>
<?php
// 更新用戶資料:選填欄位
$updates = [];
// nickname:若有送才更新(即使為空字串表示清除)
if (filter_has_var(INPUT_POST, 'nickname')) {
$updates['nickname'] = filter_input(INPUT_POST, 'nickname', FILTER_SANITIZE_STRING);
}
// bio:未送則不更新
if (filter_has_var(INPUT_POST, 'bio')) {
$updates['bio'] = filter_input(INPUT_POST, 'bio', FILTER_SANITIZE_STRING);
}
// 執行更新...
?>
<?php
// $_FILES 不支援 filter_has_var,需用 isset
if (isset($_FILES['avatar']) && $_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
// 處理上傳
}
?>
<?php
class InputValidator {
private array $required = [];
private array $optional = [];
public function require(string $field, int $source = INPUT_POST): self {
$this->required[$field] = $source;
return $this;
}
public function optional(string $field, int $source = INPUT_POST): self {
$this->optional[$field] = $source;
return $this;
}
public function validate(): array {
$missing = [];
foreach ($this->required as $field => $source) {
if (!filter_has_var($source, $field)) {
$missing[] = $field;
}
}
if ($missing) {
throw new Exception("缺少必要參數:" . implode(', ', $missing));
}
return array_merge($this->required, $this->optional);
}
}
// 使用方式
$validator = new InputValidator();
$validator->require('email')->require('password')->optional('remember_me');
$fields = $validator->validate();
?>
filter_has_var 雖然簡單,但能解決「參數是否真正被送來」這個基本又關鍵的問題,是建立健壯輸入處理流程的基石。