Using fetch_assoc on prepared statements (php mysq

2020-02-06 07:56发布

问题:

I'm currently working on a login script, and I got this code:

$selectUser = $db->prepare("SELECT `id`,`password`,`salt` FROM `users` WHERE `username`=?");
$selectUser->bind_param('s', $username);
$selectUser->execute();

if ($selectUser->num_rows() < 0)
    echo "no_user";
else
{
    $user = $selectUser->fetch_assoc();
    echo $user['id'];
}

Here's the error I get:

Fatal error: Uncaught Error: Call to undefined method mysqli_stmt::fetch_assoc()

I tried all sorts of variations, like:

$result = $selectUser->execute();
$user = $result->fetch_assoc();

and more... nothing worked.

回答1:

That's because fetch_assoc is not part of a mysqli_stmt object. fetch_assoc belongs to the mysqli_result class. You can use mysqli_stmt::get_result to first get a result object and then call fetch_assoc:

$selectUser = $db->prepare("SELECT `id`,`password`,`salt` FROM `users` WHERE `username`=?");
$selectUser->bind_param('s', $username);
$selectUser->execute();
$result = $selectUser->get_result();
$assoc = $result->fetch_assoc();

Alternatively, you can use bind_result to bind the query's columns to variables and use fetch() instead:

$selectUser = $db->prepare("SELECT `id`,`password`,`salt` FROM `users` WHERE `username`=?");
$selectUser->bind_param('s', $username);
$selectUser->bind_result($id, $password, $salt);
$selectUser->execute();
while($selectUser->fetch())
{
    //$id, $password and $salt contain the values you're looking for
}


回答2:

1) you need the mysqlInd driver.

The variable $db is of type mysqli_stmt, not mysqli_result. The mysqli_stmt class doesn't have a method fetch_assoc() defined for it.

You can get a mysqli_result object from your mysqli_stmt object by calling its get_result() method. For this you need the mysqlInd driver installed!

Alternative try this

    $selectUser = $db->prepare("SELECT `id`,`password`,`salt` FROM `users` WHERE `username`=?");
    $selectUser->bind_param('s', $username);

     $selectUser->execute();
    $selectUser->bind_result($id, $password,$salt);

    while ($selectUser->fetch()) {
        printf("%s %s %s\n", $id, $password,$salt);
    }

for more info about this Reference link



回答3:

Now talk of alternatives.

PDO, unlike mysqli, never have a problem like this. It can fetch you an array out of a prepared statement without the need of installing any additional modules.

$stmt = $db->prepare("SELECT `id`,`password`,`salt` FROM `users` WHERE `username`=?");
$stmt->execute([$username]);
$user = $stmt->fetch();

if (!$user) {
    echo "no_user";
} else {
    echo $user['id'];
}

See, it works exactly the way you would expect and require two times less code to write. Not to mention other wonderful features.