Recommended Free Tools
Validate every submitted value on the server before using it: define what each field is allowed to contain, reject invalid input with a useful field-level message, and keep validation separate from both output encoding and CSRF protection. Browser checks can make a form easier to use, but they are not a security boundary.
What reliable PHP form validation does
A reliable form handler treats request data as untrusted, checks it against the form’s actual requirements, and proceeds only when all required checks pass. Validation should cover both a value’s shape and its meaning in the application: an integer may need to be within a permitted range, and two individually valid dates may still be invalid if the start date comes after the end date.
Client-side HTML constraints such as required, type="email", and maxlength help people catch routine mistakes before submitting. They do not replace server-side checks: a request can be sent without the browser interface or modified before it reaches PHP. OWASP’s Input Validation Cheat Sheet says validation must happen on the server before data is processed.
Choose a rule for each field
Write down the field’s expected type, allowed values, length limits, range, and any relationships to other fields before choosing a PHP function. The rule should fit the application, not just a convenient pattern.
#1 Best Overall
| Field type | Useful checks | Common pitfall |
|---|---|---|
| Integer or quantity | Check that the value is an integer, then enforce the business range. | Accepting numeric-looking strings without checking the expected range or treating a valid zero as failure. |
| Select or status | Compare against a server-defined list of permitted values. | Trusting a submitted option merely because the form normally offers it. |
| Email address | Check syntax as an initial filter; verify ownership with a confirmation link or code if the workflow requires it. | Assuming syntactic validity proves that the mailbox exists or belongs to the submitter. |
| Date or date range | Parse against the expected format, validate calendar correctness, and check relationships such as start before end. | Checking each date separately while overlooking an invalid range. |
| Name or free-form message | Apply appropriate requiredness and length limits; preserve legitimate Unicode text. | Rejecting ordinary names or messages with broad ASCII-only or denylist rules. |
For structured values, prefer a deliberate allowlist or constraint over a broad denylist. A rule such as “only these known status values” is usually more precise than trying to enumerate every unwanted value. For natural-language text, avoid arbitrary character restrictions that reject valid names or writing. OWASP discusses Unicode normalization and character-category or allowlist policies when a field genuinely needs character constraints.
Validate submitted values with explicit PHP rules
PHP’s filter_var() can apply an explicit validation or sanitization filter. Do not call it without a filter expecting it to validate input: the default, FILTER_DEFAULT, aliases FILTER_UNSAFE_RAW and performs no filtering. The PHP manual documents this behavior at filter_var().
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
On successful validation, filter_var() returns the filtered value; on failure it returns false, unless FILTER_NULL_ON_FAILURE is selected. Use strict comparison to distinguish failure from legitimate falsey values such as 0. Sanitization and validation are different: sanitization can change a value, but a returned value does not by itself prove the original input met the application’s rule. See the PHP Filter extension manual.
A small POST handler with field errors
This example checks a required name, email syntax, a bounded age, and a server-approved role. It preserves submitted values for the form, but escapes them when rendering. Replace the example role list and age range with the rules your application actually needs.
Rank #3
<?php
declare(strict_types=1);
$allowedRoles = ['reader', 'editor'];
$values = ['name' => '', 'email' => '', 'age' => '', 'role' => ''];
$errors = [];
$submitted = ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST';
if ($submitted) {
foreach ($values as $field => $_) {
$raw = $_POST[$field] ?? '';
$values[$field] = is_string($raw) ? trim($raw) : '';
}
if ($values['name'] === '') {
$errors['name'] = 'Enter your name.';
} elseif (mb_strlen($values['name'], 'UTF-8') > 100) {
$errors['name'] = 'Use 100 characters or fewer.';
}
if (filter_var($values['email'], FILTER_VALIDATE_EMAIL) === false) {
$errors['email'] = 'Enter an email address in a valid format.';
}
$age = filter_var($values['age'], FILTER_VALIDATE_INT);
if ($age === false || $age < 18 || $age > 120) {
$errors['age'] = 'Enter a whole number from 18 to 120.';
}
if (!in_array($values['role'], $allowedRoles, true)) {
$errors['role'] = 'Choose an available role.';
}
if ($errors === []) {
// Process validated values here, for example by calling application code.
// Do not build SQL by concatenating these values; use prepared statements.
$success = true;
}
}
function h(string $value): string {
return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
?>
<?php if (!empty($success)): ?>
<p>Your form was accepted.</p>
<?php else: ?>
<form method="post">
<label>Name
<input name="name" value="<?= h($values['name']) ?>" required maxlength="100">
</label>
<?php if (isset($errors['name'])): ?><p><?= h($errors['name']) ?></p><?php endif; ?>
<label>Email
<input type="email" name="email" value="<?= h($values['email']) ?>" required>
</label>
<?php if (isset($errors['email'])): ?><p><?= h($errors['email']) ?></p><?php endif; ?>
<label>Age
<input type="number" name="age" value="<?= h($values['age']) ?>" min="18" max="120" required>
</label>
<?php if (isset($errors['age'])): ?><p><?= h($errors['age']) ?></p><?php endif; ?>
<label>Role
<select name="role" required>
<option value="">Choose one</option>
<?php foreach ($allowedRoles as $role): ?>
<option value="<?= h($role) ?>"<?= $values['role'] === $role ? ' selected' : '' ?>><?= h($role) ?></option>
<?php endforeach; ?>
</select>
</label>
<?php if (isset($errors['role'])): ?><p><?= h($errors['role']) ?></p><?php endif; ?>
<button type="submit">Send</button>
</form>
<?php endif; ?>
The handler normalizes expected scalar inputs to strings before validation, so an unexpected array value does not reach string functions. It validates the age as an integer and then applies the range rule. The role check uses strict comparison against server-defined values. For dates, use an explicit expected format and also apply any business rule across fields; parsing one date does not establish that a range is sensible.
Show useful errors without creating a new vulnerability
When validation fails, keep safe values that help the person correct the form, associate each error with its field, and state what to change. Do not echo raw submitted text into the page or expose exception traces and internal implementation details in a user-facing error. The sample uses a small HTML-escaping helper for values and messages.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Validation is not the primary defense against cross-site scripting (XSS). Encode user-controlled data for the context where it is rendered. htmlspecialchars() with suitable flags and UTF-8 is appropriate for ordinary HTML text and quoted-attribute output, but it is not a universal sanitizer and does not make data safe inside JavaScript or every other context. The PHP manual documents htmlspecialchars(); OWASP explains why validation and context-sensitive output encoding are separate controls.
Likewise, form validation does not make database queries safe from SQL injection. Use parameterized queries rather than concatenating submitted text into SQL. These controls solve different problems and should be applied together where relevant.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Best Value
Add CSRF protection to state-changing forms
A valid set of fields does not prove that the user intentionally submitted the request. For authenticated state-changing actions, use a CSRF token or the application’s appropriate CSRF defense, and verify it on the server. Follow OWASP’s CSRF Prevention Cheat Sheet for token handling and related defenses. Validation answers whether values satisfy field rules; CSRF defenses address whether a request was forged.
Troubleshoot common validation mistakes
- Every value appears to pass: An unqualified
filter_var($value)usesFILTER_DEFAULT, which performs no filtering. Select a specific validation filter or apply explicit application rules. - Zero is reported as invalid: Avoid truthiness checks such as
if (!$value)when zero can be legitimate. Check failure with=== falsefor filters that return false on failure. - A valid choice is rejected or an invalid one accepted: Compare submitted select values against the server’s permitted list, using strict comparison and the expected input type.
- Names with accents or non-Latin characters fail: Review arbitrary ASCII-only rules. Preserve legitimate Unicode text and apply only field-specific constraints.
- A value looks harmless but the page executes markup: Validation is not output encoding. Escape at the point of output for the actual context; do not rely on input cleanup alone.
- Email syntax passes but messages bounce: Syntax does not establish mailbox existence or ownership. Use a confirmation link or code when ownership matters, and handle delivery failure in the workflow.
- Client checks work, but a crafted request bypasses them: Move the authoritative checks into the server handler. Browser validation is a usability aid, not a trust boundary.
Or skip the browser setup
Form validation itself belongs in your PHP application; a screenshot service does not validate submitted form data. If you also need a rendered screenshot of a page in a test or monitoring workflow, ScreenshotNeo is a website screenshot API and MCP server. One GET request can return a PNG, JPEG, WebP, or PDF. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Every feature is on every plan.
See the ScreenshotNeo documentation for API options. Example cURL request:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Frequently Asked Questions
Does filter_var() validate input if I omit the filter argument?
No. Its default filter is FILTER_DEFAULT, an alias of FILTER_UNSAFE_RAW, so no filtering takes place.
Does validating an email address prove that it belongs to the person submitting the form?
No. A syntax check is only an initial check; ownership requires a confirmation link or code when the workflow depends on it.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

