Menu
CoddyTech

回顾:表单验证器

本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 69 课,共 91 课。

challenge icon

挑战

简单

我们来构建一个用户注册表单验证器,用来收集验证错误并一次性报告所有错误,而不是遇到第一个问题就停止。这就是现实中的表单验证方式:用户希望看到提交内容中的所有问题,而不是一次只修复一个问题。

你将把代码组织在 4 个文件中:

  • ValidationException.php:创建一个继承自 Exception 的基础 ValidationException 类。它将作为所有与验证相关的异常的父类。
  • Exceptions.php:引入 ValidationException 文件,并创建 3 个继承自 ValidationException 的特定异常类:
    • RequiredFieldException:在构造函数中接收字段名,并将消息 "[fieldName] is required" 传给父类
    • InvalidEmailException:在构造函数中接收电子邮件字符串,并将消息 "'[email]' is not a valid email" 传给父类
    • MinLengthException:在构造函数中接收字段名和最小长度(int),并将消息 "[fieldName] must be at least [minLength] characters" 传给父类
  • FormValidator.php:引入 Exceptions 文件,并创建一个 FormValidator 类,包含以下验证方法:
    • validateRequired(?string $value, string $fieldName): string:如果值为 null 或为空(去除首尾空白后),则抛出 RequiredFieldException;否则返回去除首尾空白后的值
    • validateEmail(string $email): string:如果电子邮件无效,则抛出 InvalidEmailException(使用 filter_var 和 FILTER_VALIDATE_EMAIL);否则返回该电子邮件
    • validateMinLength(string $value, string $fieldName, int $minLength): string:如果字符串长度小于最小长度,则抛出 MinLengthException;否则返回该值
  • main.php:引入 FormValidator 文件。你将收到 3 个输入:用户名、电子邮件和密码。

    创建一个 FormValidator 和一个空数组,用来收集错误消息。分别在单独的 try-catch 块中验证每个字段:

    • 验证用户名为必填项
    • 先验证电子邮件为必填项,再验证其格式是否有效
    • 先验证密码为必填项,再验证其长度是否至少为 8 个字符

    捕获 ValidationException 时,将其中的消息添加到错误数组中,而不是停止执行。

    完成所有验证后,如果存在错误,就将每条错误消息单独打印在一行上。如果没有错误,就打印 "Registration successful"。

在报告错误之前先收集所有错误,是提升用户体验的关键。这种异常层级结构让你可以轻松地通过一个 catch 块捕获所有验证问题,同时仍能为不同的验证失败使用特定的异常类型。

亲手试试

<?php
require_once 'FormValidator.php';

// 读取输入
$username = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$password = trim(fgets(STDIN));

// 创建一个 FormValidator 实例
$validator = new FormValidator();

// 创建一个空数组,用来收集错误消息
$errors = [];

// TODO: 在 try-catch 块中验证 username 为必填项
// 捕获 ValidationException,并将其消息添加到 $errors 数组

// TODO: 先验证 email 为必填项,再验证其格式是否为有效的电子邮件地址
// 使用 try-catch 块,并将所有错误消息添加到 $errors 数组

// TODO: 先验证 password 为必填项,再验证其长度至少为 8 个字符
// 使用 try-catch 块,并将所有错误消息添加到 $errors 数组

// TODO: 完成所有验证后:
// - 如果有错误,将每条错误消息分别打印在一行
// - 如果没有错误,打印 "Registration successful"

?>

面向对象编程中的所有课

自己练习: PHP 在线编译器