PHP
Implement Robust Server-Side Input Validation in PHP
Secure your PHP applications by implementing comprehensive server-side input validation, sanitizing and validating user data to prevent common vulnerabilities and ensure data integrity.
<?php
/**
* Validates and sanitizes user input for common web forms.
*
* @param array $data The raw input data, typically $_POST or $_GET.
* @return array An array containing 'errors' and 'validated_data'.
*/
function validateUserInput(array $data): array {
$errors = [];
$validated_data = [];
// --- Username Validation ---
if (empty($data['username'])) {
$errors['username'] = 'Username is required.';
} else {
// Sanitize username: remove HTML tags and trim whitespace
$username = trim(strip_tags($data['username']));
// Validate username: alphanumeric, 3-20 chars
if (!preg_match('/^[a-zA-Z0-9_]{3,20}$/', $username)) {
$errors['username'] = 'Username must be 3-20 characters long and contain only letters, numbers, or underscores.';
}
$validated_data['username'] = $username;
}
// --- Email Validation ---
if (empty($data['email'])) {
$errors['email'] = 'Email is required.';
} else {
// Sanitize email: remove all characters except letters, digits, and !#$%&'*+-=?^_`{|}~@.[]
$email = filter_var($data['email'], FILTER_SANITIZE_EMAIL);
// Validate email format
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'Invalid email format.';
}
$validated_data['email'] = $email;
}
// --- Password Validation ---
// Note: Password hashing should happen after validation, not as part of validation/sanitization here.
if (empty($data['password'])) {
$errors['password'] = 'Password is required.';
} else {
$password = $data['password']; // No sanitization for password, it will be hashed
// Validate password strength: min 8 chars, at least one uppercase, one lowercase, one number, one special char
if (strlen($password) < 8 ||
!preg_match('/[A-Z]/', $password) ||
!preg_match('/[a-z]/', $password) ||
!preg_match('/[0-9]/', $password) ||
!preg_match('/[^a-zA-Z0-9\s]/', $password)) {
$errors['password'] = 'Password must be at least 8 characters long and include uppercase, lowercase, number, and special character.';
}
$validated_data['password'] = $password; // Store unhashed for now, hash later
}
// --- Age Validation (example of numeric validation) ---
if (!empty($data['age'])) {
// Sanitize age: remove non-digit characters
$age = filter_var($data['age'], FILTER_SANITIZE_NUMBER_INT);
// Validate age: must be an integer between 18 and 120
if (!filter_var($age, FILTER_VALIDATE_INT, ['options' => ['min_range' => 18, 'max_range' => 120]])) {
$errors['age'] = 'Age must be an integer between 18 and 120.';
}
$validated_data['age'] = (int)$age;
}
return ['errors' => $errors, 'validated_data' => $validated_data];
}
// --- Example Usage ---
$post_data_example = [
'username' => 'test_user123',
'email' => '[email protected]',
'password' => 'StrongP@ssw0rd!',
'age' => '30'
];
$validation_result = validateUserInput($post_data_example);
if (empty($validation_result['errors'])) {
echo "Validation successful!
";
print_r($validation_result['validated_data']);
// Proceed to process data, e.g., hash password, save to database
} else {
echo "Validation failed:
";
print_r($validation_result['errors']);
}
echo "
--- Invalid Example ---
";
$invalid_data_example = [
'username' => 'ab', // Too short
'email' => 'invalid-email',
'password' => 'weak', // Too short, no special chars
'age' => '15' // Too young
];
$invalid_result = validateUserInput($invalid_data_example);
if (empty($invalid_result['errors'])) {
echo "Validation successful!
";
} else {
echo "Validation failed:
";
print_r($invalid_result['errors']);
}
?>
How it works: This PHP snippet provides a comprehensive function for server-side input validation and sanitization. It demonstrates validating common fields like username, email, and password using regular expressions (`preg_match`) and PHP's `filter_var` functions, which offer robust sanitization (e.g., `FILTER_SANITIZE_EMAIL`, `FILTER_SANITIZE_NUMBER_INT`) and validation (e.g., `FILTER_VALIDATE_EMAIL`, `FILTER_VALIDATE_INT`). Proper validation prevents malformed data, various injection attacks, and ensures data integrity before processing or storing user input.