Web forms allow visitors to send information to a PHP program.
However, we should never assume that submitted information is complete, correct or safe to display.
A visitor might:
- Leave a required box empty
- Enter letters where a number is expected
- Type an invalid email address
- Select a value that our form does not allow
- Enter a very long value by mistake
- Change the form using browser developer tools
- Send the request without using our webpage at all
This is why PHP programs need form validation.
In Part 10 of this PHP tutorial for kids and complete beginners, you will learn:
- What form validation means
- Why HTML validation is not enough by itself
- How to check whether a form was submitted
- How to safely read values from
$_POST - How to check required fields
- How to validate names, ages, email addresses and choices
- How to show useful error messages
- How to keep old values inside the form
- How to escape information before displaying it
- How to build a complete Kids’ Club registration form
- How to organise repeated validation code with functions
The examples use beginner-friendly PHP 8 syntax and do not require a database.
Quick Answer
PHP form validation checks whether submitted information follows the rules of our program.
Here is a small example:
<?php
$name = "";
$nameError = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$name = trim($_POST["name"] ?? "");
if ($name === "") {
$nameError = "Please enter your name.";
}
}
?>
<form method="post">
<label for="name">Name</label>
<input
type="text"
id="name"
name="name"
value="<?php echo htmlspecialchars($name); ?>"
>
<p><?php echo $nameError; ?></p>
<button type="submit">Submit</button>
</form>
The program:
- Waits for a
POSTrequest. - Reads the submitted name.
- Removes unnecessary spaces with
trim(). - Checks whether the name is empty.
- Displays an error if the visitor did not enter a name.
- Safely places the old value back inside the form.
We will improve every part of this example during the tutorial.
What Is Form Validation?
Form validation means checking submitted information before using it.
Imagine that we are creating a registration form with these rules:
| Field | Rule |
|---|---|
| Name | Required and no longer than 50 characters |
| Required and must look like an email address | |
| Age | Must be a whole number from 7 to 17 |
| Favourite colour | Must be one of the available choices |
| Agreement | Must be selected |
If the submitted data follows all the rules, it is valid.
If one or more rules are broken, the program should not continue as though everything is correct. It should explain the problem and allow the visitor to fix it.
Good validation should answer three questions:
- Is the value present?
- Is it the correct type or format?
- Is it acceptable for this particular program?
An age of 500 is made from numbers, but it is not acceptable for a children’s club. Format checking alone is therefore not enough.
Client-Side and Server-Side Validation
HTML can perform some validation inside the browser.
<input
type="email"
name="email"
required
>
The required attribute asks the browser to prevent an empty submission. The email type asks the browser to check the basic email format.
This is called client-side validation because it happens in the visitor’s browser.
It is useful because the visitor receives quick feedback. However, it must not be our only validation.
A visitor or another program can:
- Remove the HTML attributes
- Change the page using developer tools
- Turn off browser validation
- Send a request directly to the PHP file
- Submit extra values that never appeared in the original form
PHP validation runs on the server. This is called server-side validation.
| Validation type | Runs where? | Main purpose |
| HTML or JavaScript | Visitor’s browser | Fast and friendly feedback |
| PHP | Web server | Final trusted decision |
Use both when possible, but always let PHP make the final decision.
A Basic HTML Form
Create a new file named:
registration.php
Start with this form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kids' Club Registration</title>
</head>
<body>
<h1>Kids' Club Registration</h1>
<form method="post">
<label for="name">Name</label>
<input type="text" id="name" name="name">
<label for="email">Email</label>
<input type="email" id="email" name="email">
<label for="age">Age</label>
<input type="number" id="age" name="age">
<button type="submit">Register</button>
</form>
</body>
</html>
The form uses:
method="post"
When the button is pressed, the browser sends the values to PHP in a POST request.
Because the form has no action attribute, it submits to the same page.
Checking Whether the Form Was Submitted
The page is normally requested with GET when we first open it.
The form sends a POST request when it is submitted.
PHP provides the request method through:
$_SERVER["REQUEST_METHOD"]
We can check it like this:
<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {
echo "The form was submitted.";
}
The strict comparison operator === checks both value and type.
For this form, our validation code should run only after a POST request. Without the if statement, the page could display errors before the visitor has entered anything.
Safely Reading Values from POST
A submitted text field can be read from $_POST:
$name = $_POST["name"];
However, this assumes that name definitely exists.
Someone can submit a request without that field. PHP may then show an “Undefined array key” warning.
Use the null coalescing operator instead:
$name = $_POST["name"] ?? "";
This means:
- Use
$_POST["name"]if it exists. - Otherwise, use an empty string.
For a simple beginner form, we can then remove spaces from the beginning and end:
$name = trim($_POST["name"] ?? "");
If a visitor enters:
Aina
trim() changes it to:
Aina
A More Defensive Version
A request can be changed so that name is sent as an array instead of text. Passing an array into trim() causes a type error.
We can guard against that:
$nameInput = $_POST["name"] ?? "";
if (!is_string($nameInput)) {
$nameInput = "";
}
$name = trim($nameInput);
This is slightly longer, but it prevents malformed input from crashing the validation code.
Later, we will place this repeated work inside a function.
Checking a Required Field
Create variables before processing the form:
<?php
$name = "";
$nameError = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$nameInput = $_POST["name"] ?? "";
if (!is_string($nameInput)) {
$nameInput = "";
}
$name = trim($nameInput);
if ($name === "") {
$nameError = "Please enter your name.";
}
}
We compare the cleaned name with an empty string:
if ($name === "")
If it is empty, we store an error message.
We can display the message beneath the input:
<label for="name">Name</label>
<input type="text" id="name" name="name">
<?php if ($nameError !== ""): ?>
<p><?php echo $nameError; ?></p>
<?php endif; ?>
The paragraph appears only when an error exists.
Checking the Length of a Name
A required-field check prevents an empty value, but someone could still submit thousands of characters.
We can add a maximum length:
if ($name === "") {
$nameError = "Please enter your name.";
} elseif (strlen($name) > 50) {
$nameError = "Your name must be 50 characters or fewer.";
}
The elseif runs only when the first condition is false.
The browser can also receive the same limit:
<input
type="text"
id="name"
name="name"
maxlength="50"
required
>
Remember that the HTML rule improves the experience, while PHP still enforces the trusted rule.
For multilingual production websites, developers often use mb_strlen() so that multibyte characters are counted properly. That function requires PHP’s mbstring extension. We use strlen() here to keep the first project simple.
Validating an Email Address
Checking whether an email contains @ is not enough.
This is too weak:
if (!str_contains($email, "@")) {
$emailError = "Invalid email.";
}
PHP provides filter_var() with FILTER_VALIDATE_EMAIL:
if ($email === "") {
$emailError = "Please enter an email address.";
} elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$emailError = "Please enter a valid email address.";
}
Examples:
| Value | Basic result |
[email protected] | Valid format |
aina.example.com | Invalid format |
aina@ | Invalid format |
| Empty string | Required-field error |
Email validation checks the format. It does not prove that:
- The mailbox exists
- The address belongs to the visitor
- The visitor can receive messages
A real registration system normally sends a verification link or code to confirm ownership.
Validating a Whole Number and Range
Our club accepts ages from 7 to 17.
We want to reject:
- An empty value
- Words such as
twelve - Decimals such as
12.5 - Ages lower than 7
- Ages greater than 17
PHP can validate the number and range together:
$ageValue = filter_var(
$age,
FILTER_VALIDATE_INT,
[
"options" => [
"min_range" => 7,
"max_range" => 17
]
]
);
if ($age === "") {
$ageError = "Please enter your age.";
} elseif ($ageValue === false) {
$ageError = "Age must be a whole number from 7 to 17.";
}
The strict check is important:
$ageValue === false
Some valid filters can return values that PHP might otherwise treat as false. A strict comparison makes our intention clear.
The HTML input should also describe the range:
<input
type="number"
id="age"
name="age"
min="7"
max="17"
step="1"
required
>
Again, the PHP check remains necessary.
Validating a Select Menu
Suppose the form offers three favourite colours:
<select id="colour" name="colour">
<option value="">Choose a colour</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>
It may appear impossible to submit another value, but a request can be edited.
Create a list of allowed values:
$allowedColours = [
"red",
"blue",
"green"
];
Then validate the submitted value:
if (!in_array($colour, $allowedColours, true)) {
$colourError = "Please choose one of the available colours.";
}
The final argument true tells in_array() to use strict comparison.
This method is sometimes called an allowlist. Instead of trying to imagine every bad value, we accept only the values our program understands.
Validating a Checkbox
Checkboxes behave differently from text inputs.
If a checkbox is not selected, its name is normally absent from $_POST.
HTML:
<input
type="checkbox"
id="agree"
name="agree"
value="yes"
>
<label for="agree">
I agree to follow the club rules.
</label>
PHP:
$agreed = (
isset($_POST["agree"])
&& $_POST["agree"] === "yes"
);
if (!$agreed) {
$agreeError = "You must agree to the club rules.";
}
We do not merely check whether any value was submitted. We check for the exact allowed value yes.
Validation, Sanitisation and Escaping Are Different
These words are related, but they do not mean the same thing.
| Job | Question | Example |
| Validation | Is this value acceptable? | Is age an integer from 7 to 17? |
| Sanitisation | Should the value be transformed or cleaned? | Remove surrounding spaces with trim() |
| Escaping | How can this value be safely placed into a particular output? | Convert special HTML characters before displaying text |
Consider this name:
<script>alert('Hello')</script>
If we directly place it into HTML, the browser may treat it as code.
Do not output untrusted text like this:
echo $_POST["name"];
Escape it for HTML:
echo htmlspecialchars(
$name,
ENT_QUOTES | ENT_SUBSTITUTE,
"UTF-8"
);
The browser then displays the characters as text instead of interpreting them as an HTML tag.
It is helpful to create a short function:
function e(string $value): string
{
return htmlspecialchars(
$value,
ENT_QUOTES | ENT_SUBSTITUTE,
"UTF-8"
);
}
Now we can write:
<?php echo e($name); ?>
Escaping depends on where the value is going. HTML text, HTML attributes, URLs, JavaScript, SQL and terminal commands have different rules. htmlspecialchars() is for HTML output; it is not a database security function.
Creating a Sticky Form
A sticky form keeps valid submitted values after an error.
Without a sticky form, a visitor who makes one mistake may need to type everything again.
For a text input:
<input
type="text"
id="name"
name="name"
value="<?php echo e($name); ?>"
>
For a select menu:
<option
value="blue"
<?php echo $colour === "blue" ? "selected" : ""; ?>
>
Blue
</option>
For a checkbox:
<input
type="checkbox"
id="agree"
name="agree"
value="yes"
<?php echo $agreed ? "checked" : ""; ?>
>
Do not place raw submitted text into an HTML value attribute. Always escape it first.
Passwords are a common exception: password boxes are normally cleared rather than refilled after an error.
Storing Errors in an Array
Separate variables such as $nameError and $emailError work, but a larger form becomes easier to manage with an array.
$errors = [];
Add an error using the field name as the key:
if ($name === "") {
$errors["name"] = "Please enter your name.";
}
Display one field’s error:
<?php if (isset($errors["name"])): ?>
<p class="error">
<?php echo e($errors["name"]); ?>
</p>
<?php endif; ?>
Check whether the entire form is valid:
if ($errors === []) {
$success = true;
}
An empty error array means that no validation rule failed.
Reusing Code with a Helper Function
Several text fields need the same safe reading steps.
We can create a function:
function postText(string $key): string
{
$value = $_POST[$key] ?? "";
if (!is_string($value)) {
return "";
}
return trim($value);
}
Now we can read values with:
$name = postText("name");
$email = postText("email");
$age = postText("age");
$colour = postText("colour");
This makes the main validation section shorter and gives every text field consistent basic handling.
The function does not decide whether a value is valid. It only returns a trimmed string or an empty string. Each field still has its own rules.
Complete Project: Kids’ Club Registration Form
The following project combines all the lessons into one file.
Save it as:
registration.php
<?php
function e(string $value): string
{
return htmlspecialchars(
$value,
ENT_QUOTES | ENT_SUBSTITUTE,
"UTF-8"
);
}
function postText(string $key): string
{
$value = $_POST[$key] ?? "";
if (!is_string($value)) {
return "";
}
return trim($value);
}
$name = "";
$email = "";
$age = "";
$colour = "";
$agreed = false;
$errors = [];
$success = false;
$allowedColours = [
"red",
"blue",
"green"
];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$name = postText("name");
$email = postText("email");
$age = postText("age");
$colour = postText("colour");
$agreed = (
isset($_POST["agree"])
&& $_POST["agree"] === "yes"
);
if ($name === "") {
$errors["name"] = "Please enter your name.";
} elseif (strlen($name) > 50) {
$errors["name"] = (
"Your name must be 50 characters or fewer."
);
}
if ($email === "") {
$errors["email"] = (
"Please enter an email address."
);
} elseif (
filter_var(
$email,
FILTER_VALIDATE_EMAIL
) === false
) {
$errors["email"] = (
"Please enter a valid email address."
);
}
if ($age === "") {
$errors["age"] = "Please enter your age.";
} else {
$validAge = filter_var(
$age,
FILTER_VALIDATE_INT,
[
"options" => [
"min_range" => 7,
"max_range" => 17
]
]
);
if ($validAge === false) {
$errors["age"] = (
"Age must be a whole number from 7 to 17."
);
}
}
if (!in_array($colour, $allowedColours, true)) {
$errors["colour"] = (
"Please choose an available colour."
);
}
if (!$agreed) {
$errors["agree"] = (
"You must agree to follow the club rules."
);
}
if ($errors === []) {
$success = true;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kids' Club Registration</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 30px 16px;
background: #f2f6ff;
color: #1f2937;
font-family: Arial, sans-serif;
}
.card {
width: 100%;
max-width: 620px;
margin: 0 auto;
padding: 28px;
border-radius: 16px;
background: #ffffff;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
}
h1 {
margin-top: 0;
}
.field {
margin-bottom: 20px;
}
label,
legend {
display: block;
margin-bottom: 7px;
font-weight: bold;
}
input[type="text"],
input[type="email"],
input[type="number"],
select {
width: 100%;
padding: 11px;
border: 1px solid #9ca3af;
border-radius: 8px;
font: inherit;
}
fieldset {
padding: 0;
border: 0;
}
.checkbox-row {
display: flex;
gap: 9px;
align-items: flex-start;
}
.checkbox-row label {
margin: 0;
font-weight: normal;
}
.error {
margin: 7px 0 0;
color: #b91c1c;
font-size: 0.92rem;
}
.error-summary {
margin-bottom: 22px;
padding: 14px;
border: 1px solid #f87171;
border-radius: 8px;
background: #fef2f2;
}
.success {
padding: 18px;
border: 1px solid #34d399;
border-radius: 8px;
background: #ecfdf5;
}
button {
padding: 11px 18px;
border: 0;
border-radius: 8px;
background: #2563eb;
color: white;
font: inherit;
font-weight: bold;
cursor: pointer;
}
button:hover {
background: #1d4ed8;
}
</style>
</head>
<body>
<main class="card">
<h1>Kids' Club Registration</h1>
<?php if ($success): ?>
<div class="success">
<h2>Registration received!</h2>
<p>
Welcome, <?php echo e($name); ?>.
Your form passed all the validation checks.
</p>
<p>
A real website could now save the information
or send a confirmation message.
</p>
</div>
<?php else: ?>
<?php if ($errors !== []): ?>
<div class="error-summary">
<strong>Please correct the form.</strong>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php echo e($error); ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form method="post" novalidate>
<div class="field">
<label for="name">Name</label>
<input
type="text"
id="name"
name="name"
maxlength="50"
value="<?php echo e($name); ?>"
required
>
<?php if (isset($errors["name"])): ?>
<p class="error">
<?php echo e($errors["name"]); ?>
</p>
<?php endif; ?>
</div>
<div class="field">
<label for="email">Email address</label>
<input
type="email"
id="email"
name="email"
value="<?php echo e($email); ?>"
required
>
<?php if (isset($errors["email"])): ?>
<p class="error">
<?php echo e($errors["email"]); ?>
</p>
<?php endif; ?>
</div>
<div class="field">
<label for="age">Age</label>
<input
type="number"
id="age"
name="age"
min="7"
max="17"
step="1"
value="<?php echo e($age); ?>"
required
>
<?php if (isset($errors["age"])): ?>
<p class="error">
<?php echo e($errors["age"]); ?>
</p>
<?php endif; ?>
</div>
<div class="field">
<label for="colour">Favourite colour</label>
<select id="colour" name="colour" required>
<option value="">Choose a colour</option>
<option
value="red"
<?php echo $colour === "red" ? "selected" : ""; ?>
>
Red
</option>
<option
value="blue"
<?php echo $colour === "blue" ? "selected" : ""; ?>
>
Blue
</option>
<option
value="green"
<?php echo $colour === "green" ? "selected" : ""; ?>
>
Green
</option>
</select>
<?php if (isset($errors["colour"])): ?>
<p class="error">
<?php echo e($errors["colour"]); ?>
</p>
<?php endif; ?>
</div>
<fieldset class="field">
<legend>Club rules</legend>
<div class="checkbox-row">
<input
type="checkbox"
id="agree"
name="agree"
value="yes"
<?php echo $agreed ? "checked" : ""; ?>
>
<label for="agree">
I agree to be kind and follow the club rules.
</label>
</div>
<?php if (isset($errors["agree"])): ?>
<p class="error">
<?php echo e($errors["agree"]); ?>
</p>
<?php endif; ?>
</fieldset>
<button type="submit">Register</button>
</form>
<?php endif; ?>
</main>
</body>
</html>
Why Does the Form Use novalidate?
The project contains:
<form method="post" novalidate>
novalidate temporarily disables the browser’s automatic validation. This makes it easier to test and see our PHP error messages during the lesson.
After you understand the PHP checks, remove novalidate:
<form method="post">
The final form will then use both browser validation and PHP validation.
How the Complete Project Works
1. Helper Functions Are Created
The e() function escapes text for HTML:
function e(string $value): string
The postText() function safely reads a submitted string:
function postText(string $key): string
2. Default Values Are Prepared
Before the form is submitted, the field values are empty and success is false:
$name = "";
$errors = [];
$success = false;
This also prevents undefined-variable warnings in the HTML section.
3. PHP Waits for POST
if ($_SERVER["REQUEST_METHOD"] === "POST")
The validation runs only after submission.
4. Every Field Is Checked
Each field has rules that match its purpose:
- Name: required and maximum length
- Email: required and valid format
- Age: required integer in a permitted range
- Colour: must appear in the allowlist
- Agreement: exact checkbox value required
5. Success Requires No Errors
if ($errors === []) {
$success = true;
}
The program does not accept the form if even one error remains.
6. The Page Shows One of Two Views
If $success is true, the confirmation is shown.
Otherwise, the form is shown with its previous values and any error messages.
How to Run the Project
Open a terminal in the folder containing registration.php.
Run PHP’s built-in development server:
php -S localhost:8000
Open this address in your browser:
http://localhost:8000/registration.php
Stop the development server by pressing:
Ctrl + C
The built-in server is useful for learning and local development. It is not intended to be a public production web server.
Testing the Validation
Do not test only the happy path. Try values that should fail.
| Test | Expected result |
| Submit everything empty | Required-field errors appear |
| Name contains spaces only | Name error appears after trim() |
| Name is longer than 50 characters | Length error appears |
Email is hello | Email-format error appears |
Age is 6 | Range error appears |
Age is 18 | Range error appears |
Age is 12.5 | Whole-number error appears |
| No colour chosen | Colour error appears |
| Agreement not selected | Agreement error appears |
| One field is wrong | Other valid values remain in the form |
Name contains <b>Aina</b> | Tags appear as text, not formatted HTML |
| Every field is valid | Success message appears |
You can also use browser developer tools to change a colour option to an unexpected value. PHP should reject it because it is not in $allowedColours.
Testing invalid input is part of programming. It helps prove that the program follows its rules when users make mistakes or requests are modified.
Common PHP Form Validation Mistakes
1. Trusting required by Itself
This improves browser validation:
<input name="name" required>
It does not replace PHP validation. A request can bypass the HTML page.
2. Reading Missing Keys Directly
Risky:
$name = $_POST["name"];
Safer:
$name = $_POST["name"] ?? "";
For defensive code, also confirm that the value is a string.
3. Showing Submitted Data Without Escaping
Unsafe:
echo $_POST["name"];
Safer for HTML output:
echo htmlspecialchars(
$name,
ENT_QUOTES | ENT_SUBSTITUTE,
"UTF-8"
);
4. Checking Only the Data Type
This checks whether age is an integer:
filter_var($age, FILTER_VALIDATE_INT)
The program must still check whether the integer is in the allowed range.
5. Trusting Select and Radio Values
A menu is not a security boundary. Validate its value against an allowlist on the server.
6. Using empty() Without Understanding It
empty() treats several different values as empty, including the string "0".
For required text, an explicit check is often clearer:
if ($value === "")
This is especially important if 0 might be a valid answer.
7. Removing Characters Instead of Defining Rules
Silently deleting unexpected characters may change a person’s real name or other important data.
Whenever possible:
- Trim unnecessary surrounding spaces.
- Validate the value according to clear rules.
- Show an error if the value is unacceptable.
- Escape it for the output context when displayed.
8. Confusing Email Format with Email Ownership
FILTER_VALIDATE_EMAIL checks the format. Verification normally requires sending a link or code to the address.
9. Saving Data Before All Checks Pass
Do not write to a file or database and then discover that another field is invalid.
The usual order is:
- Read the request.
- Validate all fields.
- If errors exist, show the form again.
- If there are no errors, perform the intended action.
10. Believing Validation Solves Every Security Problem
Validation is one part of secure form handling.
A production form that changes data may also need:
- CSRF protection
- Authentication and authorisation
- Safe database queries using prepared statements
- Rate limiting
- Secure file-upload rules
- Password hashing
- HTTPS
- Server-side logging without exposing private information
We will meet several of these ideas in later lessons.
Validation Rules Should Match the Project
There is no universal rule that every name must contain only letters.
Real names can contain:
- Spaces
- Hyphens
- Apostrophes
- Accented letters
- Characters from many writing systems
A rule such as this can reject genuine names:
if (!preg_match("/^[a-zA-Z]+$/", $name)) {
// This is too restrictive for many real names.
}
For a beginner registration form, requiring a non-empty name and a reasonable maximum length is often more suitable.
Validation is a program-design decision. Ask what the application truly needs rather than copying a strict rule from an unrelated tutorial.
Practice Exercises
Try these tasks before reading the answers.
Exercise 1: Username
Create a username field with these rules:
- Required
- At least 3 characters
- No more than 20 characters
Exercise 2: Lucky Number
Create a lucky-number field that accepts only whole numbers from 1 to 100.
Exercise 3: Favourite Animal
Create a select menu containing:
- Cat
- Dog
- Rabbit
Validate the result with an allowlist.
Exercise 4: Sticky Nickname
Create a nickname input. If another field has an error, keep the submitted nickname inside the form and escape it safely.
Exercise 5: Error List
Store three errors inside an array and use foreach to display them as an HTML unordered list.
Exercise 6: Add a Hobby
Add a hobby field to the complete project. It should be optional but no longer than 100 characters.
Exercise Answers
Answer 1
$username = postText("username");
if ($username === "") {
$errors["username"] = "Please enter a username.";
} elseif (strlen($username) < 3) {
$errors["username"] = (
"The username must contain at least 3 characters."
);
} elseif (strlen($username) > 20) {
$errors["username"] = (
"The username must contain no more than 20 characters."
);
}
Answer 2
$luckyNumber = postText("lucky_number");
$validLuckyNumber = filter_var(
$luckyNumber,
FILTER_VALIDATE_INT,
[
"options" => [
"min_range" => 1,
"max_range" => 100
]
]
);
if ($validLuckyNumber === false) {
$errors["lucky_number"] = (
"Enter a whole number from 1 to 100."
);
}
Answer 3
$animal = postText("animal");
$allowedAnimals = [
"cat",
"dog",
"rabbit"
];
if (!in_array($animal, $allowedAnimals, true)) {
$errors["animal"] = "Please choose a valid animal.";
}
Answer 4
<input
type="text"
id="nickname"
name="nickname"
value="<?php echo e($nickname); ?>"
>
The value must be escaped before it is placed inside the HTML attribute.
Answer 5
$errors = [
"Please enter your name.",
"Please enter a valid email address.",
"Please choose a colour."
];
<ul>
<?php foreach ($errors as $error): ?>
<li><?php echo e($error); ?></li>
<?php endforeach; ?>
</ul>
Answer 6
$hobby = postText("hobby");
if (strlen($hobby) > 100) {
$errors["hobby"] = (
"Your hobby must be 100 characters or fewer."
);
}
There is no required-field check because an empty hobby is allowed.
PHP Form Validation Cheat Sheet
Check for POST
if ($_SERVER["REQUEST_METHOD"] === "POST") {
// Validate submitted values.
}
Read a Value with a Default
$name = $_POST["name"] ?? "";
Trim a String Safely
$value = $_POST["field"] ?? "";
if (!is_string($value)) {
$value = "";
}
$value = trim($value);
Check Required Text
if ($value === "") {
$errors["field"] = "This field is required.";
}
Check Maximum Length
if (strlen($value) > 50) {
$errors["field"] = "Use 50 characters or fewer.";
}
Validate an Email
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$errors["email"] = "Enter a valid email address.";
}
Validate an Integer Range
$number = filter_var(
$value,
FILTER_VALIDATE_INT,
[
"options" => [
"min_range" => 1,
"max_range" => 100
]
]
);
if ($number === false) {
$errors["number"] = "Enter a whole number from 1 to 100.";
}
Validate an Allowed Choice
if (!in_array($choice, $allowedChoices, true)) {
$errors["choice"] = "Choose an available option.";
}
Escape HTML Output
echo htmlspecialchars(
$value,
ENT_QUOTES | ENT_SUBSTITUTE,
"UTF-8"
);
Check Whether Validation Passed
if ($errors === []) {
echo "The form is valid.";
}
Frequently Asked Questions
What is PHP form validation?
PHP form validation checks submitted values on the server before the program accepts or uses them. It can check required fields, formats, lengths, ranges and allowed choices.
Why is HTML required not enough?
HTML validation happens in the browser and can be changed or bypassed. PHP must repeat the important checks on the server.
What does trim() do?
trim() removes whitespace from the beginning and end of a string. It is useful when a visitor accidentally enters extra spaces.
What does the double question mark mean?
The null coalescing operator ?? provides a default value when an array key does not exist or contains null.
$name = $_POST["name"] ?? "";
Should I use GET or POST for a registration form?
Use POST for a form that submits registration information or causes a change. GET is more suitable for retrieval operations such as searches and filters whose parameters can appear in the URL.
POST values not appearing in the address bar does not automatically make them encrypted. Use HTTPS for information travelling between the browser and server.
Does filter_var() clean all dangerous input?
No. filter_var() performs the filter you specifically request. For example, FILTER_VALIDATE_EMAIL checks email format. It does not automatically make the value safe for HTML, SQL or every other use.
Why use htmlspecialchars()?
It converts special characters so the browser treats them as text in HTML output rather than interpreting them as markup. Use it when displaying untrusted text in HTML.
Is validation the same as escaping?
No. Validation decides whether a value follows the program’s rules. Escaping safely represents a value in a particular output context. A valid name must still be escaped before being inserted into HTML.
What is a sticky form?
A sticky form keeps previously submitted values after validation fails. It prevents visitors from having to re-enter every correct field.
Why validate a select menu?
A visitor can modify HTML or send a request directly. PHP should accept only values that the server recognises.
Should error messages explain the exact problem?
For normal validation errors, yes. “Age must be a whole number from 7 to 17” is more useful than “Invalid input.” Security-sensitive systems may use more general messages for information such as login failures.
Can I save the successful form to a database now?
You can after learning safe database access. Use PDO prepared statements, validate the data first, and never build SQL by joining raw submitted values into a query.
What is CSRF protection?
Cross-site request forgery protection helps prove that a state-changing form was intentionally submitted from your application. It normally uses a random token stored in a server-side session. It becomes important when forms create, update or delete real data.
Why does the example not save anything?
Part 10 focuses on validation. Keeping the first project independent of a database makes it easier to see the complete request, validation and response process.
Final Summary
Form validation protects the rules and reliability of a PHP application.
In this tutorial, we learned:
- The browser can help with validation, but PHP makes the final decision.
$_SERVER["REQUEST_METHOD"]tells us how the page was requested.- The
??operator prevents warnings when a submitted key is missing. is_string()can reject malformed array input before string functions are used.trim()removes unnecessary surrounding spaces.- Required fields can be checked against an empty string.
- Length rules prevent unexpectedly large values.
filter_var()can validate email addresses and integers.- Number fields often need both a type check and a range check.
- Select, radio and checkbox values must also be checked on the server.
- An allowlist accepts only choices our program understands.
- Validation, sanitisation and output escaping have different purposes.
htmlspecialchars()safely represents untrusted text in HTML.- Sticky forms improve the experience after an error.
- An error array makes larger forms easier to organise.
- A form should continue only when every important check passes.
The best way to learn validation is to test both correct and incorrect values. Try missing fields, wrong formats, unexpected choices and very long text, then confirm that the program responds clearly without crashing.
In Part 11, we can learn how PHP sessions and cookies remember information between different page requests. We can then use a session to add a CSRF token and create safer multi-page projects.
Leave a Reply