Session 4.5 – PHP Filters
Module 4: Server-Side Scripting – PHP | Duration: 1 hr
Learning Objectives
By the end of this session, students will be able to:
- Understand the importance of input filtering and sanitization
- Use PHP filter functions for validation and sanitization
- Apply appropriate filters for different data types
- Implement custom filter validation
- Secure applications against injection attacks
- Combine filters for comprehensive data validation
Introduction to PHP Filters
PHP filters are used to validate and sanitize external input. They provide a secure way to handle user data and protect against injection attacks and invalid data.
Why Use Filters?
- Security: Prevent SQL injection, XSS, and other attacks
- Data Integrity: Ensure data meets expected format
- Consistency: Standardized validation across application
- Performance: Built-in functions are optimized
Filter Types
Validation Filters
Check if data meets certain criteria. Returns the value if valid, FALSE otherwise.
- FILTER_VALIDATE_BOOLEAN
- FILTER_VALIDATE_EMAIL
- FILTER_VALIDATE_FLOAT
- FILTER_VALIDATE_INT
- FILTER_VALIDATE_IP
- FILTER_VALIDATE_URL
- FILTER_VALIDATE_REGEXP
- FILTER_VALIDATE_DOMAIN
Sanitization Filters
Remove or encode unwanted characters. Returns the sanitized value.
- FILTER_SANITIZE_EMAIL
- FILTER_SANITIZE_ENCODED
- FILTER_SANITIZE_NUMBER_FLOAT
- FILTER_SANITIZE_NUMBER_INT
- FILTER_SANITIZE_SPECIAL_CHARS
- FILTER_SANITIZE_STRING
- FILTER_SANITIZE_URL
- FILTER_UNSAFE_RAW
Validation Filters
Email Validation
<?php
$email = "user@example.com";
// Basic validation
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Valid email address";
} else {
echo "Invalid email address";
}
// Check if email exists (additional validation)
function isValidEmail($email) {
// Validate format
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return false;
}
// Check domain has MX record
list($user, $domain) = explode('@', $email);
if (!checkdnsrr($domain, 'MX')) {
return false;
}
return true;
}
?>
URL Validation
<?php
$url = "https://www.example.com";
if (filter_var($url, FILTER_VALIDATE_URL)) {
echo "Valid URL";
} else {
echo "Invalid URL";
}
// Validate URL with specific protocol
$options = array(
'options' => array(
'default' => NULL,
'regexp' => '/^https:\/\/.*/' // Must start with https://
)
);
if (filter_var($url, FILTER_VALIDATE_REGEXP, $options)) {
echo "Valid HTTPS URL";
}
?>
Integer and Float Validation
<?php
// Integer validation
$age = "25";
if (filter_var($age, FILTER_VALIDATE_INT)) {
echo "Valid integer";
}
// Integer with range
$options = array(
'options' => array(
'min_range' => 18,
'max_range' => 120
)
);
if (filter_var($age, FILTER_VALIDATE_INT, $options)) {
echo "Valid age (18-120)";
}
// Float validation
$price = "19.99";
if (filter_var($price, FILTER_VALIDATE_FLOAT)) {
echo "Valid float";
}
// Float with decimal separator
$options = array(
'options' => array(
'decimal' => ',' // Accept comma as decimal separator
)
);
$price_eu = "19,99";
if (filter_var($price_eu, FILTER_VALIDATE_FLOAT, $options)) {
echo "Valid European price format";
}
?>
IP Address Validation
<?php
$ip = "192.168.1.1";
// Validate any IP address
if (filter_var($ip, FILTER_VALIDATE_IP)) {
echo "Valid IP address";
}
// Validate IPv4 only
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
echo "Valid IPv4 address";
}
// Validate IPv6 only
$ipv6 = "2001:0db8:85a3::8a2e:0370:7334";
if (filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
echo "Valid IPv6 address";
}
// Not private or reserved range
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
echo "Valid public IP address";
}
?>
Boolean Validation
<?php
// These return TRUE
$values = array("1", "true", "on", "yes");
foreach ($values as $value) {
var_dump(filter_var($value, FILTER_VALIDATE_BOOLEAN)); // bool(true)
}
// These return FALSE
$values = array("0", "false", "off", "no");
foreach ($values as $value) {
var_dump(filter_var($value, FILTER_VALIDATE_BOOLEAN)); // bool(false)
}
// NULL_ON_FAILURE flag
$result = filter_var("invalid", FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
var_dump($result); // NULL instead of FALSE
?>
Sanitization Filters
Sanitize Email
<?php
$email = "user(comment)@exa mple.com";
$clean_email = filter_var($email, FILTER_SANITIZE_EMAIL);
echo $clean_email; // user@example.com
// Remove all illegal characters
?>
Sanitize URL
<?php
$url = "https://www.example.com/<script>alert('xss')</script>";
$clean_url = filter_var($url, FILTER_SANITIZE_URL);
echo $clean_url; // https://www.example.com/scriptalert'xss'/script
// Removes all illegal characters from URL
?>
Sanitize Numbers
<?php
// Sanitize integer
$number = "123abc456";
$clean_int = filter_var($number, FILTER_SANITIZE_NUMBER_INT);
echo $clean_int; // 123456
// Sanitize float
$price = "$19.99 USD";
$clean_float = filter_var($price, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
echo $clean_float; // 19.99
// Allow decimal and thousand separator
$price = "1,234.56";
$clean = filter_var($price, FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND);
echo $clean; // 1,234.56
?>
Sanitize Special Characters
<?php
$text = "<script>alert('XSS')</script>";
// Encode special characters
$clean = filter_var($text, FILTER_SANITIZE_SPECIAL_CHARS);
echo $clean; // <script>alert('XSS')</script>
// This is similar to htmlspecialchars()
$clean2 = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
echo $clean2;
?>
Remove HTML Tags
<?php
$html = "<p>Hello <b>World</b><script>alert('xss')</script></p>";
// Remove all HTML tags
$clean = strip_tags($html);
echo $clean; // Hello World
// Allow specific tags
$clean = strip_tags($html, '<p><b>');
echo $clean; // <p>Hello <b>World</b></p>
?>
Filter Functions
filter_var() - Single Variable
<?php
// Basic usage
$email = "user@example.com";
$result = filter_var($email, FILTER_VALIDATE_EMAIL);
if ($result !== false) {
echo "Valid: $result";
} else {
echo "Invalid email";
}
?>
filter_input() - Get and Filter Input
<?php
// Get and validate from $_GET
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id !== false && $id !== null) {
echo "Valid ID: $id";
}
// Get and sanitize from $_POST
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
// With options
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, array(
'options' => array(
'min_range' => 0,
'max_range' => 120,
'default' => 0
)
));
// Available input types
// INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV
?>
filter_var_array() - Multiple Variables
<?php
// Define filters for multiple variables
$data = array(
'name' => 'John Doe',
'email' => 'john@example.com',
'age' => '25',
'website' => 'https://example.com'
);
$filters = array(
'name' => FILTER_SANITIZE_STRING,
'email' => FILTER_VALIDATE_EMAIL,
'age' => array(
'filter' => FILTER_VALIDATE_INT,
'options' => array('min_range' => 1, 'max_range' => 120)
),
'website' => FILTER_VALIDATE_URL
);
$result = filter_var_array($data, $filters);
// Check results
if ($result['email'] === false) {
echo "Invalid email";
}
if ($result['age'] === false) {
echo "Invalid age";
}
?>
filter_input_array() - Get Multiple Inputs
<?php
// Define filters for $_POST data
$filters = array(
'username' => FILTER_SANITIZE_STRING,
'email' => FILTER_SANITIZE_EMAIL,
'age' => array(
'filter' => FILTER_VALIDATE_INT,
'flags' => FILTER_REQUIRE_SCALAR,
'options' => array('min_range' => 18, 'max_range' => 100)
)
);
// Filter all $_POST variables
$result = filter_input_array(INPUT_POST, $filters);
// Validate results
$errors = array();
if (!filter_var($result['email'], FILTER_VALIDATE_EMAIL)) {
$errors[] = "Invalid email";
}
if ($result['age'] === false || $result['age'] === null) {
$errors[] = "Invalid age";
}
if (empty($errors)) {
echo "All inputs valid";
} else {
foreach ($errors as $error) {
echo $error . "<br>";
}
}
?>
Practical Examples
Complete Registration Form Validation
<?php
// register.php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Define filters
$filters = array(
'username' => array(
'filter' => FILTER_CALLBACK,
'options' => function($value) {
$value = trim($value);
if (strlen($value) < 3 || strlen($value) > 20) {
return false;
}
if (!preg_match('/^[a-zA-Z0-9_]+$/', $value)) {
return false;
}
return $value;
}
),
'email' => FILTER_VALIDATE_EMAIL,
'age' => array(
'filter' => FILTER_VALIDATE_INT,
'options' => array('min_range' => 18, 'max_range' => 120)
),
'website' => array(
'filter' => FILTER_VALIDATE_URL,
'flags' => FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED
),
'agree_terms' => FILTER_VALIDATE_BOOLEAN
);
// Filter inputs
$inputs = filter_input_array(INPUT_POST, $filters);
// Validation
$errors = array();
if ($inputs['username'] === false || $inputs['username'] === null) {
$errors['username'] = "Username must be 3-20 alphanumeric characters";
}
if ($inputs['email'] === false) {
$errors['email'] = "Invalid email address";
}
if ($inputs['age'] === false || $inputs['age'] === null) {
$errors['age'] = "Age must be between 18 and 120";
}
if (isset($inputs['website']) && !empty($_POST['website']) && $inputs['website'] === false) {
$errors['website'] = "Invalid website URL";
}
if (!$inputs['agree_terms']) {
$errors['agree_terms'] = "You must agree to the terms";
}
// Process if no errors
if (empty($errors)) {
// Sanitize for display/storage
$clean_username = htmlspecialchars($inputs['username'], ENT_QUOTES, 'UTF-8');
$clean_email = htmlspecialchars($inputs['email'], ENT_QUOTES, 'UTF-8');
// Save to database (use prepared statements!)
echo "Registration successful!";
} else {
// Display errors
foreach ($errors as $field => $error) {
echo "<div class='alert alert-danger'>$error</div>";
}
}
}
?>
Search Form with Sanitization
<?php
// search.php
$search = filter_input(INPUT_GET, 'q', FILTER_SANITIZE_STRING);
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
'options' => array('min_range' => 1, 'default' => 1)
));
$category = filter_input(INPUT_GET, 'category', FILTER_SANITIZE_STRING);
// Additional validation
if (strlen($search) > 100) {
$search = substr($search, 0, 100);
}
// Remove extra whitespace
$search = preg_replace('/\s+/', ' ', trim($search));
// Escape for display
$safe_search = htmlspecialchars($search, ENT_QUOTES, 'UTF-8');
echo "Searching for: $safe_search";
echo "Page: $page";
// Use in database query with prepared statements
// $stmt = $pdo->prepare("SELECT * FROM products WHERE name LIKE ? LIMIT ?, 20");
// $stmt->execute(["%$search%", ($page - 1) * 20]);
?>
Custom Filter Callback
<?php
// Custom validation function
function validatePhone($phone) {
// Remove formatting
$phone = preg_replace('/[^0-9]/', '', $phone);
// Check length
if (strlen($phone) != 10) {
return false;
}
// Format as (XXX) XXX-XXXX
return sprintf("(%s) %s-%s",
substr($phone, 0, 3),
substr($phone, 3, 3),
substr($phone, 6)
);
}
// Use custom filter
$phone = filter_input(INPUT_POST, 'phone', FILTER_CALLBACK, array(
'options' => 'validatePhone'
));
if ($phone === false) {
echo "Invalid phone number";
} else {
echo "Formatted phone: $phone";
}
?>
Session Summary
Key Points
- PHP filters provide built-in validation and sanitization functions
- Validation filters check if data meets criteria (returns value or FALSE)
- Sanitization filters remove or encode unwanted characters
- filter_var() filters a single variable
- filter_input() gets and filters external input directly
- filter_var_array() and filter_input_array() handle multiple values
- Custom callbacks can be used for complex validation logic
- Always combine filters with proper error handling and security practices
Next Session Preview
In the next session, we will explore Error Handling and Exceptions in PHP, learning how to gracefully handle errors and implement robust error management in our applications.