表單/ API 參數驗證是 Web 開發高頻需求。本文提供一個輕量、可擴展的 Validator 類,支援規則鏈、多字段批量驗證、錯誤信息收集,新增規則只需在類中添加方法即可。
class Validator {
private $_data = [];
private $_ruleList = [];
private $_resultInfo = [];
public function __construct(array $data = []) {
$this->_data = $data;
}
public function setRule(string $field, $rule): void {
$this->_ruleList[$field] = $rule;
}
public function validate(array $data = null): bool {
if ($data) $this->_data = $data;
$this->_resultInfo = [];
$ok = true;
foreach ($this->_ruleList as $field => $rules) {
$ruleSet = is_array($rules) ? $rules : [$rules];
foreach ($ruleSet as $ruleName => $params) {
$method = is_int($ruleName) ? $params : $ruleName;
$args = is_int($ruleName) ? [] : (array)$params;
if (!method_exists($this, $method)) continue;
$pass = $this->$method($field, ...$args);
if (!$pass) {
$this->_resultInfo[$field][$method] = false;
$ok = false;
}
}
}
return $ok;
}
public function getResultInfo(): array {
return $this->_resultInfo;
}
// 內置規則方法 -------------------------------------------------
public function required(string $field): bool {
return isset($this->_data[$field]) && $this->_data[$field] !== '';
}
public function length(string $field, int $min, int $max): bool {
if (!$this->required($field)) return true; // 非必填為空視為通過
$len = mb_strlen($this->_data[$field]);
return $len >= $min && $len <= $max;
}
public function email(string $field): bool {
if (!$this->required($field)) return true;
return (bool)preg_match('/^[-\w.]+@[-\w.]+\.[a-z]{2,}$/i', $this->_data[$field]);
}
public function mobile(string $field): bool {
if (!$this->required($field)) return true;
return (bool)preg_match('/^1[3-9]\d{9}$/', $this->_data[$field]);
}
public function digit(string $field): bool {
return $this->required($field) && is_numeric($this->_data[$field]);
}
public function url(string $field): bool {
if (!$this->required($field)) return true;
return (bool)preg_match('#^https?://[\w.-]+\.[a-z]{2,}(/.*)?$#i', $this->_data[$field]);
}
// 可繼續添加 id_card、ip、date、regex 等規則
}
$data = [
'nickname' => 'heno',
'realname' => 'steven',
'age' => 25,
'mobile' => '1521060426',
];
$v = new Validator($data);
$v->setRule('nickname', 'required');
$v->setRule('realname', ['length' => [1,6], 'required']);
$v->setRule('age', ['required', 'digit']);
$v->setRule('mobile', ['mobile']);
if ($v->validate()) {
echo "驗證通過";
} else {
print_r($v->getResultInfo());
/* 輸出示例
Array
(
[realname] => Array ( [length] => )
[mobile] => Array ( [mobile] => )
)
*/
}
Validator,添加 protected function myRule($field, $param)。public function customRule(...),規則名即方法名。true 通過,false 失敗。setRule('field', ['customRule' => [$arg1, $arg2]])。filter_var() 內置過濾器(FILTER_VALIDATE_EMAIL 等)提高可靠性。_resultInfo 存儲錯誤碼,視圖層映射語言包。symfony/validator、laravel/validation 等成熟組件,支援異步驗證、嵌套對象、條件規則。