当前位置: 首页 > news >正文

PHP数据验证与净化技术全解

PHP数据验证与净化技术全解

数据验证和净化是Web开发中最基本也最重要的环节。PHP提供了很多工具来处理这个问题。今天从简单到复杂,把验证和净化技术都说一遍。

先看看filter_var函数。它是PHP内置的验证工具,可以验证邮箱、URL、IP地址等各种格式。

```php
// filter_var验证
$values = [
'email' => 'test@example.com',
'url' => 'https://www.example.com',
'ip' => '192.168.1.1',
'mac' => '00:1A:2B:3C:4D:5E',
];

echo "邮箱: " . (filter_var($values['email'], FILTER_VALIDATE_EMAIL) ?: '无效') . "\n";
echo "URL: " . (filter_var($values['url'], FILTER_VALIDATE_URL) ?: '无效') . "\n";
echo "IP: " . (filter_var($values['ip'], FILTER_VALIDATE_IP) ?: '无效') . "\n";

// 整数和浮点数验证
$intVal = filter_var('42', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 100]
]);
echo "整数(1-100): " . ($intVal !== false ? $intVal : '无效') . "\n";

$floatVal = filter_var('3.14', FILTER_VALIDATE_FLOAT);
echo "浮点数: " . ($floatVal !== false ? $floatVal : '无效') . "\n";

// 布尔值验证
$boolVal = filter_var('yes', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
echo "布尔值: " . ($boolVal !== null ? ($boolVal ? 'true' : 'false') : '无效') . "\n";
?>
```

数据净化用FILTER_SANITIZE_*系列函数:

```php
// 数据净化
$dirtyInput = [
'email' => "test@exa\tmple.com\n",
'url' => "javascript:alert('xss')",
'string' => "",
'int' => "abc123def456",
'float' => "3.14abc",
'encoding' => "UTF-8字符",
];

echo "净化邮箱: " . filter_var($dirtyInput['email'], FILTER_SANITIZE_EMAIL) . "\n";
echo "净化URL: " . filter_var($dirtyInput['url'], FILTER_SANITIZE_URL) . "\n";
echo "净化字符串: " . filter_var($dirtyInput['string'], FILTER_SANITIZE_STRING) . "\n";
echo "净化整数: " . filter_var($dirtyInput['int'], FILTER_SANITIZE_NUMBER_INT) . "\n";
echo "净化浮点: " . filter_var($dirtyInput['float'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) . "\n";
echo "净化编码: " . filter_var($dirtyInput['encoding'], FILTER_SANITIZE_ENCODED) . "\n";
?>
```

完整的表单验证系统:

```php
class Validator
{
private array $data;
private array $rules;
private array $errors = [];
private array $validated = [];

public function __construct(array $data, array $rules)
{
$this->data = $data;
$this->rules = $rules;
$this->validate();
}

public function fails(): bool
{
return !empty($this->errors);
}

public function errors(): array
{
return $this->errors;
}

public function validated(): array
{
return $this->validated;
}

private function validate(): void
{
foreach ($this->rules as $field => $ruleSet) {
$value = $this->data[$field] ?? null;
$rules = is_string($ruleSet) ? explode('|', $ruleSet) : $ruleSet;

foreach ($rules as $rule) {
$this->applyRule($field, $value, $rule);
}

if (!isset($this->errors[$field])) {
$this->validated[$field] = $value;
}
}
}

private function applyRule(string $field, mixed $value, string $rule): void
{
$params = [];
if (str_contains($rule, ':')) {
[$rule, $paramStr] = explode(':', $rule, 2);
$params = explode(',', $paramStr);
}

$methodName = 'rule' . ucfirst($rule);
if (method_exists($this, $methodName)) {
$this->$methodName($field, $value, $params);
}
}

private function ruleRequired(string $field, mixed $value, array $params): void
{
if ($value === null || $value === '' || (is_array($value) && empty($value))) {
$this->addError($field, "{$field}不能为空");
}
}

private function ruleEmail(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
$this->addError($field, "{$field}格式不正确");
}
}

private function ruleMin(string $field, mixed $value, array $params): void
{
$min = (int)($params[0] ?? 0);
if (is_string($value) && mb_strlen($value) < $min) {
$this->addError($field, "{$field}至少{$min}个字符");
}
if (is_numeric($value) && $value < $min) {
$this->addError($field, "{$field}不能小于{$min}");
}
}

private function ruleMax(string $field, mixed $value, array $params): void
{
$max = (int)($params[0] ?? 0);
if (is_string($value) && mb_strlen($value) > $max) {
$this->addError($field, "{$field}不能超过{$max}个字符");
}
if (is_numeric($value) && $value > $max) {
$this->addError($field, "{$field}不能大于{$max}");
}
}

private function ruleNumeric(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !is_numeric($value)) {
$this->addError($field, "{$field}必须是数字");
}
}

private function ruleUrl(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !filter_var($value, FILTER_VALIDATE_URL)) {
$this->addError($field, "{$field}不是有效的URL");
}
}

private function ruleIn(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !in_array((string)$value, $params)) {
$this->addError($field, "{$field}必须是: " . implode(', ', $params));
}
}

private function ruleInteger(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !filter_var($value, FILTER_VALIDATE_INT)) {
$this->addError($field, "{$field}必须是整数");
}
}

private function ruleBoolean(string $field, mixed $value, array $params): void
{
if ($value !== null && !is_bool($value) && !in_array($value, ['0', '1', 0, 1, 'true', 'false'], true)) {
$this->addError($field, "{$field}必须是布尔值");
}
}

private function ruleDate(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '') {
$format = $params[0] ?? 'Y-m-d';
$date = \DateTime::createFromFormat($format, $value);
if (!$date || $date->format($format) !== $value) {
$this->addError($field, "{$field}不是有效的日期格式");
}
}
}

private function addError(string $field, string $message): void
{
if (!isset($this->errors[$field])) {
$this->errors[$field] = $message;
}
}
}

// 使用验证器
$data = [
'name' => '张三',
'email' => 'invalid-email',
'age' => 200,
'gender' => 'unknown',
'website' => 'not-a-url',
];

$rules = [
'name' => 'required|min:2|max:50',
'email' => 'required|email',
'age' => 'required|numeric|min:1|max:150',
'gender' => 'required|in:male,female,other',
'website' => 'url',
];

$validator = new Validator($data, $rules);

if ($validator->fails()) {
echo "验证失败:\n";
foreach ($validator->errors() as $field => $error) {
echo " - $error\n";
}
} else {
echo "验证通过\n";
print_r($validator->validated());
}
?>
```

