Secure PHP Application Development: Best Practices for Input Validation and Sanitization
PHP applications often receive input from various sources, including form submissions, query strings, and API requests. Without proper validation and sanitization, this input can be exploited to compromise the integrity and security of your application. This article explains how to handle user input securely, using modern PHP practices and secure coding techniques.
Input Validation and Sanitization in PHP
1. Understanding Input Sources
In PHP, input can come from multiple sources, such as:
| Source | Example |
|---|---|
$_GET | http://example.com?search=php |
$_POST | Form submissions |
$_COOKIE | Browser cookies |
$_SERVER | Server and execution environment |
file_get_contents() | Reading from files or URLs |
Each source must be treated with care, as they can contain malicious data.
2. Validating Input with filter_var()
PHP provides the filter_var() function to validate and sanitize input. It supports multiple filters, including:
FILTER_VALIDATE_EMAILFILTER_VALIDATE_URLFILTER_VALIDATE_INTFILTER_SANITIZE_STRING
Example:
$email = $_POST['email'];
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Valid email address.";
} else {
echo "Invalid email address.";
}
3. Sanitizing Input with filter_var()
Sanitization removes potentially harmful characters from input. For example, FILTER_SANITIZE_STRING removes or encodes special characters:
$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
echo "Hello, " . htmlspecialchars($name);
4. Using htmlspecialchars() for Output
When displaying user input, always use htmlspecialchars() to prevent XSS attacks:
$user_input = $_GET['comment'];
echo "<p>" . htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8') . "</p>";
5. Validating and Sanitizing Arrays
If your application receives arrays (e.g., from $_GET or $_POST), you can loop through them and apply filters:
$tags = $_POST['tags'] ?? [];
$validated_tags = array_map(function($tag) {
return filter_var($tag, FILTER_SANITIZE_STRING);
}, $tags);
6. Using filter_list() to Check Available Filters
You can list all available filters using filter_list():
$filters = filter_list();
print_r($filters);
7. Custom Validation with filter_var() and Callbacks
For more complex validation, use the FILTER_CALLBACK filter:
function validate_username($username) {
return preg_match('/^[a-zA-Z0-9_]{3,20}$/', $username);
}
$username = filter_var($_POST['username'], FILTER_CALLBACK, ['options' => 'validate_username']);
if ($username === false) {
echo "Invalid username.";
}
Best Practices Summary
| Practice | Description |
|---|---|
| Always validate input | Check for expected data types and formats |
| Sanitize output | Use htmlspecialchars() or similar functions |
| Avoid direct user input in queries | Use prepared statements instead of concatenating strings |
| Use built-in functions | Leverage filter_var() and filter_list() |
| Validate and sanitize arrays | Apply filters to each element in an array |
| Use callbacks for custom logic | For complex validation scenarios |