Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call to undefined method mysqli_stmt::get_result() when mysqlnd is not available #967

Closed
AndrewPixel opened this issue May 7, 2023 · 16 comments · Fixed by #971
Closed
Assignees
Labels
bug mysqli MySQL and compatible drivers (MariaDB, etc) (Tier 1)
Milestone

Comments

@AndrewPixel
Copy link

AndrewPixel commented May 7, 2023

Description

I can no longer connect to the db.

Environment

  • ADOdb version: 5.22.5
  • Driver or Module: mysqli
  • Database type and version: mySQL
  • PHP version: 8

Steps to reproduce

Attempt to connect to the db with

$type = "mysqli";
$db = ADONewConnection($type);
$db->connect("s131.fred.hostingplatform.net", "fred_user", "fred_pwd", "fred_db");

I get this error:

mysqli_query(): Argument #1 ($mysql) must be of type mysqli, bool given at /home/fred/public_html/Decide.It/upload/adodb/drivers/adodb-mysqli.inc.php:1372

Expected behaviour

A successful connection is made.

Additional context

I develop locally using IIS and it works as expected but when I upload the same code (which works with earlier versions of ADOdb) it fails.

@AndrewPixel AndrewPixel added the triage New issues not yet reviewed by ADOdb developers label May 7, 2023
@dregad dregad added question no change required and removed triage New issues not yet reviewed by ADOdb developers labels May 7, 2023
@dregad
Copy link
Member

dregad commented May 7, 2023

If the code works locally but not on your server, that rules out the problem being caused by a bug in ADOdb.

For the record: the provided code snippet does not allow to reproduce the problem - ADODB_mysqli::connect() does not call mysql_query().

The problem is almost certainly caused by an unsuccessful connection (your $db->connect() call fails), so the $_connectionId is false. You should check the method's return value before continuing with your code
You can also set $db->debug = true; before, ADOdb will print an error message that will help you troubleshoot.

@dregad dregad closed this as not planned Won't fix, can't repro, duplicate, stale May 7, 2023
@AndrewPixel
Copy link
Author

I turned on debug and got "Could not connect : Access denied for user..."

Thank you for taking the time to help.

