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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs