I was using the following code to make a query with prepared statements: I used mysqli::prepare(), NOT mysqli_stmt::prepare(), so $res does not have to be initialized. It is returned by mysqli::prepared. php.net link
$sql2 = "INSERT INTO best_scores(`user_id`, `test_id`, `score`) VALUES(?, ?, ?)";
if($res = $db->prepare($sql2) == FALSE) echo $db->error . "
";
$res->bind_param("sii", $user_id, $_GET['test'], $max);
$res->execute();
$res->free_result();
When that code was reached, the following error appeared:
Call to a member function bind_param() on a non-object
I looked for answers but all the questions had mistakes in the SQL query string or they didn't free the previous results. None of them helped me, so I tried to change something. I changed my code into this:
$sql2 = "INSERT INTO best_scores(`user_id`, `test_id`, `score`) VALUES(?, ?, ?)";
$res = $db->stmt_init();
if($res->prepare($sql2) == FALSE) echo $db->error . "
";
$res->bind_param("sii", $user_id, $_GET['test'], $max);
$res->execute();
$res->free_result();
Now it is working. But why is it different? What was the problem with the first attempt?
Edit: My $db object is defined like this:
$db = new mysqli("localhost", "user", "pass", "database");
if($db->connect_errno > 0) {
die('Unable to connect to database [' . $db->connect_error . ']');
}
As we discuss it in the comments, it might be a wrong assignation in the if()
block.
What do I tested. If block, like yours:
$x = (object)array('a'=>'b');
if ($a = $x == false) {
echo 'a';
}
var_dump($a);
Output:
boolean false
Then I have put parentheses around the assignation:
$x = (object)array('a'=>'b');
if (($a = $x) == false) {
echo 'a';
}
var_dump($a);
Output:
object(stdClass)[1] public 'a' => string 'b' (length=1)
so you would need to put parentheses around the assignation for $res
if(($res = $db->prepare($sql2)) == FALSE)
Because your way, you wrongly reassign $res to FALSE
and the object has been lost
You're checking if your db->prepare worked in the first example and if it doesn't you use $res anyways, which is now not an object, because it wasn't initialized. In the second example you declare and initialize it first.
In the Docs:
mysqli_stmt_init — Initializes a statement and returns an object for use with mysqli_stmt_prepare
in you prev code you do not have initialized. in second code snippet after initialization it worked.