PHP
Prevent SQL Injection with PHP PDO Parameterized Queries
Learn to prevent critical SQL Injection vulnerabilities in PHP by using prepared statements and parameterized queries with PDO.
<?php
// Database connection details
$host = 'localhost';
$db = 'your_database_name';
$user = 'your_username';
$pass = 'your_password';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // Crucial for security
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
// echo "Connected successfully to the database.";
// --- Example: Preventing SQL Injection for a SELECT query ---
$userId = 1; // This could come from $_GET or $_POST
$stmt = $pdo->prepare("SELECT username, email FROM users WHERE id = :id");
$stmt->bindParam(':id', $userId, PDO::PARAM_INT);
$stmt->execute();
$user = $stmt->fetch();
// if ($user) {
// echo "
User: " . $user['username'] . ", Email: " . $user['email'];
// } else {
// echo "
User not found.";
// }
// --- Example: Preventing SQL Injection for an INSERT query ---
$username = 'newuser';
$email = '[email protected]';
// $passwordHash = password_hash('securepass', PASSWORD_DEFAULT); // Always hash passwords!
$stmt = $pdo->prepare("INSERT INTO users (username, email) VALUES (:username, :email)");
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
// $stmt->bindParam(':password', $passwordHash, PDO::PARAM_STR);
// $stmt->execute();
// echo "
New user added successfully (if uncommented).";
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>
How it works: This PHP snippet demonstrates the crucial practice of preventing SQL Injection using PDO (PHP Data Objects) with parameterized queries. Instead of directly concatenating user input into the SQL query, `prepare()` creates a statement with placeholders (e.g., `:id`, `:username`). `bindParam()` then safely binds the user-provided values to these placeholders, ensuring they are treated purely as data, not executable code. Setting `PDO::ATTR_EMULATE_PREPARES` to `false` further enhances security by forcing the database itself to prepare the statement.