Search code examples
phpmysqlsqlmysqlisql-injection

Prepared statements not working in PHP


I am currently trying to prevent SQL injection with prepared statements, but every time I try to load this code it is failing, what am I doing wrong?

<?php
$mysqli = new mysqli("127.0.0.1", "root", "root", "Database", 3306);
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

$stmt = $mysqli->prepare('SELECT * FROM `Users`');
$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    echo $row[0] . "<br>";
}
/* close statement */
$stmt->close();

/* close connection */
$mysqli->close();
?>

Solution

  • With a prepared statement you should bind the results like the following:

        $stmt = $mysqli->prepare('SELECT * FROM `Users`')) {
        $stmt->execute();   
        $stmt->store_result();
        $stmt->bind_result($param1, $param2...);
        $stmt->fetch();
    

    Unfortunately $stmt->bind_param() does not accept params array

    So you can fetch them with something like this:

    $stmt->execute();   
    $stmt->store_result();
    $rows = $stmt->num_rows;
    $meta = $stmt->result_metadata(); 
    
        while ($field = $meta->fetch_field()) 
        { 
            $params[] = &$row[$field->name]; 
        }
    call_user_func_array(array($stmt, 'bind_result'), $params); 
    while ($stmt->fetch()) { 
        foreach($row as $key => $val) 
        { 
            $c[$key] = $val; 
        } 
        $result[] = $c; 
    } 
    
    $stmt->close(); 
    

    The array $result will contain the result you need.