Get_result() working in php7.4 but in php8 I get an error "Call to undefined method mysqli_stmt::get_result()"

Hi,
I have the code below:

  $stmt=$dbc->prepare("SELECT user_id, first_name, last_name, pass FROM users WHERE email=? ") ; 
  $stmt->bind_param('s', $e);          
  $stmt->execute();          
  if ($stmt->error){echo "something has gone wrong";} 
  $r=$stmt->get_result();                                
  $row = mysqli_fetch_array ( $r, MYSQLI_ASSOC ) ;

as part of a login script. Running this in PHP7.4 it works without problem. But if I change the PHP version to 8 the script halts and I get the error

Call to undefined method mysqli_stmt::get_result() 

referring to the line

  $r=$stmt->get_result();  

I have run the code through a PHP syntax checker and it shows no errors. https://www.php.net/manual/en/mysqli-stmt.get-result shows the method as being in both PHP7 and PHP8.

So what am I missing here? Any help/thoughts/pointers gratefully received - thank you. If you need me to post more code then let me know.

Try adding the following at the start of the page and hopefully more error information will be shown:

<?php declare(strict_types=1);
error_reporting(-1);
ini_set(‘display_errors’, ‘true’);

Edit:

Also from the online PHP Manual it appears the function name has changed:

$result = mysqli_stmt_get_result($stmt);

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

get_result is only available when php is actually using the msyqlnd driver to connect with the database server. This requires php to be built to use the msyqlnd driver with the MySql database extensions and that the mysqlnd driver is enabled and working. If these conditions are not met, things like mysqli’s get_result, fetch_all, … don’t exist and won’t work.

This would be a good time to switch the much simpler and more consistent PDO extension. It has no gotya’s like this. You would also want to switch to using exceptions for errors and set the default fetch mode to assoc when the database connection is made.

Using PDO, the posted code would simply become -

// note: building your sql query in a php variable aids debugging and reduces typing errors by separating the sql syntax from the php syntax as much as possible
$sql = "SELECT user_id, first_name, last_name, pass FROM users WHERE email=?";
$stmt=$pdo->prepare($sql);
$stmt->execute([$e]);
$row = $stmt->fetch();
2 Likes

My “to do” list includes changing everything to PDO.

But what I don’t understand is that the code works with PHP 7.4 but not PHP8 (I change these in cPanel)

That worked, except I had to change the penultimate line to

$stmt->execute();

Now I need to alter the page further down - time to learn some more stuff - thank you.

Edit - just realised that I shouldn’t have made the alteration I did. Think I need sleep and a fresh look. Thank you.

OMG! The page I saw still had it the same for php7 and php8!

Hmm. I may have misunderstood here. I altered the code to:

  $stmt=$dbc->prepare("SELECT user_id, first_name, last_name, pass FROM users WHERE email=? ") ; 
  $stmt->bind_param('s', $e);          
  $stmt->execute();          
  if ($stmt->error){echo "something has gone wrong";} 
  $r=mysqli_stmt_get_result($stmt);                                
  $row = mysqli_fetch_array ( $r, MYSQLI_ASSOC ) ;
 
**Fatal error** : Uncaught Error: Call to undefined function mysqli_stmt_get_result() in /home/onadbzxi/public_html/rotacreator/login_tools.php:72 Stack trace: #0 /home/onadbzxi/public_html/rotacreator/login_action.php(12): validate() #1 {main} thrown in **/home/onadbzxi/public_html/rotacreator/login_tools.php** on line **72**

(login_tools.php contains a function “validate”.
login_action.php requires login_tools.php.
login.php contains a form whose action is login_action.php)

I agree with the confusion.

Take a look at the two examples:

  1. Example #1 Object-oriented style
  2. Example #2 Procedural style

The Object Oriented script uses get_result(); but the Procedural Script does not :frowning:

1 Like

PHP8 also supports it, if it has been compiled using mysqlnd. It appears your host didn’t do that. Nothing to be done about that on your end.

Your options:

  • ask your host to recompile PHP8 using mysqlnd
  • switch to a different host
  • switch to PDO instead of MySQLi
1 Like

Excellent and clear reply - thank you. I get it now.

So what I think I will do now is revert to php7.4 while I learn how to use PDO and recode my sites accordingly.

Thank you.

There’s not much to learn.

After you make a connection using PDO -

  1. The use a the ? prepared query place-holder is the same.
  2. Calling the ->prepare() method is the same.
  3. Instead of explicitly using the mysqli’s bind_param() method, you supply an array of the input values to the ->execute([…]) call.
  4. If you are using the last insert id or number of affected rows, there are equivalent PDO calls.
  5. For both a prepared and non-prepared SELECT query, you directly fetch data using either the ->fetch() method (one row), the ->fetchAll() method (all rows), or occasionally the ->fetchColumn() method (a specific column from a row.)
  6. After you have fetched the data into a php variable, the rest of your code using that data should remain the same. If you are not already using this design pattern, which separates your database specific code from your presentation code, this would be a good time to make this change, so that if you ever need to change the database specific code again, you won’t need to touch your presentation code.
1 Like

Thank you.

The process I adopted to convert to PDO was to create functions, move the existing MySqli script and return a result. I found Database scripts confusing because they can and often return bool results. To simplify the results individual functions were created to accept the SQL statements and return a specific value. Functions were named similar to the following:

  • getPdoArray($sql);
  • getPdoObject($sql);
  • getPdoInteger($sql);

Similar functions created for MySqli scripts.

If you are not aware of the following site related to PDO it is worth bookmarking because it has detailed descriptions and also many good examples.

https://phpdelusions.com/

1 Like

Thank you. I had previously bookmarked https://phpdelusions.net/pdo as recommended previously here and am actually reading it now.

1 Like

Alternatively, you could use something like Doctrine DBAL which makes things a bit more consistent and would make it easier to switch from PDO to the next thing, should that ever come along.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.