Current Location: Home> Latest Articles> How to Effectively Prevent SQL Injection Attacks when Using PDOStatement::fetchAll for Queries

How to Effectively Prevent SQL Injection Attacks when Using PDOStatement::fetchAll for Queries

M66 2025-06-28

What is SQL Injection?

SQL injection refers to an attack where the attacker inserts malicious SQL code into an SQL query to steal, modify data, or even take control of the database server. For example, if a developer directly concatenates user input into an SQL query, an attacker could input specific SQL code to modify the query logic.

For instance, consider the following query:

$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";

If the attacker enters the following as their username or password:

  • Username: ' OR '1'='1

  • Password: ' OR '1'='1

The query would then become:

SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '' OR '1'='1';

This bypasses normal authentication, allowing the attacker to easily access sensitive data. To prevent this, we can use parameterized queries (Prepared Statements) to protect the application from SQL injection attacks.


Preventing SQL Injection with PDO

PDO provides a powerful mechanism to prevent SQL injection, namely prepared statements. With prepared statements, user inputs in queries are treated as parameters, not part of the SQL code itself. This ensures that even if a user enters malicious SQL, the database will not execute it.

1. Connecting to the Database with PDO

First, you need to connect to the database using PDO. Ensure that exceptions are enabled when creating the connection for better error debugging.

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo "Database connection failed: " . $e->getMessage();
}

2. Using Prepared Statements for Queries

PDO’s prepared statements not only prevent SQL injection, but they also improve query performance, especially when executing the same type of query multiple times.

Assume we have a query that retrieves user data based on the username. We can use the following code:

$sql = "SELECT * FROM users WHERE username = :username";
$stmt = $pdo->prepare($sql);
<p>// Bind parameters<br>
$stmt->bindParam(':username', $username, PDO::PARAM_STR);</p>
<p>// Execute query<br>
$stmt->execute();</p>
<p>// Get query results<br>
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);</p>
<p>// Output results<br>
foreach ($results as $row) {<br>
echo "Username: " . $row['username'] . "<br>";<br>
echo "Email: " . $row['email'] . "<br>";<br>
}<br>

In the above code, :username is a placeholder, and the user input for username is bound to the placeholder via the bindParam method. This approach ensures that no matter what the user inputs, it is passed as a parameter to the database rather than being directly concatenated into the SQL query, effectively preventing SQL injection.

3. Using fetchAll to Retrieve Results

The PDOStatement::fetchAll method returns the query results as an array, which is especially useful when retrieving multiple rows of data. In the above code, fetchAll(PDO::FETCH_ASSOC) returns the results as an associative array, where each element corresponds to a data row.

If you wish to retrieve all query results, you can use the following method:

$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

If you only need a single row of results, use the fetch method, but if you need multiple rows, fetchAll is a good choice.

4. Considerations When Using URL Parameters

When handling user inputs, especially URL parameters, you should always use prepared statements. For instance, if a URL contains an id parameter, avoid directly concatenating it into the SQL statement. Instead, pass it through a prepared statement.

Suppose the URL passes an id parameter; you can perform a secure query as follows:

$id = $_GET['id'];  // Get the id parameter from the URL
<p>$sql = "SELECT * FROM users WHERE id = :id";<br>
$stmt = $pdo->prepare($sql);</p>
<p>// Bind parameter<br>
$stmt->bindParam(':id', $id, PDO::PARAM_INT);</p>
<p>// Execute query<br>
$stmt->execute();</p>
<p data-is-last-node="" data-is-only-node="">// Get query results<br>
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);<br>
  • Related Tags:

    SQL