Pergunta

I've got a query which I want to convert to use prepared statements, but I can't figure out how!

The code below is working code, but not safe because it's not using prepared statements. I want the function getUser to return the same result as it does now; can anyone tell me how to convert this?

$results = getUser('myUser@test.com');
foreach($results as $result) {
    echo $result['email'];
}
function getUser($email){
    $con = DBConnect();
    $result = mysqli_query($con,"SELECT * FROM tbl_appl_users WHERE email='".$email."'");
    $resultArray = array(); 
    while($row = mysqli_fetch_array($result)) {
        array_push($resultArray,$row);
    }
    return $resultArray;
    mysqli_close($con);
}

I know how to set up the prepared statement, but don't know how to process it. In the example code the query is requesting a single value but I want to get all values returned. The function as far as I got it is below:

function getUser($email){
    $con = DBConnect();
    $resultArray = array(); 
    if ($stmt = $con->prepare("SELECT * FROM tbl_appl_users WHERE email=?")) {
        $stmt->bind_param("s", $email);
        $stmt->execute();
        //$stmt->bind_result($district); // how to do this for a * result set.
        $stmt->fetch();
        while($row = mysqli_fetch_array($stmt)) {
            array_push($resultArray,$row);
        }
        //printf("%s is in district %s\n", $city, $district);
        $stmt->close();
    }
    return $resultArray;
    mysqli_close($con);
}
Foi útil?

Solução

I use MySQL PDO rather than MySQLi, but I've done some digging to show how I'd go about researching this. Here is the problematic method:

http://www.php.net/manual/en/mysqli-stmt.get-result.php

Several of the comments on that page refer to the same problem - MySQLi appears to want all columns to be bound to variables, which is a bit cumbersome if you are trying to write a generic routine. However one comment mentioned this:

http://php.net/manual/en/mysqli-stmt.bind-result.php

Aha! That reveals that you can now do the following, without having to bind output columns:

    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_array(MYSQLI_NUM))
    {
        foreach ($row as $r)
        {
            print "$r ";
        }
        print "\n";
    }

Give that a try?


From the comments, you discovered that get_result is not always available on shared hosting, as it requires the non-standard PHP module mysqlnd. In that case, you're either stuck with output column binding, or you can switch to PDO, which allows whole array rows/objects to be read.

Outras dicas

With the help of halfer, I came to the conclusion that rewriting with MySQL/PDO is much better.

function getUser($mail){
    $dsn = 'mysql:host=***;dbname=***';
    $dbh = new PDO($dsn, 'user', 'password');
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
    $stmt = $dbh->prepare('SELECT * FROM tbl_appl_users WHERE email=?');
    $stmt->bindParam(1, $mail);
    $stmt->execute();
    while ($row = $stmt->fetch()) {
        return $row;
    }           
    $dbh = null;
} 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top