Patch attached. Should be fully backwards compatible. All unit tests pass, and no code changes required anywhere outside of wpdb.

This leaves wpdb alone for the most part, and just swaps in a different database driver to handle any msyql_* specific calls. No new strings, even! It includes drivers for mysql, mysqli, and pdo_mysql.

This doesn't overreach (no transaction support, and no rewriting of prepare ). It's just designed to address main concern of the ticket: the mysql extension may not be available (due to deprecation?) at some point, and wpdb should support other options.

As we discussed in IRC, this is probably far in the future as deprecation notices won't be turned on until after php 5.4 and other drivers (mysqli, pdo) have their quirks, too.

Patch updated for [21420]. Currently, the mysql driver is the only one that works with the new config options. The mysql, mysqli, and PDO drivers all have different ways to specify their options, so a single constant in wp-config.php won't work going forward with this patch.

Also, I'm not sure if there's a new_link flag for PDO/mysqli. Isn't this default unless specify persistent connections? Perhaps this is addressable in the drivers ...

+1 on this, especially in light of the MySQL deprecation. The question is whether to use mysqli or PDO with the MySQL driver. I think we should stick to a single one in core rather than having both. mysqli has a larger install base than PDO as far as I remember.

I ended up leaving the vote open for a couple of extra days (been a
busy week), but I've now closed the ext/mysql deprecation vote. The
full results are at ​https://wiki.php.net/rfc/mysql_deprecation — the
short version is that the final vote was 25-12 in favour of
deprecation in PHP 5.5.

This made the second question moot, but for the record, the result
there was 26-12 in favour of option (a) (deprecation in PHP 5.6 if not
in PHP 5.5).

[...]

I intend to commit the patch along with the relevant test updates in
the next few days. Admittedly, I'm bad with timeframes, so please
don't hang me if it slips a little. It'll be in before beta 1, I
promise.

21663.4.patch​ has been tested with 3.6, unit tests, and installer code. Seems to work in PDO and classic mysql modes. This new version addresses a few bugs and allows for the user to define a driver via a WPDB_DRIVER constant in wp-config.php or db.php.

I'm open to input. There was some disagreement over whether interfaces was the right way to go in #6821.

This model should give plugin authors the ability to define a new db driver in db.php, too.

If you go the driver route, you should reduce duplicate code between those classes, e.g. to have that in a (abstract?) base class.

Also I'd say there is pretty much an overhead through the level of indirection by having "drivers". I mean PHP offers this Drivers Thingy with PDO, no need to re-invent the wheel technically - just to integrate PDO which is already driver based.

Just while I've quickly seen it in the patch: For the PDO Driver, keep in mind that the DSN can be an alias. You can not just convert host / database / username / password here into a DSN like in the patch. Also you've hardencoded the actual PDO driver. That's limiting the use of a PDO based database class for no reason. Just saying, what jumps into my sight, it's maybe too early for concrete feedback at all.

To reduce the levels of indirection, it is probably more straight forward to offer a set of default database classes that Wordpress can load (by configuration). If you work with Interfaces, it is not important any longer if that included database class then is having a full blown driver implementation loading diverse drivers or is just a straight-forward database class as we have it since years (and as we love it). The legacy database class then can become the blueprint for the interface.

Next generation classes could implement an interface that extends from the legacy interface (to deal with the problems the original implementation has, or at least to offer some way to deal with it).

Also I suggest you leave warnings all over the place that the prepare function is misnamed. I've seen on the Wordpress dev blog that users are being told this is the way to "prepare" just not so long ago, but the prepare function actually just verifies and sanitizes the first string parameter (the query) and then does some dumb stuff on the passed array that should represent values. This is the exact opposite of what prepared and parametrized queries are.

If you want to improve things, start there offering an additional function that follows common parametric queries patterns so that it's not such a burden to go there with a Mysqli / PDO based class. The escape route is not used by a driver based abstraction, like PDO demonstrates.

Otherwise, this all might just not be worth the work because even as of today, you can simply replace the database class with the taste you like most.

From ​IRC today, the prevailing thought is to dump mysqli support and probably the driver system, too.

My original thoughts when writing this: Get off of the old mysql extension. If PDO is available, great. If not, jump onto mysqli. The original cause for the ticket was "mysql is going to be deprecated." I don't know of a firm method or date for that deprecation, though.

mysqli doesn't buy us anything over PDO.

What are our options?

Keep the new system, it's fine

Drop the mysqli driver

Drop the new system and rewrite wp-db to just have PDO

???

It doesn't look like WordPress will easily support other database engines (e.g. sqlite) at this point without rewriting queries or abstracting out the database layer further.

Considerations: How will this impact hyperdb? What can we do to add value while we're under the hood?

I don't think we should waste effort on making plugins/themes that still don't use $wpdb work in PHP 5.4.

By my count, I've found 1,722 plugins in the WP.org plugin repository that make raw calls to mysql_*() functions. Some might have nothing to to with the WP main connection or not actually be calls to core PHP methods, but most of them likely are.

That's 7.4% of all plugins.

What those plugins are doing is wrong, however, it works, and I don't think we should intentionally break them before we absolutely need to. We can at least give them a fighting chance by only using the PDO (or mysqli) extension when either the mysql extension is no longer available, or just on PHP 5.5+ (to avoid dealing with deprecation notices during development even though the mysql extension is available). There's not any compelling reasons that I see for making the jump any earlier than PHP 5.5; we can continue using mysql through PHP 5.4.