In my code I've wrapped the call to connect in a try/catch expecting it to throw an error if it didn't connect (which it didn't)

try {
$type = "mysqli";
$db = ADONewConnection($type);
$db->connect("s131.fred.hostingplatform.net", "fred", "rhy.ES", "fred_db");
} catch (\Throwable $t) {
echo "Error: " . $t->getMessage(), " at ", $t->getFile(), ":", $t->getLine(), "\n";
}

Instead, is the right way to do this to immediately check for a successful connection?

@dregad
Copy link
Member

dregad commented May 8, 2023

@AndrewPixel
Copy link
Author

For testing, I've simplified the code to:

include 'adodb/adodb.inc.php';

$type = "mysqli";
$db = ADONewConnection($type);
$db->connect("s131.fred.hostingplatform.net", "fred_user", "rhyfredES", "fred_db");
$db->EXECUTE("set names 'utf8mb4'");

if (!$db->isConnected()) die('Error: NO!');

$bindVars = array($email);
$sql = "SELECT user FROM admin WHERE email=?";
$rs = $db->Execute($sql, $bindVars);

and I get this in the console at the Execute:

Fatal error: Uncaught Error: Call to undefined method mysqli_stmt::get_result() in /home/fred/public_html/tool/upload/adodb/drivers/adodb-mysqli.inc.php:1340
Stack trace:
#0 /home/fred/public_html/tool/upload/adodb/adodb.inc.php(1613): ADODB_mysqli->_query()
#1 /home/fred/public_html/tool/upload/adodb/drivers/adodb-mysqli.inc.php(1153): ADOConnection->_Execute()
#2 /home/fred/public_html/tool/upload/login.php(37): ADODB_mysqli->execute()
#3 /home/fred/public_html/tool/upload/login.php(249): include('/home/fred/...')
#4 {main}
thrown in /home/fred/public_html/tool/upload/adodb/drivers/adodb-mysqli.inc.php on line 1340

So it seems it's connecting to the database but failing when it tries to query it. Sadly I don't know how to go about resolving this. Any help would be appreciated.

@AndrewPixel
Copy link
Author

I just now replaced ADOdb 5.22.5 with the legacy release 5.21.4 and now everything works as expected!

I've no idea why 5.22.5 errors on the production server.

@dregad
Copy link
Member

dregad commented May 9, 2023

Aha, now that's interesting ! I think we're on to something...

The ADOdb mysqli driver changed significantly in 5.22 (see #655), to use true prepared statements. This happens here:

$stmt = $this->_connectionID->prepare($sql);

and then we use get_results() on the prepared statement

// Turn the statement into a result set and return it
return $stmt->get_result();
but according to the documentation, the method is only available with mysqlnd.

So can you check whether that is installed on your production server ?

@dregad dregad reopened this May 9, 2023
@AndrewPixel
Copy link
Author

mysqlnd wasn't installed. I installed it then tried 5.22 again and it worked.

@dregad dregad added this to the v5.22.6 milestone May 10, 2023
@dregad dregad added bug mysqli MySQL and compatible drivers (MariaDB, etc) (Tier 1) and removed question no change required labels May 10, 2023
@dregad dregad self-assigned this May 10, 2023
@dregad
Copy link
Member

dregad commented May 10, 2023

For now I have updated the mysqli driver documentation, to add a warning that the mysqlnd extension is required.

Planning to add a check in the code, that will stop with a meaningful error when it is not present.

@dregad dregad changed the title Fails to connect to mysql Call to undefined method mysqli_stmt::get_result() when mysqlnd is not available May 10, 2023
@dregad
Copy link
Member

dregad commented May 10, 2023

@AndrewPixel I don't have any environment available where I could actually test this (meaning, the missing mysqlnd). When the change is implemented, would you be able to test and confirm that the updated code works as expected ? It would be appreciated.

@AndrewPixel
Copy link
Author

Yes, I installed mysqlnd on the production server and now it behaves as expected.

My development server is IIS and not only is mysqind not installed it doesn't even appear to be available (though everything still works as expected.)

@dregad
Copy link
Member

dregad commented May 11, 2023

Yes, I installed mysqlnd on the production server and now it behaves as expected.

I'm not sure you understood what I meant. I'm planning to add an extra check in the ADOdb MySQL driver, to ensure that mysqlnd is present when initializing the driver or connecting to the DB, and trigger an error if not.

Since I will not be able to properly test this myself in a real-life scenario, what I would like you to do when the fix is ready, is confirm that the code actually works as expected, i.e. that it correctly detects and reports that mysqlnd is missing in an environment where it is not installed, like your prod server before you fixed it.

development server is IIS and not only is mysqind not installed it doesn't even appear to be available

What makes you say that ? It must be, otherwise you would get the same error here as you reported in #967 (comment)... Did you check phpinfo() ? You should see something like this:

image

@AndrewPixel
Copy link
Author

Oh, yes I'll test a new version of ADOdb to check that it gives an error if mysqlInd is missing.

Yes you're right, it is in phpinfo. As an extension I can install/disable only php_mysqli.dll (and pdo_mysql.dll).

dregad added a commit that referenced this issue May 18, 2023
Since 5.22.0, the mysqli driver relies on the mysqli_stmt_get_result()
function, which is only available in the MySQL Native Driver, to execute
queries.

An attempt to connect on a system using libmysqlclient should fail with
an error message, to avoid problems down the line.

Fixes #967
@dregad
Copy link
Member

dregad commented May 18, 2023

Oh, yes I'll test a new version of ADOdb to check that it gives an error if mysqlInd is missing.

@AndrewPixel I just submitted pull request #971 with the fix I'd like you to test. Looking forward to your feedback. Thanks !

@dregad
Copy link
Member

dregad commented May 24, 2023

Without feedback from you, I assume you don't have time or interest to test. I'll merge the pull request as-is and close this issue, you can always reopen it later if you notice that things are not working as they should.

dregad added a commit that referenced this issue May 24, 2023
Since 5.22.0, the mysqli driver relies on the mysqli_stmt_get_result()
function, which is only available in the MySQL Native Driver, to execute
queries.

An attempt to connect on a system using libmysqlclient should fail with
an error message, to avoid problems down the line.

Fixes #967
@AndrewPixel
Copy link
Author

It's not that I don't want to test it. It's that I don't know github well enough to know out how to get the copy I need to test. I looked for a download link but couldn't find one :-(

@dregad
Copy link
Member

dregad commented May 25, 2023

I don't know github well enough

Sorry ! You should have just said so...

You can always get the whole code from the Code (tree) view of any GitHub commit, by clicking the green Code button and selecting the Download ZIP option. For example, from this issue's related PR #971:

  1. From the PR's commit view (https://github.com/ADOdb/ADOdb/pull/971/commits), select the most recent commit
    image
  2. Download the ZIP
    image

@dregad dregad closed this as completed May 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mysqli MySQL and compatible drivers (MariaDB, etc) (Tier 1)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants