Jump to content

Recommended Posts

Hi all

 

I cannot seem to get the following code to work correctly.

 

Basically I have created a new mysqli() and stored this in a variable called $myCon.

 

I then pass this variable by reference so I can use the same connection into the functions.

 

The first query runs fine but queries after the first one dont work and I get the following error message:

 

Fatal error: Call to a member function bind_param() on a non-object

 


$myCon = new mysqli('localhost', 'surname', 'pass', 'dbHere');

signIn(&$myCon); ----- referenced as the $myCon var is stored in a different PHP file and included




function signIn($Con)
{
$username = $_POST['username'];
$password = $_POST['password'];

$sql = "call sp_checkLoginDetails(?, ?)";
$stmt = $Con->prepare($sql);
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows != 1)
{
$error = "<div id=\"formMessages\">Username or Password is incorrect. Please try again.</div>";

if($username == "username...")
{
$username = "";
}
}
else
{
$stmt->bind_result($userID, $firstNme);
while($row = $stmt->fetch())
{
$_SESSION['usrID'] = $userID;
$_SESSION['firstName'] = $firstNme;
}
$_SESSION['isLoggedIn'] = true;
$stmt->close();
$sql = "call sp_updateLoginDateTime(?)";
$stmt = $Con->prepare($sql);
$stmt->bind_param('s', $_SESSION['usrID']); ----- this is where it gets the error
$stmt->execute();
header("Location: .");
die();}}


Edited by mds1256
Link to comment
https://forums.phpfreaks.com/topic/272335-mysqli-prepared-statements-problem/
Share on other sites

If I create a new mysqli object just below the last stmt->close then it works so I am guessing that the mysqli object is being closed / destroyed and will not allow further queries to be ran.

 

Why is this happening and is there a way around it.

Do you have php's error_reporting set to E_ALL, so that more than just fatal runtime errors will be reported, and you need to test if your database statements are failing or not before using the result from one statement in the next to prevent follow-on errors, and to report/display/log your own application errors when a statement does fail so that you can find and fix the problem. Your ->prepare() statement is failing, but you have no error checking/error reporting/logging logic in your code to get your code to tell you why.

 

The ->prepare() method will return a false value if it fails. You need to test for that and if it is false, the $Con->error property will contain the error that occurred for the ->prepare() statement.

I believe the error_reporting is set to E_ALL in the php.ini

 

ok here is the code with a little error checking.

 

The error I get is: Commands out of sync; you can't run this command now

 

               $username = $_POST['username'];
 $password = $_POST['password'];

 $sql = "call sp_checkLoginDetails(?, ?)";
 $stmt = $Con->prepare($sql);
 if($stmt)
 {
  $stmt->bind_param('ss', $username, $password);
  $stmt->execute();
  $stmt->store_result();
  if($stmt->num_rows != 1)
  {
   $error = "<div id=\"formMessages\">Username or Password is incorrect. Please try again.</div>";

   if($username == "username...")
   {
 $username = "";
   }
   $stmt->close();
  }
  else
  {
   $stmt->bind_result($userID, $firstNme);
   while($row = $stmt->fetch())
   {
 $_SESSION['usrID'] = $userID;
 $_SESSION['firstName'] = $firstNme;
   }
   $_SESSION['isLoggedIn'] = true;
   $stmt->close();
   $sql = "call sp_updateLoginDateTime(?)";
   $stmt = $Con->prepare($sql);
   if($stmt)
   {
 $stmt->bind_param('s', $_SESSION['usrID']);
 $stmt->execute();
 $stmt->close();
 header("Location: .");
 die();
   }
   else
   {
 echo $Con->error;
   }


  }

 }
 else
 {
  echo $Con->error;
 }

Having read a little more about this problem it seems that you need to return all results before a 2nd query can run as it blocks the connection (hence why If I create a new db connection it will work).

 

see: https://bugs.php.net/bug.php?id=54444

 

So I tried the $stmt->get_result();

 

BUT my web host doesnt have the mysqld (native driver) and will not support this.

 

Is there any work around for this, plenty people are using prepared statements, someone must have came across this issue?

Edited by mds1256

Further developments....

 

It seems that this works when not calling mysql stored procedures but when you are you have to call: $Con->next_result();

 

This clears the result set even if there are no further results.

 

http://www.php.net/manual/en/mysqli.query.php#102904

Yes, a mySql stored procedure returns two "results sets". So you have to call next_result to "clear the pipe", so to speak, and allow other data to come through. If you look at mysqli.multi-query the examples show one way to do it (generically). Basically, you can call $con->more_results() to see if there is more; and call $con->next_result() to get the "more results".

 

I'm not sure how this is impacted by prepared statements, I haven't tried it that way.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.