By my count, I've found 1,722 plugins in the WP.org plugin repository that make raw calls to mysql_*() functions. Some might have nothing to to with the WP main connection or not actually be calls to core PHP methods, but most of them likely are.

It's pretty awesome how much everyone here raves about how WordPress maintains full compatibility and never removes old API, but when it comes down to things like this, everyone is like "screw them".

What are we gaining by using PDO or mysqli in PHP 5.3 or 5.4 as opposed to using mysql? The answer is absolutely nothing. In fact, if this new code isn't extensively tested before release, we're actually just risking potential bugs (including possible SQL injection issues) with new changes that provide no additional benefits in PHP 5.4 and below. So why is it even being debated? We have the option of slowly rolling this out, and we should take advantage of that.

@bpetty In fairness, the ticket has been open for 5 months, there has been time to raise concerns.

@deltafactory I've applied the patch to a copy of our production DB/code and benchmarked actual page generation. Thus far it's working fine in PDO-mode at performance numbers within a margin of error. No significant loss/gain.

I'm also interested to hear how this would impact HyperDB. I'm personally interested in moving the idea of DB roles into core (for comparison, Drupal has been there for some time).

Apparently everyone seems to have gotten the impression that I'm suggesting we don't migrate to PDO/mysqli at all, so I just want to clarify that this is *not* the case at all. I like this patch, and I do know the mysql extension is deprecated in PHP 5.5, so this has to happen.

To be perfectly clear, what I'm saying is that the patch needs to not default to PDO first if it's available *unless* the version of PHP being used is 5.5 or above, and in cases of PHP 5.4 and below, it should default to using the existing mysql extension it's using right now. In doing so, we give plugin authors who did incorrectly use raw mysql calls a chance of fixing their plugin before it breaks on every WordPress installation the second everyone upgrades to 3.6, and it also gives users of those plugins the time to perform their plugin updates appropriately as well.

As long as we can disable mysql and enable PDO for any PHP version, and then run or test WordPress through PDO, we are fine. For PHP < 5.5, both drivers enabled, mysql takes priority. For PHP >= 5.5, both drivers enabled, PDO takes priority to avoid using deprecated functionality. For any PHP version, when only one driver is avaialable, WordPress will use that.

To be perfectly clear, what I'm saying is that the patch needs to not default to PDO first if it's available *unless* the version of PHP being used is 5.5 or above, and in cases of PHP 5.4 and below, it should default to using the existing mysql extension it's using right now. In doing so, we give plugin authors who did incorrectly use raw mysql calls a chance of fixing their plugin before it breaks on every WordPress installation the second everyone upgrades to 3.6, and it also gives users of those plugins the time to perform their plugin updates appropriately as well.

I agree with the idea, but disagree with the approach.

Plugins using mysql_* functions basically are relying on the mysql_connect and mysql_select_db functions having been called to set up that initial connection for them to use. It would be possible to call both of those in PHP < 5.5 installs, just to set up the connection for plugins, and then to continue on using the newer methods, if available, for the speed improvements.

For the people who argue that making a connection which is then unused is rather stupid, I agree. But it would both maintain backward compatibility and give the performance boost. And, we could wrap this extra connection in a define or some such to allow power-users to turn it off manually via their wp-config.

If you want to take this idea further and somehow detect when mysql_* functions are being used and do the connection on the fly somehow, then feel free to think about that. But for a first draft, just adding a couple of extra old mysql calls is enough for backward compat, I believe.

I am very against bending over backwards to support bad old plugins. I like to think I do things the right way, and with every release, I've had to recode something to prepare. Exempting the lowest common denominator from such "pain" is just ignoring the problem. There was an admin action in 3.5 which was removed without warning that broke 3 of the plugins I wrote for our photo editor. Do we not expect plugin authors to be the ones responsible for keeping up with the times?

@sc0ttclark, I asked a similar question. Not sure how to efficiently search the code of the repository, short of downloading the entire trunk.

@wonderboymusic, it's not bending over backward to *keep* the current functionality (on some level) while trying to move the platform to its most current. I'm surprised you are so gung-ho about leaving people behind considering the work you had to do so recently.

The lead devs are conscious of the "brand" impact this has. WP doesn't want a reputation of breaking during updates for a number of reasons that I don't need to cover here. The $wpdb->prepare() situation from 3.5 was another recent instance where bad plugin code penalized "regular" users who had otherwise had a safe experience upgrading WP. I don't think I'm alone in my desire to prevent bad plugin code + hasty decisions in core from hurting users who aren't web developers.

I would like to see a phased approach based on what I and others have suggested:

Provide a legacy connection with mysql_connect() etc, no matter what $wpdb uses.

Gather stats about offending plugins in the repository and notify authors. (How?)

Announce the intention to deprecate, knowing it probably won't reach the offenders.

In general I think @deltafactory's suggestions are reasonable, with one caveat and one question.

The legacy connection needs to be able to be turned on and off by a constant as soon as it's introduced. I'd prefer off by default, but I could go either way so long as it exists. Opening both a PDO and mysql connection will double the open mysql connections. While PDO/mysql seem negligible in my testing, doubling the connections will be a huge performance issue.

Just think of all the WP sites we've ever seen go down for a DB error, now imagine that suddenly happens at half the traffic.

The question is whether WP has a precedent of version detection. I've seen plenty of feature detection and that makes sense, but I don't know if I get the value of version detection at an app level in the PHP world.

In regards to performance, this is the driver we're talking about, not the query itself. It's almost never the bottleneck compared with the query, your indexes, or your PHP code working on the results (which should already be cached anyway if it's been optimized properly).

Of course this doesn't stop people from benchmarking them anyway. ​Many of ​them don't find more than a 5% difference in performance with equivalent operations. Just as many find wildly different results. One benchmark even ​claims (though without publishing test details/results) that the original MySQL extension is faster in all tests they ran.

Regardless, don't believe most of the benchmarks out there in regards to this. Most of them don't configure their sandbox properly for benchmarking (tuning various optimization settings, clearing caches, etc), and don't measure the appropriate aspects, often mixing performance measurements of tasks unrelated to the driver itself such as tests that spend 90% of the time running the SQL query itself, or code that extracts data from the results - assuming that these will perform consistently enough that they won't affect measurements, and assuming that this is mostly how the driver is being used across all installations of the application.

Of course, we should be profiling these changes anyway, just in case some part of it is inefficiently written (outside of use of the driver anyway) and does make a significant difference for a default WP installation. However, focus on compatibility is much more important than database driver performance (and staying on what everyone is already using right now until PHP is upgraded isn't hurting anyone's current performance). I haven't seen any guides or presentations on WordPress performance ever suggest possibly switching this out to speed up WordPress (and it's ridiculous how many WP performance presentations I've seen, there's at least one per WordCamp). There's significantly more important aspects to consider when it comes to performance.

The scope of this ticket was originally to address the issue of compatibility, not performance. If performance was really a concern here, we would have seen a patch doing exactly the same thing here well before the MySQL extension was deprecated.

Ryan and I discussed this ticket about a month ago in IRC and decided then it should be punted. I am sorry this did not make it back to the ticket. For a few reasons.

PHP 5.5 isn't out yet, and PHP 5.4 (despite being out for a year) as a whopping 1% market penetration. Because this only results in E_DEPRECATED (which we suppress anyway), we're at least a few months to a year out before we even start to look bad here, and we'll work just fine for a while. I would love to revisit this and get it done in either 3.7 or 3.8 (as in, this year). It just isn't a priority for 3.6.

Emphasis this cycle on slashing, caching, and our nascent terms roadmap needed to take precedence, and we didn't have as much bandwidth as expected to cover everything.

Once PHP 5.5 is out, I imagine there will be increased interest in this ticket. That is good. Maybe at that point there can be a better consensus on the approach, as well as a clearer picture of the impact.

Even something as simple as deciding which engine will be used if both are available (pre-5.5) is an important decision. Our mysql engine *does work*. We don't want a bug in the PDO engine to cause us problems on servers and PHP versions that are just fine. Also, PDO has quite a bit of bugs in earlier versions of PHP (5.2, 5.3) which make up the most of our target audience. We should research said issues.

I was reading through this with growing excitement and repeated thoughts of "well, finally, about time", so I was pretty sad to hit nacin's comment at the end and have my hopes dashed for the next few years (most likely, PHP releases seem to roll around very slowly).

An approach which maintains backwards compatibility in the meantime (as advocated by some above), but allows PDO as a non-default option, would allow time for the code to stabilise, to get some practical research into any lingering PDO bugs (the only problems I ran into were pre-5.2) and to get feedback from other developers.

While we certainly can wait around, it's not something that we need to do and we're only delaying the inevitable and (most likely) making the eventual pain worse by choosing to do things at the last possible moment rather than allowing a smooth transition by getting it underway now.

I know it's an old discussion. Change is in wp_check_php_mysql_versions() so that disabling the mysql extension in PHP doesn't throw an error provided an alternate extension is available. Diff is against latest master branch on github; apologies if I screwed something up int the git => svn patch translation.

I suggest that PDO is the first priority only for PHP >= 5.4. For PHP < 5.4 I suggest mysql has priority, then PDO as second. Don't change a winning team, and don't fix what isn't broken or not even undesired.

For PHP 5.2 the stability of PDO should be examined. May be prefer mysqli over PDO in case there is no mysql extension.

I any case, this task should enable the future WordPress to run on a PHP without the mysql extension, regardless of PHP version.

@markoheijnen, I added a patch for your plugin to get SSL support. I have chosen to add a options array to the interface for connect() but I'm not sure if this is the right way to go about it. We can also just have the classes themselves read directly from defined constants instead of getting them passed in. (The legacy mysql client does this for feature flags.)

I guess the question is do we turn SSL cert verification on if available across the board or do we make it configurable? (If we make it configurable I'm guessing we should make it on by default?) In either case we should wrap that set options in a if defined block so mysqli compiled without verify support does not throw PHP notices.

Noticed that #5932 it's going to be, quote,tackled in 3.8, probably with mysqli at the same time.I feel the need to comment on this:

1. I fully trust the decision of the wordpress team, to go either with PDO, either with mysqli.

2. I hope the (potential) discussion mysqli vs. PDO will be very brief, and a conclusion will be reached before wp 3.8 beta 1 lands, so full support for php 5.5 will be added in wp 3.8. Early adopters can react to PDO / mysqli (probable) bugs with php 5.5, before php 5.6 will land (that will not resume to only deprecated errors).

3. I'm sure you're aware both major competitors (joomla & drupal) already support other databases (like PostgreSQL) - drupal via PDO, or that Oracle has a history of making ​weird decisions regarding mysql, or that both major Linux distributions and Google NOW prefer ​MariaDB over mysql.

But I hope you'd also consider when choosing between mysqli and PDO which solution is the most future-proof. Maybe at some point Oracle will give everyone reasons to look for alternatives, and when that time comes, a good decision taken now would help. For example, the possibility to use mysqli as an extension for php also with MariaDB is important, but is MariaDB sufficient when it comes to alternatives for mysql?

WordPress supports MySQL-like databases. That includes MariaDB and Percona Server. In fact, WordPress.org uses Percona for quite a bit. Both work just fine with WordPress as-is, right now — even with ext-mysql or ext-mysqli — and shouldn't impact any decision points here.

Also, I think "full" support for PHP 5.5 is already built-in. The main reason why the PHP core developers were convinced they should finally deprecate ext-mysql is because a WordPress lead developer told them to just rip the band-aid off and do it already. WordPress would then adapt to the changing landscape because that's what we were good at. But ext-mysql still works in 5.5; you're just annoyed by some deprecated messages. Anyone operating PHP 5.5 — which is basically no one at under 0.1% of WordPress sites — knows what they're doing, and they can best serve the WordPress project by testing out markoheijnen's plugin.

Summary
changed from Use PDO for MySQL queries when PDO is available to Use PDO or mysqli for MySQL queries when available

My take on the current work here: While we should look into adding this in 3.8, I think it needs to be a narrow approach. I dislike the idea of any future improvements in wp-db.php needing to be written in two places, as would occur if it were a second file that extends wpdb and overrides methods. (Obviously, that makes the most sense for a plugin, but isn't necessarily the way core should do it.)

I think a "driver" situation is pretty robust, but that the current proposals are actually more robust than what we need to simply add mysqli support. Based on some conversations I've had with marko and others, targeting mysqli seems like a good first step, versus more general DB abstraction. Then we can see how well that works, and maybe get to the point where we have multiple drivers with an interface. I hope to engage with scribu and marko at WordCamp Europe this weekend; maybe we can get something committed to trunk once 3.7 is branched.

It looks like ​Ubuntu 13.10 shipped with PHP 5.5.3, so people are going to start running into this quite a bit more now. Everything works, but all dev environments with WP_DEBUG on get "Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /path/to/wp/wp-includes/wp-db.php on line 1142"

Nacin: What was the outcome of your talks at WordCamp Europe?

Honestly, with the plugin existing and seemingly stable, I think it would be nice to go ahead and move to supporting mysqli as well as PDO.

It also looks like there's a problem with the .7 patch. The files wp-includes/wp-db-driver.interface.php, wp-includes/wp-db-driver-mysql.php, wp-includes/wp-db-driver-mysqli.php, and wp-includes/wp-db-driver-pdo_mysql.php all seem to have triple copies of the code in them.

I don't think we should waste effort on making plugins/themes that still don't use $wpdb work in PHP 5.4.

By my count, I've found 1,722 plugins in the WP.org plugin repository that make raw calls to mysql_*() functions. Some might have nothing to to with the WP main connection or not actually be calls to core PHP methods, but most of them likely are.

That's 7.4% of all plugins.

Using the slurper I have run that stats just now, there are some plugins that failed downloading but here are the stats for me as of right now:
Total plugins: 33263
Plugins using mysql_query: 1019 (files found: 2061)
Percentage: 3,06%

Can someone throw up their patch or summarize the approach that was decided? It would suck if this missed the boat again. The Deprecated: mysql_connect() notice everywhere in PHP 5.5 is harshing my mellow

No final decision as far as I know. The current "driver" idea as implemented above prizes compatibility by supporting mysql, mysqli, and pdo possible (thus increasing maintenance costs). It increases cost with no real access to the "candy" parts of PDO or mysqli. It may be smarter to do a hard cut and say "okay, we're now PDO now" and make wp-db only support pdo.

It would suck if this missed the boat again. The Deprecated: mysql_connect() notice everywhere in PHP 5.5 is harshing my mellow

Added a patch based on the latest code on GitHub. I added a wpdb_drivers filter in wpdb::set_driver() to allow someone to shove another slug in there. I ran unit tests with each driver, everything works.

I added a wpdb_drivers filter in wpdb::set_driver() to allow someone to shove another slug in there.

This is going to be hard to access. Plugins and mu-plugins aren't loaded until after a database connection is made, so what could set that filter? If this is in core, it would probably only be code in db.php. The current plugin on github relies on a constant named WPDB_DRIVER (presumably in wp-config.php) if the user wants to pick a particular driver.

No final decision as far as I know. The current "driver" idea as implemented above prizes compatibility by supporting mysql, mysqli, and pdo possible (thus increasing maintenance costs). It increases cost with no real access to the "candy" parts of PDO or mysqli. It may be smarter to do a hard cut and say "okay, we're now PDO now" and make wp-db only support pdo.

+1 with the idea of sticking to PDO only. It would be really sweet if this change opened the venue to make WP compatible with e.g. Postgres down the road, instead of saddling us with new technical debt.

I added a wpdb_drivers filter in wpdb::set_driver() to allow someone to shove another slug in there.

This is going to be hard to access. Plugins and mu-plugins aren't loaded until after a database connection is made, so what could set that filter? If this is in core, it would probably only be code in db.php. The current plugin on github relies on a constant named WPDB_DRIVER (presumably in wp-config.php) if the user wants to pick a particular driver.

Thoughts?

And thanks for adding the patch :-)

Wouldn't it still be possible if you use the dropin? Since there you still need to set the $wpdb variable and when you don't do that WordPress will load it's own class.

21663-PDO-merge.diff​​ is my first attempt to merge the PDO driver into wpdb, which was way more brutal a task than it looks in the diff. Took me like 7 tries. A Meta Query unit test fails, but everything else passes.

21663-PDO-merge.diff​​ is my first attempt to merge the PDO driver into wpdb, which was way more brutal a task than it looks in the diff. Took me like 7 tries. A Meta Query unit test fails, but everything else passes.

Adding this as a conversation piece.

Emulated prepared statements are an essential flag in my own experience, and it usually is what is needed, wanted and expected. It produces better query plans, too.

1&1 is planning to introduce PHP 5.5 next year and I would love that this is then addressed. I think its weird that there isn't any major discussion about this topic yet. We should already had a plan on how we are going to do this instead of focussing on adding new functionality to WordPress.

21663.2.diff​ is a quick replacement of all mysql_* functions with their mysqli_* counterparts. It only does this if mysqli_connect() exists and PHP >= 5.5. There is a filter called use_mysqli to override. There are a couple issues still, and that is what to do with MYSQL_NEW_LINK and MYSQL_CLIENT_FLAGS. We default new link to true, which is what mysqli does by default, but I'm not sure that MySQLi has an override. I also didn't have time to dig into the various possible flags yet, but I wanted to get the patch up so people could play with it.

There were a couple places I missed yesterday. One in wpdb::flush() for freeing a result, one in wpdb::print_error() to grab the most recent error, and a couple references in the PHPDoc for wpdb::_real_escape(). These have all been taken care of in 21663.3.diff​

Quick thoughts on 21663.3.diff​, Perhaps it'd be best to stick to full if's rather than ternaries? It makes the diff nice and short, but would be much more readable with full if's instead.

After creating the diff I thought about that. I stuck with the ternaries because they're beneficial for the while (such as while ( $row = ( $this->use_mysqli )? @mysqli_fetch_object( $this->result ) : @mysql_fetch_object( $this->result ) ) ) and using them everywhere kept things uniform. I can break most of them into full ifs though.

Quick thoughts on 21663.3.diff​, Perhaps it'd be best to stick to full if's rather than ternaries? It makes the diff nice and short, but would be much more readable with full if's instead.

After creating the diff I thought about that. I stuck with the ternaries because they're beneficial for the while (such as while ( $row = ( $this->use_mysqli )? @mysqli_fetch_object( $this->result ) : @mysql_fetch_object( $this->result ) ) ) and using them everywhere kept things uniform. I can break most of them into full ifs though.

Ah didn't notice those. I think going for a full if () { while(){}; } else { while(){}; } would be more readable anyway, just my thoughts though.

The filter is too early for a plugin to modify it. We should remove it. If you want to use mysqli, then for 3.8, you have to use the latest version of PHP. Or, we *could* add a constant here, as I don't think it would be difficult to keep around in a backwards compatible manner.

The mysqli_set_charset conditional likely still needs the has_cap() check. Or was it removed deliberately?

I double-checked that the client flags are the same value, whether MYSQL_* or MYSQLI_*, so that's cool.

The wpdb::load_col_info() should do the for loop inside the use_mysqli conditionals. It merges to conditionals into one and makes it easier to read.

Let's set $this->last_error = mysqli_error( $this->dbh ) in its own conditional, rather than duplicating the logic inside both branches of the if statement.

It may be cleaner to reverse the nesting of WP_DEBUG and use_mysqli, that way the mysqli commands are together. mysqli_init() also doesn't need to be silenced, so this will reduce that to one line.

I removed the filter and opted to NOT introduce a new constant. Constants have been quite a pain for us in the not-too-distant past, and since this didn't seem necessary I thought we'd see if we came up with a better solution later instead of rushing to add it now.

If we use the OO versions of mysql and mysqli, we won't have to branch the code as much - the constructor would branch, but most of the methods are named the same and take the same args. That's probably lowest hanging fruit.

Could you reactivate this conversation and catch up PHP5.6 out?
I don't know next version of WordPress come earlier than PHP5.6. But it might be time.

Reading the linked posting & RFC, you can see that they only voted on adding a deprecated notice in 5.5, no discussion on removing it in 5.6 was discussed/voted on which is what would normally happen if they were planning an immediate removal. Due to the sheer amount of users of the extension, I wouldn't expect PHP to remove the extension in 5.6 at all. It'd be put to a RFC vote first and we'd have plenty of notice.

That being said, the discussion on this, and the development that occurred on this during 3.7/3.8 is still ongoing and not forgotten. "Future Release" is simply our broad milestone, we'll pull it to the 3.9 milestone if enough development work happens that a change will make it into the release.

I really hoped this would have been included and fixed in WP 3.8, either via mysqli or either PDO. Now ​RHEL 7 is just inches from its stable launch (followed soon by its CentOS more popular alternative), with MariaDB coming as the default database.

After ​Plesk, also Cpanel has full support for MariaDB ​planned, so everybody has (or will soon have) OFFICIAL alternatives to MySQL, that are easy to implement (MariaDB is considered by everybody a drop-in replacement for MySQL).

In this context, when almost everybody is running away from MySQL, is 2014 the year when wordpress will fully support MariaDB (with a mention of this in its ​requirements page, that's very important for non-tech-savvy-users / late adopters) via mysqli (or PDO)? I mean, I see it's not even considered worthy for 3.9... :(

Core does lack having attention for this issue. I totally forgot to mention this in the chat yesterday. That said you can already use MariaDB. I already do that for one site. You normally do get a warning that the version doesn't match warning . I'm not sure if that is fixable with mysql_* functions so I do use PDO for that by using db.php dropin.

I'm a little discouraged by the potential issues that may pop up after mysqli is implemented, if I would be a MariaDB early adopter. I am a little tech-savvy, but I don't want to spend time fixing problems of my own doing.

Sorry for the little offtopic, hope the development on this will restart soon, but please think about this, there are many non-tech-savvy users out there that want a replacement for MySQL NOW, but cannot act in this manner, since the requirements page only mention MySQL.

From own experience there aren't many non-tech-savvy users out there that want to replace MySQL. Like they have no idea which version of MySQL they are running on. And that is totally fine.

I have no issues with using MariaDB and it was always compatible with MySQL. I guess the reason why it's not on the requirement page is that we don't test on it. But to me that is not a reason for not using it.

I’m a big fan of eventually moving to a driver-style WPDB, like markoheijnen’s plugin, but I don’t think we’re ready for that, yet. Changes to WPDB can have far reaching effects, so we need to move in baby steps, and I like aaroncampbell’s approach as a first step.

This patch will need to be updated for #26847 and (hopefully) #5932, but I’d like to see it get into 3.9 early, so we can give it as much soaking time as possible. Changing over to mysqli will probably break any plugins that call the mysql_*() functions directly, so we’ll need to give the plugin authors as much time as possible to update their plugins.

Moving to a driver-style WPDB is a pretty big step. Not because of the changes to the code, but because of the changes to how WPDB can be extended.

Releasing a driver interface is telling the world (even if it isn’t explicitly announced) “here is our DB interface, you can extend it to add new drivers”. Locking down an interface we’re comfortable supporting for a long time is not something we can do quickly or easily.

Moving to a driver-style WPDB is a pretty big step. Not because of the changes to the code, but because of the changes to how WPDB can be extended.

I do get that it's a bigh step. I already had that experience with WP_Image_Editor. I do believe that time is irrelevant. It needs a lot of attention to get how we want it and currently that is the major issue. We only want to do ugly hot fixes instead of making the code great.

MySQL 5.0.6 was released in May 2005. Should earlier versions make WordPress not use set_charset()? How many users are on MySQL <= 5.0.5?

My bad. I missed the MySQL version requirement.

Not bad. WordPress still not requiring 5.0.6 is bad, if WordPress really needs this to be better and consistent regarding charset. I'm ok with just requiring 5.0.x in general, but wonder how bad it would be to raise the requirement just a bit.

I may not understand the implications, but will learn. Requirements have to change from time to time, or else we are in trouble.

It needs a lot of attention to get how we want it and currently that is the major issue. We only want to do ugly hot fixes instead of making the code great.

There are two major issues:

We need to move away from ext/mysql as soon as possible, due to it being deprecated.

We need to modernise WPDB.

This ticket is about moving away from ext/mysql as quickly and with as little pain as possible, and the easiest way to do that is with as few changes to the codebase as possible, which is the aim of the current patch.

I understand that you would prefer to have the correctly engineered solution, that would be my first preference as well. But the more pressing need is to have 3.9 be able to use mysqli, which we won’t be able to do if we implement it as driver solution.

Not bad. WordPress still not requiring 5.0.6 is bad, if WordPress really needs this to be better and consistent regarding charset. I’m ok with just requiring 5.0.x in general, but wonder how bad it would be to raise the requirement just a bit.

We do upgrade the minimum requirements as we need to, usually when the usage levels are negligible. I don’t have the usage breakdown handy, nacin will know the answer to that.

That said, however, for the sake of a few lines of code, I’m not inclined to upgrade the minimum MySQL requirements from 5.0.0 to 5.0.6. Perhaps when we decide to make use of views (added in MySQL 5.0.3), we’ll upgrade it.

We need to move away from ext/mysql as soon as possible, due to it being deprecated.

We need to modernise WPDB.

This ticket is about moving away from ext/mysql as quickly and with as little pain as possible, and the easiest way to do that is with as few changes to the codebase as possible, which is the aim of the current patch.

I understand that you would prefer to have the correctly engineered solution, that would be my first preference as well. But the more pressing need is to have 3.9 be able to use mysqli, which we won’t be able to do if we implement it as driver solution.

I disagree that this ticket is about moving away from ext/mysql. I rather see it as hijacked to be like that. That also makes this ticket now hard to follow since there are patches with the ticket number doing different things. One focusses on one file with mysqli support and the other going for the driver approach.

The problem I'm having now is that we don't focus on the best solution. That happend in 3.8 and now also again for 3.9. With the last sentence you mean if we go for the driver approach we will not hit 3.9?

I believe the driver approach is really stable but on the API side it can be that it isn't something we want. The real issue is never tackled here and that is what to do with plugins that still do raw calls to mysql_query() for example.

This ticket was opened to use a non-deprecated API when available. I'm going to modify that a bit, but the general goal is the same. Here are the goals for 3.9:

Use mysqli when PHP 5.5+, assuming it is available.

Offer the ability to not use ext/mysql even when PHP 5.4 or below, but this will not be the default.

pento is right: We should move away from ext/mysql as soon as possible. I will say I don't think it's simply because PHP has decided it's now deprecated. Honestly, this matters fairly little. Rather, eventually we're going to need mysqli to be our default, and in order to get there in a sane fashion, we need to get this in core at the PHP 5.5+ level first.

Why? (And why 5.5?) Well, one, WordPress already works pretty well under ext/mysql, and we've gotten used to its quirks, and I wouldn't want to suddenly break a site that's been working fine under PHP 5.2-5.4. Two, the bigger issue is that a lot of plugins are going to be affected, and that's what's probably gonna break a site. Easing this in (5.5 only) is the only way to do this without causing a complete disaster.

A driver is out of scope for this ticket. The only goal of this ticket is to get our foot in the door and to signal to plugin developers they need to stop using direct mysql_* functions. (We can email the author of every plugin that uses mysql_* functions, FWIW, and we will do so.)

What about plugins that not use $wpdb... They dont strife to be compatible if they don't. WordPress or it's team doesn't have to concern themselves with those.
So either ban them or break them... They should get in line and use the API in a meaningfull way or they become irrelevant.

That's a short and narrow view, even for me. But it will force devs to improve and get with the times.
Just imagine how many plugins are insecure because a dev is too lazy to use the API. And how many inefficient code exists because the dev is not aware of $wpdb.
I believe (strongly) that breaking compatibility with plugins not using $wpdb will benefit every user in the long run. All be it a bit messy during the transition.

Wordpress offers a rubost and (I think) beautiful API for databases. Everyone who doesn't use it is not seeking compatibility and ease of use.

What about plugins that not use $wpdb... They dont strife to be compatible if they don't. WordPress or it's team doesn't have to concern themselves with those.
So either ban them or break them... They should get in line and use the API in a meaningfull way or they become irrelevant.

I'm very concerned with those. We don't break backwards compatibility just to spite plugin authors. Some of them may have been using mysql_* accidentally, or recklessly, or even intentionally (say, for something not [easily] done with wpdb). And it's been working for them for 11 years without any problem. We're not just going to indiscriminately break plugins (and, thus, sites) when we have the option to not do so. It's not our style and it doesn't sit well with our philosophies.

True, but at the same time you shouldn't let them hinder the progress of Wordpress as a whole. If WP is looking to drop support for mysql_* they are directly slowing down development of WP in a big way.
If that's allowed, this whole ticket and discussion becomes pointless.

So while I agree that my earlier comment is short and perhaps too strict. A clear stance has to be taken towards (against?) such plugins.

Migrate: Start including experimental support for the new methods on a limited basis, with planned expansion of the methods later. This also lets you modify the methods later if it turns out you have to do so, without breaking huge amounts of new development based on it.

Teach: Find the most common dependencies that will break because of it on those cases. Make documentation somewhere detailing these cases, and providing examples of how to change the dependent code effectively.

Notify: Make a list of code that will be affected, mass email the authors, point them to said documentation and other resources.

Deprecate: After sufficient time or after enough measurable migration has occurred, deprecate support for the older methods, stop using old methods by default, but perhaps with sufficient backwards compatibility to make some cases not break totally, or to otherwise minimize impact to users.

Any big change has to be this way. You can't just break the world because it's the right thing to do, because it's never really the right thing to do.

We want to make the method backwards compatible for when we move to a driver system, I like the WPDB_DRIVER define from markoheijnen's WP DB Driver plugin.

aaroncampbell, you mentioned previously that we've had problems with adding defines in the past - are there particular problems we've had that you think would apply to this situation? Given how early $wpdb is created, it seems a define would be the only practical way for a site to be able to change the driver.

[27257] additionally forces mysqli for development environments. This should increase testing during 3.9 beta.

21663.13.diff​ adds a constant called USE_EXT_MYSQL. Rather than the more forward-thinking driver approach, this simply restricts it to applying to the enabling/disabling of ext/mysql.

I actually first had it only allow for the disabling of ext/mysql via USE_EXT_MYSQL = false. USE_EXT_MYSQL = true wouldn't force ext/mysql on PHP 5.5. The patch does this, however, since it may be useful to force ext/mysql for development/testing purposes, and because it's inevitable this will break a PHP 5.5 site, so let's ensure we have easy recourse.

21663.13.diff​ adds a constant called USE_EXT_MYSQL. Rather than the more forward-thinking driver approach, this simply restricts it to applying to the enabling/disabling of ext/mysql.

$this->use_mysqli = (bool) USE_EXT_MYSQL;

I think you meant:

$this->use_mysqli = !USE_EXT_MYSQL;

That said, methinks the define should actually be USE_EXT_MYSQLI to *enable* MySQLi, rather than USE_EXT_MYSQL to *disable* MySQL.

Imho, the odds are ridiculously low that someone would actually go in his wp-config file and define a constant to use the clunky old library, whereas I can readily imagine a number of hackers going in there and happily define a constant that allows to use the more modern library.

aaroncampbell, you mentioned previously that we've had problems with adding defines in the past - are there particular problems we've had that you think would apply to this situation? Given how early $wpdb is created, it seems a define would be the only practical way for a site to be able to change the driver.

Sorry, I missed this with my last comment. The problem has been mostly in unit testing. If you define something like USE_EXT_MYSQL to make a unit test to see that it works, you can't then change it during the testing so that another unit test can test the other option. If filters can't be run at the point where the DB is loaded though, we don't have a lot of options.

Sorry, I missed this with my last comment. The problem has been mostly in unit testing. If you define something like USE_EXT_MYSQL to make a unit test to see that it works, you can't then change it during the testing so that another unit test can test the other option. If filters can't be run at the point where the DB is loaded though, we don't have a lot of options.

For unit testing purposes, couldn't we simply add a filter that we explicitly document as e.g. "internal, for unit testing purposes only — this hook cannot be used by plugins, because these are not loaded at this stage".

Alternatively, and perhaps more ideally, we could tweak the load procedure so to ensure that add_filter() exists when wp-config.php is loaded. It's a matter of including a couple of files in wp-load.php, and changing the calls to require_once (instead of require) in wp-settings.php. That would ensure backwards compatibility with plugins that mindlessly include wp-config.php, and forward compatibility of the needed filter.

Correct, there are a few issues with my patch. Fixed in 21663.14.diff​.

USE_EXT_MYSQLI means if we ever add PDO, we would need to continue to force MySQLi in order to obey their settings. It would be a permanent fixture. An ext/mysql constant, however, would eventually just fade away.

I can readily imagine a number of hackers going in there and happily define a constant that allows to use the more modern library.

Honestly, the only reason why I'm even considering the constant is for development/testing purposes and easy recourse for broken sites. For this situation, said hackers should update to PHP 5.5. If they want to use a more modern library, then the onus should be on them to use a more modern version of PHP.

For unit testing, we can extend wpdb and set use_mysqli to true. That property should probably be protected, not private.

Sorry, I missed this with my last comment. The problem has been mostly in unit testing. If you define something like USE_EXT_MYSQL to make a unit test to see that it works, you can't then change it during the testing so that another unit test can test the other option. If filters can't be run at the point where the DB is loaded though, we don't have a lot of options.

(…)

Alternatively, and perhaps more ideally, we could tweak the load procedure so to ensure that add_filter() exists when wp-config.php is loaded. It's a matter of including a couple of files in wp-load.php, and changing the calls to require_once (instead of require) in wp-settings.php. That would ensure backwards compatibility with plugins that mindlessly include wp-config.php, and forward compatibility of the needed filter.

USE_EXT_MYSQLI means if we ever add PDO, we would need to continue to force MySQLi in order to obey their settings. It would be a permanent fixture. An ext/mysql constant, however, would eventually just fade away.

This is a good idea.

Would the code for switching to mysqli in development versions also disappear during RC or code freeze? Just curious since it would mean the unit tests would also always use mysqli across the board (including with PHP 5.2), which will be great for testing, but leaves us without results on ext/mysql all the way up to the very final tagged release even though it's still going to be used with 99% of installations right now. I'm not really too concerned about it, but it's something to think about.

For this situation, said hackers should update to PHP 5.5. If they want to use a more modern library, then the onus should be on them to use a more modern version of PHP.

Completely agreed here. If there's actually anyone in a situation where they could legitimately use mysqli enhancements or optimizations, the choice of upgrading to PHP 5.5 should make much more sense anyway, and they most likely already have the power to do this on their server(s). I'm honestly having a hard time even coming up with some use cases that might cover more than even 0.1% of users, and for that many, installing a DB drop-in is still a perfectly acceptable solution.

attachment:21663.15.diff​ adds the USE_EXT_MYSQL define, and fixes some warnings caused by wpdb::$dbh not being empty when the connection fails using mysqli - mysqli doesn't set the handle to null like ext/mysql does.

This ticket was mentioned in IRC in #wordpress-dev by DH-Shredder. ​View the logs.

Summary
changed from Use PDO or mysqli for MySQL queries when available to Use mysqli for MySQL queries when available

In terms of offering a mysql_* fallback for plugins, I don't see the benefit. This will only help when ext/mysql is missing, and it never is. ext/mysql will start to be disabled more often over time, but by the time that's any measurable footprint, we should be able to have moved the needle on plugins using MySQL directly.

There is little left here (please weigh in on anything I'm missing):

Email the authors of all plugins that use mysql_* functions directly.

Get Travis CI to run the test suite under MySQLi. It'd double the time it takes to do the tests, but it's probably worth it at least for now.

Given the decision not to do the full abstraction this time around, please carefully test and consider how this will affect the existing database abstraction plugins that many sites have installed in order to support databases other than MySQL.

One such plugin is "Wordpress Database Abstraction" ( ​http://wordpress.org/extend/plugins/wordpress-database-abstraction/ ), which (though not updated for a few years) is still working nicely with WordPress 3.8.1 . With the original developers of that plugin apparently gone, a way forward is needed to continue using alternative databases (such as MSSQL) with WordPress 3.9 .

One option would be for markoheijnen's plugin to be updated and to merge in the extra features from "Wordpress Database Abstraction", especially the query adjustment logic they put in their MSSQL driver (they apparently cared little for getting their other drivers right anyway).

I agree it is an configuration issue, however IMO it took me too much time to figure this out.
If I hadn't enabled WP_DEBUG, I wouldn't have seen the notice of mysqli_real_connect(), but only the generic "Error establishing a database connection"-Site, where sockets aren't even mentioned.

So instead of preventing the error (which we can't), we should improve its documentation. My suggestions:

wp-config.php could include Syntax examples for valid uses of DB_HOST

The error site on /wp-admin/ could link to a specific troubleshooting site on Codex instead of linking to the forum in general.

This ticket was mentioned in IRC in #wordpress-dev by nacin. ​View the logs.

To try and workaround situations where mysqli fails to connect, but mysql probably works, attachment:21663.17.diff​ implements a fallback to mysql, if the first attempt to connect through mysqli fails.

This patch doesn't try to figure out why the mysqli connection failed - if it's a connection configuration issue as described in comment:212, then it should just fallback nicely to mysql. If it's a more serious issue (ie, the server has gone away), mysql will return the same error as mysqli.

Don't force ext/mysqli in RC versions, as we had at one point discussed.

Documentation on this new complexity in our database layer.

Email the authors of all plugins that use mysql_* functions directly.

Get Travis CI to run the test suite under both MySQL and MySQLi. (As noted by pento, if we didn't force ext/mysqli in development versions, this would already just happen automatically for PHP 5.2/5.3/5.4 versus PHP 5.5. I'm fine with Travis running like that if we can make it work.)