filter_input_validate() 不是PHP内置函数,而是本教程提供的自定义验证函数,用于增强PHP的输入验证功能。
filter_input_validate() 是一个自定义的高级输入验证函数,它扩展了PHP内置的 filter_input() 函数,提供了更丰富的验证规则和错误处理机制。
该函数提供了以下增强功能:
<?php
/**
* 高级输入验证函数
*
* @param int $type 输入类型 (INPUT_GET, INPUT_POST, INPUT_COOKIE, etc.)
* @param string $field 字段名
* @param mixed $rules 验证规则(字符串或数组)
* @param mixed $default 验证失败时的默认值
* @return array 包含验证结果和信息的数组
*/
function filter_input_validate($type, $field, $rules, $default = null) {
// 获取原始值
$value = filter_input($type, $field);
// 如果字段不存在,使用默认值
if ($value === null) {
$value = $default;
}
// 如果值为null且没有默认值,返回验证失败
if ($value === null) {
return [
'valid' => false,
'value' => null,
'error' => '字段不存在',
'field' => $field
];
}
// 将规则字符串转换为数组
if (is_string($rules)) {
$rules = explode('|', $rules);
}
$errors = [];
$validatedValue = $value;
// 应用每个验证规则
foreach ($rules as $rule) {
$ruleParts = explode(':', $rule, 2);
$ruleName = $ruleParts[0];
$ruleParam = isset($ruleParts[1]) ? $ruleParts[1] : null;
switch ($ruleName) {
case 'required':
if (empty(trim($validatedValue))) {
$errors[] = '字段是必填的';
}
break;
case 'email':
if (!filter_var($validatedValue, FILTER_VALIDATE_EMAIL)) {
$errors[] = '邮箱格式无效';
}
break;
case 'url':
if (!filter_var($validatedValue, FILTER_VALIDATE_URL)) {
$errors[] = 'URL格式无效';
}
break;
case 'int':
$options = [];
if ($ruleParam) {
$range = explode(',', $ruleParam);
if (count($range) >= 2) {
$options['options'] = [
'min_range' => (int)$range[0],
'max_range' => (int)$range[1]
];
}
}
$filtered = filter_var($validatedValue, FILTER_VALIDATE_INT, $options);
if ($filtered === false) {
$errors[] = $ruleParam ? "整数必须在{$range[0]}-{$range[1]}之间" : '必须是有效的整数';
} else {
$validatedValue = $filtered;
}
break;
case 'float':
$filtered = filter_var($validatedValue, FILTER_VALIDATE_FLOAT);
if ($filtered === false) {
$errors[] = '必须是有效的浮点数';
} else {
$validatedValue = $filtered;
}
break;
case 'boolean':
$filtered = filter_var($validatedValue, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
if ($filtered === null) {
$errors[] = '必须是有效的布尔值';
} else {
$validatedValue = $filtered;
}
break;
case 'ip':
$filtered = filter_var($validatedValue, FILTER_VALIDATE_IP);
if ($filtered === false) {
$errors[] = '必须是有效的IP地址';
} else {
$validatedValue = $filtered;
}
break;
case 'min':
if (strlen($validatedValue) < (int)$ruleParam) {
$errors[] = "长度不能少于{$ruleParam}个字符";
}
break;
case 'max':
if (strlen($validatedValue) > (int)$ruleParam) {
$errors[] = "长度不能超过{$ruleParam}个字符";
}
break;
case 'regex':
if (!preg_match($ruleParam, $validatedValue)) {
$errors[] = '格式不符合要求';
}
break;
case 'alpha':
if (!ctype_alpha(str_replace(' ', '', $validatedValue))) {
$errors[] = '只能包含字母';
}
break;
case 'alnum':
if (!ctype_alnum(str_replace(' ', '', $validatedValue))) {
$errors[] = '只能包含字母和数字';
}
break;
case 'numeric':
if (!is_numeric($validatedValue)) {
$errors[] = '必须是数字';
}
break;
case 'date':
if (!strtotime($validatedValue)) {
$errors[] = '必须是有效的日期';
}
break;
case 'in':
$allowed = explode(',', $ruleParam);
if (!in_array($validatedValue, $allowed)) {
$errors[] = "值必须是: " . implode(', ', $allowed);
}
break;
case 'not_in':
$disallowed = explode(',', $ruleParam);
if (in_array($validatedValue, $disallowed)) {
$errors[] = "值不能是: " . implode(', ', $disallowed);
}
break;
case 'same':
$otherValue = filter_input($type, $ruleParam);
if ($validatedValue !== $otherValue) {
$errors[] = "必须与{$ruleParam}字段相同";
}
break;
case 'different':
$otherValue = filter_input($type, $ruleParam);
if ($validatedValue === $otherValue) {
$errors[] = "必须与{$ruleParam}字段不同";
}
break;
case 'callback':
if (is_callable($ruleParam) && !call_user_func($ruleParam, $validatedValue)) {
$errors[] = '自定义验证失败';
}
break;
default:
// 默认使用内置过滤器
$filterId = filter_id($ruleName);
if ($filterId !== false) {
$filtered = filter_var($validatedValue, $filterId);
if ($filtered === false) {
$errors[] = "{$ruleName}验证失败";
} else {
$validatedValue = $filtered;
}
}
break;
}
// 如果已经有错误,停止后续验证
if (!empty($errors)) {
break;
}
}
// 返回验证结果
return [
'valid' => empty($errors),
'value' => $validatedValue,
'error' => empty($errors) ? null : implode('; ', $errors),
'field' => $field,
'errors' => $errors
];
}
?>
| 参数 | 描述 |
|---|---|
$type |
输入类型。与 filter_input() 相同:
|
$field |
字段名。要验证的字段名称 |
$rules |
验证规则。可以是字符串或数组:
|
$default |
默认值(可选)。如果字段不存在,使用此默认值 |
| 规则 | 格式 | 描述 | 示例 |
|---|---|---|---|
required |
- | 字段必须存在且不为空 | required |
email |
- | 必须是有效的邮箱地址 | email |
url |
- | 必须是有效的URL | url |
int |
int:min,max |
必须是整数(可指定范围) | int:1,100 |
float |
- | 必须是浮点数 | float |
boolean |
- | 必须是布尔值 | boolean |
ip |
- | 必须是有效的IP地址 | ip |
min |
min:length |
最小长度限制 | min:3 |
max |
max:length |
最大长度限制 | max:100 |
regex |
regex:pattern |
必须匹配正则表达式 | regex:/^[a-z]+$/ |
alpha |
- | 只能包含字母 | alpha |
alnum |
- | 只能包含字母和数字 | alnum |
numeric |
- | 必须是数字 | numeric |
date |
- | 必须是有效的日期 | date |
in |
in:value1,value2 |
必须在指定值列表中 | in:admin,user,guest |
not_in |
not_in:value1,value2 |
不能在指定值列表中 | not_in:admin,root |
same |
same:field_name |
必须与另一个字段值相同 | same:password_confirmation |
different |
different:field_name |
必须与另一个字段值不同 | different:old_password |
callback |
callback:function_name |
使用自定义函数验证 | callback:my_validation_function |
函数返回一个包含以下键的关联数组:
[
'valid' => true, // 布尔值:验证是否通过
'value' => mixed, // 验证后的值(已转换类型)
'error' => null, // 字符串:错误信息(验证失败时)
'field' => string, // 字段名
'errors' => array // 详细的错误数组
]
<?php
// 包含上面的自定义函数定义
require_once 'filter_input_validate.php';
// 模拟POST数据
$_POST = [
'name' => 'John Doe',
'email' => 'john@example.com',
'age' => '25',
'website' => 'https://example.com'
];
// 验证单个字段
$nameResult = filter_input_validate(INPUT_POST, 'name', 'required|alpha|min:2|max:50');
$emailResult = filter_input_validate(INPUT_POST, 'email', 'required|email');
$ageResult = filter_input_validate(INPUT_POST, 'age', 'required|int:18,100');
$websiteResult = filter_input_validate(INPUT_POST, 'website', 'url');
// 显示验证结果
echo "<h4>验证结果:</h4>";
echo "<table class='table table-bordered'>";
echo "<tr><th>字段</th><th>值</th><th>状态</th><th>错误信息</th></tr>";
$results = [$nameResult, $emailResult, $ageResult, $websiteResult];
foreach ($results as $result) {
$status = $result['valid'] ? '<span class="badge bg-success">通过</span>' :
'<span class="badge bg-danger">失败</span>';
$error = $result['error'] ?? '无';
echo "<tr>";
echo "<td>{$result['field']}</td>";
echo "<td>" . htmlspecialchars($result['value']) . "</td>";
echo "<td>$status</td>";
echo "<td>" . htmlspecialchars($error) . "</td>";
echo "</tr>";
}
echo "</table>";
?>
<?php
// 用户注册表单处理
function validateRegistrationForm() {
// 定义验证规则
$rules = [
'username' => 'required|alnum|min:3|max:20',
'email' => 'required|email',
'password' => 'required|min:8|regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/',
'confirm_password' => 'required|same:password',
'age' => 'required|int:18,120',
'gender' => 'in:male,female,other',
'terms' => 'required|boolean',
'newsletter' => 'boolean'
];
$errors = [];
$validData = [];
// 验证每个字段
foreach ($rules as $field => $fieldRules) {
$result = filter_input_validate(INPUT_POST, $field, $fieldRules);
if (!$result['valid']) {
$errors[$field] = $result['error'];
} else {
$validData[$field] = $result['value'];
}
}
// 返回验证结果
if (empty($errors)) {
return [
'success' => true,
'message' => '验证成功',
'data' => $validData
];
} else {
return [
'success' => false,
'message' => '验证失败',
'errors' => $errors,
'data' => $validData
];
}
}
// 模拟表单提交
$_POST = [
'username' => 'john_doe123',
'email' => 'john.doe@example.com',
'password' => 'Password123',
'confirm_password' => 'Password123',
'age' => '25',
'gender' => 'male',
'terms' => 'on',
'newsletter' => '1'
];
// 执行验证
$result = validateRegistrationForm();
// 显示结果
echo "<div class='" . ($result['success'] ? 'alert alert-success' : 'alert alert-danger') . "'>";
echo "<h4>{$result['message']}</h4>";
if (!$result['success']) {
echo "<ul>";
foreach ($result['errors'] as $field => $error) {
echo "<li><strong>$field</strong>: $error</li>";
}
echo "</ul>";
} else {
echo "<pre>" . print_r($result['data'], true) . "</pre>";
}
echo "</div>";
?>
<?php
/**
* 批量验证多个字段
*/
function filter_input_validate_batch($type, $fields) {
$results = [];
$allValid = true;
foreach ($fields as $field => $config) {
$rules = $config['rules'] ?? '';
$default = $config['default'] ?? null;
$result = filter_input_validate($type, $field, $rules, $default);
$results[$field] = $result;
if (!$result['valid']) {
$allValid = false;
}
}
return [
'valid' => $allValid,
'results' => $results
];
}
// 使用批量验证
$validationConfig = [
'username' => [
'rules' => 'required|alnum|min:3|max:20',
'default' => 'guest'
],
'email' => [
'rules' => 'required|email'
],
'age' => [
'rules' => 'int:0,150'
],
'score' => [
'rules' => 'float'
],
'ip_address' => [
'rules' => 'ip'
]
];
// 模拟GET数据
$_GET = [
'username' => 'test_user',
'email' => 'test@example.com',
'age' => '30',
'score' => '95.5',
'ip_address' => '192.168.1.1'
];
// 执行批量验证
$batchResult = filter_input_validate_batch(INPUT_GET, $validationConfig);
echo "<h4>批量验证结果:</h4>";
echo "<div class='" . ($batchResult['valid'] ? 'alert alert-success' : 'alert alert-danger') . "'>";
echo "总体验证状态: " . ($batchResult['valid'] ? '通过' : '失败');
echo "</div>";
echo "<table class='table table-bordered'>";
echo "<thead><tr><th>字段</th><th>值</th><th>规则</th><th>状态</th><th>错误</th></tr></thead>";
echo "<tbody>";
foreach ($batchResult['results'] as $field => $result) {
$status = $result['valid'] ? '<span class="badge bg-success">✓</span>' :
'<span class="badge bg-danger">✗</span>';
$error = $result['error'] ?? '无';
$rules = $validationConfig[$field]['rules'] ?? '无';
echo "<tr>";
echo "<td>$field</td>";
echo "<td>" . htmlspecialchars($result['value']) . "</td>";
echo "<td>$rules</td>";
echo "<td>$status</td>";
echo "<td>" . htmlspecialchars($error) . "</td>";
echo "</tr>";
}
echo "</tbody></table>";
?>
<?php
// 自定义验证函数
function validate_phone_number($value) {
// 验证电话号码格式
return preg_match('/^\+?[0-9]{10,15}$/', $value);
}
function validate_strong_password($value) {
// 验证强密码:至少8位,包含大小写字母和数字
if (strlen($value) < 8) return false;
if (!preg_match('/[A-Z]/', $value)) return false;
if (!preg_match('/[a-z]/', $value)) return false;
if (!preg_match('/[0-9]/', $value)) return false;
return true;
}
// 使用自定义回调验证
$_POST = [
'phone' => '+1234567890',
'password' => 'MyP@ssw0rd123',
'custom_field' => 'special_value'
];
// 验证电话号码
$phoneResult = filter_input_validate(INPUT_POST, 'phone',
'required|callback:validate_phone_number');
// 验证密码强度
$passwordResult = filter_input_validate(INPUT_POST, 'password',
'required|callback:validate_strong_password');
// 使用匿名函数验证
$customResult = filter_input_validate(INPUT_POST, 'custom_field',
'callback:function($v){ return $v === "special_value"; }');
echo "<h4>自定义规则验证:</h4>";
$results = [$phoneResult, $passwordResult, $customResult];
foreach ($results as $result) {
echo "<div class='mb-2 p-2 " . ($result['valid'] ? 'bg-success' : 'bg-danger') . "'>";
echo "字段: {$result['field']}<br>";
echo "值: " . htmlspecialchars($result['value']) . "<br>";
echo "状态: " . ($result['valid'] ? '通过' : '失败') . "<br>";
if (!$result['valid']) {
echo "错误: " . htmlspecialchars($result['error']) . "<br>";
}
echo "</div>";
}
?>
<?php
// 模拟GET数据
$_GET = [
'id' => '123',
'email' => 'test@example.com',
'page' => 'invalid'
];
echo "<h4>原生filter_input():</h4>";
// 使用原生函数
$id1 = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
$email1 = filter_input(INPUT_GET, 'email', FILTER_VALIDATE_EMAIL);
$page1 = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
echo "ID: " . ($id1 !== false && $id1 !== null ? $id1 : '无效') . "<br>";
echo "Email: " . ($email1 !== false && $email1 !== null ? $email1 : '无效') . "<br>";
echo "Page: " . ($page1 !== false && $page1 !== null ? $page1 : '无效') . "<br>";
echo "<hr><h4>自定义filter_input_validate():</h4>";
// 使用自定义函数
$id2 = filter_input_validate(INPUT_GET, 'id', 'required|int:1,999');
$email2 = filter_input_validate(INPUT_GET, 'email', 'required|email');
$page2 = filter_input_validate(INPUT_GET, 'page', 'int:1,100', 1);
echo "ID: " . ($id2['valid'] ? $id2['value'] : '无效 - ' . $id2['error']) . "<br>";
echo "Email: " . ($email2['valid'] ? $email2['value'] : '无效 - ' . $email2['error']) . "<br>";
echo "Page: " . ($page2['valid'] ? $page2['value'] : '默认值: ' . $page2['value']) . "<br>";
echo "<hr><h4>优势对比:</h4>";
echo "<ul>";
echo "<li>原生函数返回简单值,自定义函数返回详细结果数组</li>";
echo "<li>自定义函数支持更丰富的验证规则</li>";
echo "<li>自定义函数提供更好的错误信息</li>";
echo "<li>自定义函数支持默认值设置</li>";
echo "<li>自定义函数支持批量验证</li>";
echo "</ul>";
?>
<?php
/**
* 扩展的验证类
*/
class AdvancedValidator {
private static $customRules = [];
/**
* 添加自定义验证规则
*/
public static function addRule($name, $callback) {
self::$customRules[$name] = $callback;
}
/**
* 增强的验证函数
*/
public static function validate($type, $field, $rules, $default = null) {
$result = filter_input_validate($type, $field, $rules, $default);
// 处理自定义规则
if (!$result['valid']) {
foreach (self::$customRules as $ruleName => $callback) {
if (strpos($rules, $ruleName) !== false) {
if (call_user_func($callback, $result['value'])) {
// 自定义规则通过,修正验证结果
$result['valid'] = true;
$result['error'] = null;
$result['errors'] = [];
break;
}
}
}
}
return $result;
}
/**
* 验证整个表单
*/
public static function validateForm($type, $rulesMap) {
$results = [];
$isValid = true;
foreach ($rulesMap as $field => $rules) {
$result = self::validate($type, $field, $rules);
$results[$field] = $result;
if (!$result['valid']) {
$isValid = false;
}
}
return [
'valid' => $isValid,
'results' => $results
];
}
}
// 使用扩展验证类
AdvancedValidator::addRule('phone', 'validate_phone_number');
AdvancedValidator::addRule('strong_password', 'validate_strong_password');
$_POST = [
'phone' => '+12345678901',
'password' => 'StrongPass123'
];
$result = AdvancedValidator::validateForm(INPUT_POST, [
'phone' => 'required|phone',
'password' => 'required|strong_password|min:8'
]);
echo "<h4>扩展验证类结果:</h4>";
echo "<pre>" . print_r($result, true) . "</pre>";
?>
该函数是 PHP 后端函数,与浏览器无关。需要 PHP 5.6 或更高版本。