PHP
Robust Server-Side Input Validation and Sanitization in PHP
Implement comprehensive server-side input validation and sanitization in PHP to prevent various vulnerabilities like injection and data corruption from malicious user input.
<?php
/**
* Validates and sanitizes user input for security and data integrity.
* @param array $inputData The associative array of user input (e.g., $_POST).
* @return array An array containing validated and sanitized data, and an array of errors.
*/
function validateAndSanitizeInput(array $inputData): array {
$validatedData = [];
$errors = [];
// 1. Validate 'name' field: Required, string, max 100 chars, allow spaces and hyphens.
if (empty($inputData['name'])) {
$errors['name'] = 'Name is required.';
} else {
$name = trim($inputData['name']);
if (!preg_match('/^[a-zA-Z\s\-]+$/', $name)) {
$errors['name'] = 'Name can only contain letters, spaces, and hyphens.';
} elseif (strlen($name) > 100) {
$errors['name'] = 'Name cannot exceed 100 characters.';
} else {
$validatedData['name'] = htmlspecialchars($name, ENT_QUOTES, 'UTF-8'); // Basic output escaping
}
}
// 2. Validate 'email' field: Required, valid email format.
if (empty($inputData['email'])) {
$errors['email'] = 'Email is required.';
} else {
$email = trim($inputData['email']);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'Invalid email format.';
} else {
$validatedData['email'] = filter_var($email, FILTER_SANITIZE_EMAIL); // Specific sanitization
}
}
// 3. Validate 'age' field: Optional, integer, between 18 and 120.
if (!empty($inputData['age'])) {
$age = filter_var($inputData['age'], FILTER_VALIDATE_INT, [
'options' => [
'min_range' => 18,
'max_range' => 120
]
]);
if ($age === false) {
$errors['age'] = 'Age must be an integer between 18 and 120.';
} else {
$validatedData['age'] = $age;
}
}
// 4. Validate 'website' field: Optional, valid URL, sanitize URL.
if (!empty($inputData['website'])) {
$website = trim($inputData['website']);
if (!filter_var($website, FILTER_VALIDATE_URL)) {
$errors['website'] = 'Invalid URL format.';
} else {
$validatedData['website'] = filter_var($website, FILTER_SANITIZE_URL);
}
}
// Generic string sanitation for other inputs if needed (example 'message')
if (!empty($inputData['message'])) {
$validatedData['message'] = htmlspecialchars(trim($inputData['message']), ENT_QUOTES, 'UTF-8');
}
return ['data' => $validatedData, 'errors' => $errors];
}
// --- Usage Example ---
// Simulate incoming POST data
$_POST = [
'name' => 'John Doe',
'email' => '[email protected]',
'age' => '30',
'website' => 'https://www.example.com/page?id=123',
'message' => '<script>alert("XSS!");</script>Hello World!'
];
$result = validateAndSanitizeInput($_POST);
if (empty($result['errors'])) {
echo "Validation successful!
";
print_r($result['data']);
} else {
echo "Validation failed!
";
print_r($result['errors']);
}
// Example with invalid data
$_POST = [
'name' => 'John <script>',
'email' => 'invalid-email',
'age' => '10',
'website' => 'not-a-url',
];
echo "
--- Testing with Invalid Data ---
";
$invalidResult = validateAndSanitizeInput($_POST);
if (empty($invalidResult['errors'])) {
echo "Validation successful! (This should not happen)
";
} else {
echo "Validation failed as expected!
";
print_r($invalidResult['errors']);
}
How it works: Server-side input validation and sanitization are crucial for protecting against various attacks, including SQL Injection, XSS (Cross-Site Scripting), and more. This PHP snippet demonstrates a robust approach by combining `filter_var` for common types like emails and URLs, and regular expressions (`preg_match`) for custom string patterns. It first validates the input against expected formats and ranges, then sanitizes it (e.g., removing HTML tags, encoding special characters) to ensure that only safe and correctly formatted data is processed or stored. It also includes basic `htmlspecialchars` for data that will be output, which is a good practice for XSS prevention when displaying user-generated content.