Recap - Form Validator
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 69 of 91.
Challenge
EasyLet's build a user registration form validator that collects validation errors and reports them all at once, rather than stopping at the first problem. This is how real-world form validation works — users want to see all issues with their submission, not fix them one at a time.
You'll organize your code across four files:
ValidationException.php— Create a baseValidationExceptionclass that extendsException. This serves as the parent for all validation-related exceptions.Exceptions.php— Include the ValidationException file and create three specific exception classes that extendValidationException:RequiredFieldException— Accepts a field name in its constructor and passes the message"[fieldName] is required"to the parentInvalidEmailException— Accepts an email string in its constructor and passes the message"'[email]' is not a valid email"to the parentMinLengthException— Accepts a field name and a minimum length (int) in its constructor and passes the message"[fieldName] must be at least [minLength] characters"to the parent
FormValidator.php— Include the Exceptions file and create aFormValidatorclass with these validation methods:validateRequired(?string $value, string $fieldName): string— ThrowsRequiredFieldExceptionif the value is null or empty (after trimming), otherwise returns the trimmed valuevalidateEmail(string $email): string— ThrowsInvalidEmailExceptionif the email is invalid (usefilter_varwithFILTER_VALIDATE_EMAIL), otherwise returns the emailvalidateMinLength(string $value, string $fieldName, int $minLength): string— ThrowsMinLengthExceptionif the string length is less than the minimum, otherwise returns the value
main.php— Include the FormValidator file. You'll receive three inputs: a username, an email, and a password.Create a
FormValidatorand an empty array to collect error messages. Validate each field in a separate try-catch block:- Validate username as required
- Validate email as required first, then validate it as a valid email format
- Validate password as required first, then validate it has a minimum length of 8 characters
When catching a
ValidationException, add its message to your errors array instead of stopping execution.After all validations, if there are errors, print each error message on its own line. If there are no errors, print
"Registration successful".
This pattern of collecting all errors before reporting them is essential for good user experience. Your exception hierarchy makes it easy to catch all validation problems with a single catch block while still having specific exception types for different validation failures.
Try it yourself
<?php
require_once 'FormValidator.php';
// Read inputs
$username = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$password = trim(fgets(STDIN));
// Create a FormValidator instance
$validator = new FormValidator();
// Create an empty array to collect error messages
$errors = [];
// TODO: Validate username as required in a try-catch block
// Catch ValidationException and add its message to $errors array
// TODO: Validate email as required first, then validate it as a valid email format
// Use a try-catch block and add any error messages to $errors array
// TODO: Validate password as required first, then validate minimum length of 8 characters
// Use a try-catch block and add any error messages to $errors array
// TODO: After all validations:
// - If there are errors, print each error message on its own line
// - If there are no errors, print "Registration successful"
?>All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern