1

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 . "\n"; $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 . "\n"; $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 . ']'); } 
1
  • can we see how your $db object is declared Commented Jan 27, 2014 at 11:50

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

1 Comment

You're right. I put the parentheses and the first version works. I also checked here: php.net/manual/en/language.operators.precedence.php, and the == operator has higher priority than =. Thank you!!
1

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.

7 Comments

It's true, but isn't the assignation done, no matter whether true/false $res = ... is
Where's the $db->stmt_init(); in the first example?
I was confused between php.net/manual/en/mysqli.prepare.php and php.net/manual/en/mysqli-stmt.prepare.php in the first one there was no need of init
There is no need for stmt_init(). The mysqli_stmt object is returned by mysqli::prepare().
@Sorin true, I first thought this, but then confused myself which one returns the actual needed object. However, after the if() statement, what does var_dump($res) saying? If the assignation in the if is done, maybe later the prepare fails, or not build the proper object
|
1

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.

Link: http://www.php.net/manual/en/mysqli.stmt-init.php

12 Comments

He does have $res = $db->prepare($sql2) which according to prepare docs (if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {) is ok?
if you see this link on php site php.net/manual/en/mysqli-stmt.prepare.php they first have initialized. prepare is used after initialization.
Right, I did not see this at first time. Sorry about it
I was looking here php.net/manual/en/mysqli.prepare.php where no need of init was mentioned
I did not use mysqli_stmt::prepare(), but mysqli::prepare(), which returns a mysqli_stmt object. This way, no initialization is needed. I edited the post and put a link there.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.