Итоги — Валидатор форм
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 69 из 91.
Задание
ЛегкоДавайте создадим валидатор формы регистрации пользователя, который собирает ошибки валидации и сообщает о них всех сразу, а не останавливается на первой же проблеме. Именно так работает валидация форм в реальном мире — пользователи хотят видеть все проблемы со своей заявкой, а не исправлять их по одной.
Вы распределите свой код по четырем файлам:
ValidationException.php— Создайте базовый классValidationException, который расширяетException. Он будет служить родителем для всех исключений, связанных с валидацией.Exceptions.php— Подключите файл ValidationException и создайте три конкретных класса исключений, расширяющихValidationException:RequiredFieldException— Принимает имя поля в конструкторе и передает сообщение"[fieldName] is required"родителюInvalidEmailException— Принимает строку email в конструкторе и передает сообщение"'[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— ВыбрасываетRequiredFieldException, если значение равно null или пустое (после обрезки пробелов), в противном случае возвращает обрезанное значениеvalidateEmail(string $email): string— ВыбрасываетInvalidEmailException, если email невалиден (используйтеfilter_varсFILTER_VALIDATE_EMAIL), в противном случае возвращает emailvalidateMinLength(string $value, string $fieldName, int $minLength): string— ВыбрасываетMinLengthException, если длина строки меньше минимальной, в противном случае возвращает значение
main.php— Подключите файл FormValidator. Вы получите три входных значения: имя пользователя (username), email и пароль (password).Создайте экземпляр
FormValidatorи пустой массив для сбора сообщений об ошибках. Проверьте каждое поле в отдельном блоке try-catch:- Проверьте username как обязательное поле (required)
- Проверьте email сначала как обязательное поле, затем проверьте его на соответствие формату email
- Проверьте password сначала как обязательное поле, затем проверьте, что его минимальная длина составляет 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
// Перехватить ValidationException и добавить его сообщение в массив $errors
// TODO: Сначала проверить email как обязательное поле, затем проверить его на соответствие формату email
// Использовать блок try-catch и добавить любые сообщения об ошибках в массив $errors
// TODO: Сначала проверить пароль как обязательное поле, затем проверить минимальную длину в 8 символов
// Использовать блок try-catch и добавить любые сообщения об ошибках в массив $errors
// TODO: После всех проверок:
// - Если есть ошибки, вывести каждое сообщение об ошибке на отдельной строке
// - Если ошибок нет, вывести "Registration successful"
?>Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Итоги — Простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыИтоги — Иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateПодробный разбор модификаторов доступаГеттеры и сеттерыСокрытие данныхConstructor Promotion (8.0)Итоги — Система учета студентов10Продвинутые концепции ООП
Композиция против наследованияВнедрение зависимостейАнонимные классыПеречисления (PHP 8.1)Файберы (PHP 8.1)Глубокое погружение в клонирование объектовГенераторы и итераторы13Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий2Пространства имен и автозагрузка
Введение в пространства именКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerИтоги: структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс против абстрактного классаType Hinting с интерфейсамиИтоги — Калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeИтоги — Кастомная коллекция11Система типов и обработка ошибок
Объявление типовNullable-типыТипы объединения и пересеченияКлассы исключенийИерархия пользовательских исключенийTry, Catch, FinallyИтоги — Валидатор форм14Проект: Управление библиотекой
Обзор проектаКлассы Book и User3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищенные свойстваСвойства Readonly (PHP 8.1)Итоги — Менеджер банковского счета6Полиморфизм
Снова о переопределении методовПолиморфизм через интерфейсыType Hinting и Union TypesПозднее статическое связываниеИтоги — Payment Processor9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy