Topics Covered in This PHP & MySQL Tutorial:
Input Sanitization, Comprehensive Error Handling, Dynamic Error Display, Professional Email Integration, Thank You Page Implementation, and Modular File Architecture
Exercise Overview
User input validation represents one of the most critical security and usability foundations in web development. Every form submission creates a potential vulnerability if not properly handled—from simple user experience issues like forgotten required fields to serious security threats from malicious code injection. Modern web applications employ a two-tiered validation approach: client-side and server-side checking.
While client-side validation using JavaScript frameworks provides immediate user feedback and reduces server load, it cannot be your only line of defense. Approximately 2-3% of users disable JavaScript, and more importantly, attackers routinely bypass client-side restrictions entirely. Server-side validation remains absolutely non-negotiable for production applications.
This exercise builds a production-ready form validation system that demonstrates industry best practices: input sanitization, comprehensive error handling, secure email processing, and modular code organization. These fundamentals scale directly to enterprise-level applications and modern PHP frameworks like Laravel and Symfony.
Client-Side vs Server-Side Validation
| Feature | Client-Side | Server-Side |
|---|---|---|
| Technology | JavaScript/jQuery | PHP |
| Reliability | Can be bypassed | Always executes |
| User Experience | Immediate feedback | Page reload required |
| Security | Vulnerable to hackers | Secure validation |
Client-side validation cannot be relied upon as users may have JavaScript disabled or hackers may purposefully bypass security measures.
Getting Started
Let's establish our development environment and examine the foundation form that we'll be securing and enhancing throughout this tutorial.
Open form.php from the form-validate-simple folder in the phpclass folder.
In a browser go to:
- Mac: localhost:8888/phpclass/form-validate-simple/form.php
- Windows: localhost/phpclass/form-validate-simple/form.php
You'll see a basic contact form with name, email, and publication preference checkboxes. This represents a typical lead generation form you might implement for a client or business.
Our enhancement roadmap includes:
- Implementing required field validation for name and email
- Adding email format verification using PHP's built-in filters
- Applying comprehensive input sanitization to prevent XSS attacks
- Creating user-friendly error messaging with detailed feedback
- Building professional email notifications with formatted data
- Developing a confirmation workflow for successful submissions
Before we begin processing, we need to configure the checkbox array properly for PHP's superglobal handling.
Switch back to your code editor.
Find the What do you read? checkbox fields around line 25. Add brackets to the name attributes to create a proper array structure:
<label><input name="publications[]" type="checkbox" id="publications_drf" value="Daily Racing Form"> Daily Racing Form</label> <label><input name="publications[]" type="checkbox" id="publications_elle" value="Elle"> Elle</label>The square brackets tell PHP to treat multiple checkbox values as an indexed array, essential for processing multiple selections.
Now configure the form's submission target. Around line 13, set the action attribute to point to our processing script:
<form action="form-action.php" method="post" name="signup" id="signup">Save the page.
Create a new page called form-action.php and save it into the form-validate-simple folder. This will serve as our central processing hub.
Form Setup Requirements
Add Array Brackets
Modify checkbox input names to publications[] so PHP recognizes them as arrays
Set Form Action
Configure the form action attribute to point to form-action.php for processing
Create Action File
Build the form-action.php file to handle form submission and validation logic
Building a Professional Input Sanitization System
Input sanitization forms your first line of defense against malicious data. Rather than simply escaping HTML entities, we'll implement a robust sanitization function that strips potentially dangerous content entirely while preserving legitimate user input.
In form-action.php, create the foundation for our sanitization system:
<?php function sanitizeInput() { } ?>This establishes our core sanitization function that we'll use throughout the application.
Implement the complete sanitization logic with parameter handling and multi-step cleaning:
function sanitizeInput($myInput) { $myInput = trim($myInput); $myInput = strip_tags($myInput); return $myInput; }This implementation follows a three-step sanitization process:
trim()removes whitespace from both ends, preventing accidental validation failuresstrip_tags()eliminates all HTML and PHP tags, blocking XSS injection attempts- Return statement provides the cleaned data back to the calling code
In production environments, you might extend this with additional filters like
htmlspecialchars()or database-specific escape functions.Initialize our error tracking system immediately after the function definition:
function sanitizeInput($myInput) { $myInput = trim($myInput); $myInput = strip_tags($myInput); return $myInput; } $errors = array();The
$errorsarray serves as our centralized error collection system. Empty arrays evaluate tofalsein conditional statements, making it simple to check whether the form passed all validation tests.Process the straightforward text inputs through our sanitization pipeline:
$errors = array(); $name = sanitizeInput($_POST['name']); $email = sanitizeInput($_POST['email']);We immediately sanitize and assign the core form fields to working variables, creating clean data for validation and email processing.
Handle the checkbox array with conditional processing, since checkboxes only submit data when selected:
$name = sanitizeInput($_POST['name']); $email = sanitizeInput($_POST['email']); if ( isset($_POST['publications']) ) { }Convert the checkbox array into a properly formatted, sanitized string:
if ( isset($_POST['publications']) ) { $publications = sanitizeInput( implode(', ', $_POST['publications']) ); }The
implode()function joins array elements with comma-space delimiters, creating professional-looking output like "Daily Racing Form, Elle, Vogue" for email notifications.Provide a sensible default when no checkboxes are selected:
if ( isset($_POST['publications']) ) { $publications = sanitizeInput( implode(', ', $_POST['publications']) ); } else { $publications = ''; }Setting empty strings prevents undefined variable errors and provides consistent data types for downstream processing.
Implementing Comprehensive Error Validation
With sanitized data in hand, we can now implement thorough validation that checks for both required fields and data quality. Modern web applications must balance user experience with data integrity requirements.
Validate the name field with clear, actionable error messaging:
if ( $name == '' ) { $errors[] = "You must enter a name."; }Required field validation should always provide specific guidance about what's missing, rather than generic "form error" messages.
Apply the same principle to email validation:
if ( $email == '' ) { $errors[] = "You must enter an email."; }Email addresses serve dual purposes: user communication and often as unique identifiers in customer databases, making them critical for most business applications.
Beyond checking for presence, email format validation prevents common user errors and ensures deliverability. PHP 5.2+ includes the robust
filter_var()function, which handles complex validation scenarios including email addresses, URLs, IP addresses, and custom patterns. The email validator performs comprehensive format checking including domain syntax validation.The validation syntax follows this pattern:
filter_var($email, FILTER_VALIDATE_EMAIL)This function returns the email address if valid, or false for invalid formats. Note that this validates format only—it doesn't verify that the email address actually exists or accepts mail.
Implement format validation for submitted email addresses:
if ( $email == '' ) { $errors[] = "You must enter an email."; } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) ) { $errors[] = "That email is not valid."; }Using
elseifensures we don't run format validation on empty strings, preventing redundant error messages.
Creating Dynamic Error Display
Professional error handling requires more than just validation—users need clear, helpful feedback presented in an intuitive format. Our approach separates successful submissions from error states, providing appropriate responses for each scenario.
Implement the core routing logic that directs form processing based on validation results:
elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) ) { $errors[] = "That email is not valid."; } if ( empty($errors) ) { //send email and display confirm page } else { //display errors }This creates two distinct pathways: error-free submissions proceed to email processing and confirmation, while problematic submissions receive detailed error feedback.
Configure error display using modular file inclusion:
if ( empty($errors) ) { //send email and display confirm page } else { require_once('form-error.php'); }The
require_once()function provides several advantages over basicinclude()statements:- Prevents duplicate inclusions if called multiple times in complex applications
- Generates fatal errors for missing files, making debugging straightforward
- Supports modular architecture that scales well in team development environments
This approach separates concerns cleanly—our validation logic focuses purely on data checking, while presentation logic lives in dedicated templates.
Save the page and examine the error display template.
Open form-error.php from the form-validate-simple folder.
Locate line 15 and replace the Display errors here comment with dynamic error rendering:
<?php foreach($errors as $value) { echo '<li>'; echo $value; echo '</li>'; } ?>This loop generates semantic HTML list items for each validation error, providing screen reader accessibility and consistent styling hooks for CSS frameworks.
Save the file and test the validation system:
- Mac: localhost:8888/phpclass/form-validate-simple/form.php
- Windows: localhost/phpclass/form-validate-simple/form.php
Experiment with various error conditions: empty name field, missing email, and invalid email formats like "test" or "user@". Confirm that appropriate, specific error messages appear for each validation failure.
Building Professional Email Integration
With validation complete, we can safely process successful form submissions into formatted email notifications. Professional email handling requires attention to headers, formatting, and content structure that works across different email clients and platforms.
Return to your code editor and open form-action.php.
Replace the success pathway comment with our email processing module:
if ( empty($errors) ) { require_once('form-send-email.php'); } else { require_once('form-error.php'); }Save the file and create our dedicated email processing script.
Create form-send-email.php in the form-validate-simple folder.
Configure the email destination based on your development environment:
- For Mac users with actual email accounts:
<?php $to = "youremail@gmail.com"; ?>- For Windows users with local mail servers:
<?php $to = "newuser@localhost"; ?>Build the complete email structure with professional headers and formatting:
<?php $to = "youremail@gmail.com"; $subject = "You have new mail!"; $message = "You have a new signup!\r\n\r\n"; $headers = "From:newuser@localhost\r\n"; mail($to, $subject, $message, $headers); ?>The
mail()function represents PHP's built-in SMTP interface. In production environments, you'd typically use more robust solutions like PHPMailer or SwiftMailer for enhanced deliverability and feature sets.Test the basic email functionality:
- Mac: localhost:8888/phpclass/form-validate-simple/form.php
- Windows: localhost/phpclass/form-validate-simple/form.php
Complete a valid form submission and verify email delivery:
- Mac users: Check your email account (including spam folders)
- Windows users: Open Thunderbird and click Get Mail
With basic delivery confirmed, let's enhance the email content with the actual form data.
Return to form-send-email.php in your editor.
Enhance the message content with structured form data:
<?php $to = "youremail@gmail.com"; $subject = "You have new mail!"; $message = "You have a new signup!\r\n\r\n"; $message.= "Name: $name \r\n"; $message.= "Email: $email \r\n"; $message.= "Publications: $publications\r\n"; $headers = "From:newuser@localhost\r\n"; mail($to, $subject, $message, $headers); ?>The .= concatenation operator appends content to existing strings, while
\r\nprovides cross-platform line breaks that work correctly in email clients.Test the enhanced email system with complete form data:
- Mac: localhost:8888/phpclass/form-validate-simple/form.php
- Windows: localhost/phpclass/form-validate-simple/form.php
Submit the form with various checkbox combinations and verify that all data appears correctly formatted in your email notifications.
Implementing User Confirmation Workflow
Professional web applications always acknowledge successful form submissions with clear confirmation messaging. This builds user confidence and provides an opportunity for additional engagement or next-step guidance.
Return to form-action.php in your editor.
Add confirmation page display to the successful submission pathway:
if ( empty($errors) ) { require_once('form-send-email.php'); require_once('form-confirm.html'); } else { require_once('form-error.php'); }This creates a complete user experience: form submission → email processing → immediate confirmation feedback. The confirmation template has been pre-built to demonstrate professional styling and messaging approaches.
Perform final testing of the complete workflow:
- Mac: localhost:8888/phpclass/form-validate-simple/form.php
- Windows: localhost/phpclass/form-validate-simple/form.php
Submit a complete, valid form and confirm that you receive both the email notification and the user-friendly confirmation page.
Close all files. You've successfully built a production-ready form processing system that demonstrates industry best practices for validation, security, and user experience.