数据验证和净化是Web开发的安全基石。永远不要信任用户输入,对所有外部数据进行验证和净化。验证确保数据格式正确,净化去除不安全的内容。两者结合使用,才能构建安全的应用。

http://www.cnnetsun.cn/news/2726569.html

相关文章:

  • 东亚地形高程数据包(ArcGIS/MapGIS即用型ESRI Grid格式)
  • 深度解析分布式流媒体播放器架构设计与性能优化指南:mpegts.js 5大架构优势
  • 终极指南:4步使用OpenCore Legacy Patcher让旧Mac重获新生
  • 用Pygame给游戏‘嗷大喵快跑’加个功能:如何实现关卡存档和最高分记录?
  • PhotoGIMP:重塑开源图像编辑的认知边界
  • 【Redis】主从复制Day9
  • AMD Ryzen处理器调优新选择:SMUDebugTool让你的电脑更懂你
  • Hy-MT2-1.8B高级指令使用指南:6种专业翻译模式详解
  • Calme-4x7B-MoE-v0.2多语言能力测试:英法俄三语任务表现深度分析
  • Wand-Enhancer终极指南:3步免费解锁完整游戏修改体验
  • QueryExcel:批量Excel文件查询的终极免费工具,一分钟完成全天工作
  • 抖音下载神器:3分钟掌握无水印批量下载终极指南
  • SXSWedu教育科技盛会:跨界创新、AI与VR应用及实践指南
  • 三步实现闲鱼数据可视化采集:基于uiautomator2的智能爬虫实战
  • Java 程序员第 41 阶段04:企业智能问答机器人落地,搭建内部智能客服系统,FAQ问答与精确检索
  • 数字记忆的时光胶囊:GetQzonehistory如何重塑你的青春档案馆
  • 上海APP开发哪家靠谱?2026硬核推荐排行
  • 陈刚直言 | 工业 AI 做不成产品,不在 AI,而在泛化能力
  • VC++医学影像三维重建工程包:含双视角配准、MC表面重建、OpenGL体绘制与BMP图像加载调试环境
  • 手柄映射工具完全指南:用AntiMicroX解决PC游戏控制器适配难题
  • AI职业影响研究:从任务适用性到人机协同的实践路径
  • 免费开源AMD Ryzen调试工具:零基础掌控硬件性能的完整指南
  • FPGA实战:用Modelsim仿真验证你的分频电路(从Testbench编写到波形分析全流程)
  • 智能仓储物流通讯故障实战手册:5类现场总线故障排查与保养
  • MinIO 站点复制部署与测试:同步与故障恢复
  • 终极指南:如何用茉莉花插件彻底解决Zotero中文文献识别难题
  • 别再只盯着读数了!手把手教你读懂光功率计探头的‘内心戏’(光电二极管 vs 热敏探头)
  • B站视频转文字终极指南:三步将任何视频变成可编辑文本
  • React基础
  • 告别拖拽式布局:用SceneBuilder + FXML重构你的JavaFX项目(附完整配置流程)