Skip to content

Change default value for PDO_Mysql driver ATTR_EMULATE_PREPARES to off #108

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

Closed
wants to merge 1 commit into from

Conversation

ircmaxell
Copy link
Contributor

This pull request changes the default value for PDO_Mysql to disable prepared statement emulation. It can still be turned on with $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true).

This fixes issue https://bugs.php.net/bug.php?id=54638

Quoting:

The PDO_MySQL driver defaults emulate_prepare to 1, which forces all prepared
queries to be emulated by the driver. This means that even though the client
library (mysqlnd or libmysql) may support prepared statements, PDO will never
really use them.

You can set the attribute PDO::ATTR_EMULATE_PREPARES to 0, and it prepares and
executes the prepared statements just fine using the native mode (rather than
emulation). However this is not documented at all on PHP.NET.

Since PDO_MYSQL will fallback to emulation automatically if the client library or
server are too old for prepared statements, I would suggest that the default
value for emulate_prepare should be set to 0 to allow for true prepared
statements.

@smalyshev
Copy link
Contributor

This would need some comments from PDO_mysql maintainers, I have no idea if this is the right thing to do.

@TehShrike
Copy link

It does seem pretty messed up that a prepared statement interface would not actually use prepared statements by default.

@ircmaxell
Copy link
Contributor Author

@smalyshev it was discussed on the list and agreed that it was the right thing to do: http://marc.info/?l=php-internals&m=133972232919056&w=2

The only reason that I have not finished and resolved this request is that getting the tests to pass was turning out to be a nightmare due to their fragility.

@jmpalacios
Copy link

If a non-PHP-developer (but heavy PHP/PDO/MySQL user) may chime in, I'd like to add a little weight in favor of this change since, if I'm not mistaken, not emulating prepared statements is a requirement to get INOUT/OUT MySQL variables in stored procedures working directly from PHP/PDO.

There are several bugs about the failure to use MySQL INOUT/OUT variables directly from PHP reported in both MySQL's & PHP's databases, but I'd like to draw your attention to the one I reported in the former because, as far as I know, it's the only one that's been verified as such by the MySQL team: http://bugs.mysql.com/bug.php?id=69206. Incidentally, PHP's failure to use server-side prepared statements was assessed in that bug report, and that's why I think my comment is relevant to this discussion. Hope I'm not mistaken.

PS: I also made a related comment here: a047ece#commitcomment-3884212

@smalyshev
Copy link
Contributor

@ircmaxell I've run it through Travis and there are a number of tests failing: https://travis-ci.org/smalyshev/php-src/builds/10584068 compared to pre-patch one: https://travis-ci.org/smalyshev/php-src/builds/10583466
Looks like some queries that worked previously don't work anymore. So I'm not sure what to do about it.

@php-pulls
Copy link

Comment on behalf of krakjoe at php.net:

This causes so many failures, such that if it were to be changed, I think it would require an RFC today.

For anyone watching, please take this action as incentive to work on this, please start a discussion and RFC, and ensure tests are passing.

You may need to target some future version of PHP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants