Request for Comments: ext/mysql deprecation
- Version: 1.2.1
- Date: 2012-12-10
- Author: Adam Harvey email@example.com
- Status: Implemented in PHP 5.5
- First Published at: https://wiki.php.net/rfc/mysql_deprecation
- Trivial patch: http://files.adamharvey.name/mysql-deprecation.patch
- Original discussion: http://article.gmane.org/gmane.comp.php.devel/76725
- Voting discussion: http://article.gmane.org/gmane.comp.php.devel/76987
This RFC proposes to generate E_DEPRECATED errors when connecting to a MySQL database with the ext/mysql API.
Please note that there are two questions below: please vote on both if possible. The first controls the direct result of this RFC, while the second is to provide guidance should the RFC be rejected.
There are four options available for the next question:
If the vote to make ext/mysql generate E_DEPRECATED errors is unsuccessful, what course of action do you think we should take?
- (a) Enhance the manual text to make the soft deprecation clearer, and generate E_DEPRECATED notices in PHP 5.6.
- (b) Enhance the manual text to make the soft deprecation clearer, but take no further action in terms of E_DEPRECATED for the forseeable future.
- (c) Remove the warnings from the manual and undeprecate ext/mysql entirely.
- (d) Do nothing.
In July 2011, Philip started a discussion on the Internals mailing list around the path forward for deprecating ext/mysql, as had been discussed informally for many years. It was agreed at the time that the first step would be to add warnings to the manual, which was done in June.
At the time, it was suggested that we revisit not adding deprecation errors to php-src until 5.5/6.0. Ergo, this RFC.
As a subsequent step, I propose that we generate E_DEPRECATED errors when users connect to MySQL: whether through mysql_connect(), mysql_pconnect() or the implicit connection functionality built into ext/mysql.
The proposed wording of the deprecation message is:
The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead
I'll quote from last year's discussion, rather than writing a long screed myself.
The documentation team is discussing the database security situation, and educating users to move away from the commonly used ext/mysql extension is part of this.
Later, Johannes wrote:
Moving away from ext/mysql is not only about security but also about having access to all features of the MySQL database.
ext/mysql was built for MySQL 3.23 and only got very few additions since then while mostly keeping compatibility with this old version which makes the code a bit harder to maintain. From top of my head missing features not support be ext/mysql include:* Stored Procedures (can't handle multiple result sets) * Prepared Statements * Encryption (SSL) * Compression * Full Charset support * ...
So moving away from ext/mysql is a good thing.
None of those reasons have gone away.
Ulf Wendel has also written a terrific blog post explaining why upgrading from ext/mysql is a good idea. For eaxmple: both MySQLi and PDO include support for prepared statements, and MySQLi also includes support for asynchronous queries.
Furthermore, Johannes Schlüter, in response to a question about whether the extension was really broken, said:
ext/mysql is hard to maintain code. It is not not getting new features. Keeping it up to date for working with new versions of libmysql or mysqlnd versions is work, we probably could spend that time better.
Why Not? (Other Options)
Arguments against raised on Internals include the following:
The current warning in the manual is very weakly worded once you get past the red warning box. That could be beefed up considerably to achieve the same effect in terms of migration without annoying users with notices.
Large Existing Codebase (Too Soon)
There is also a huge amount of code out there that relies on ext/mysql. At the very least, a compatibility library will need to be developed if ext/mysql is to ever be unbundled.
As Anthony Ferrara said on why he believes it's too soon:
My standpoint would be not to add E_DEPRECATED notices in 5.5… It's simply used too much to start loudly complaining about it. Instead, what I would suggest is the following:
1. Officially deprecate it now. Right now, on the docs it says “discouraged”, but I would suggest changing that to officially deprecated.
2. The next release (5.6 or 6) would add deprecation errors to the code.
3. The next release (5.7 or 6 or 6.1, etc) would then remove the extension entirely.
That way there's a significant roadmap towards deprecation, and people can migrate their code in tune. Sure, there are people who won't do anything and will break on that major release, but there's not much we can do about that anyway…
Additionally, a concern is that every deprecation action increases the difficulty for users of upgrading PHP versions with their existing codebases.
Related to the above, some frameworks and commonly used products still require ext/mysql without any option to use MySQLi or PDO: notable examples include WordPress and Plesk.
There are thousands of tutorials out there that teach users PHP using ext/mysql. Many of these tutorials also teach other outdated practices, such as magic quotes, improper (or no) escaping of user input and use of register globals, but undoubtedly some are also still of value. Removing ext/mysql in future will make these tutorials at best useless, and at worst, impediments to PHP takeup.
We Could Move It To PECL Now
Another argument is that ext/mysql could be unbundled in PHP 5.5 and moved straight to PECL.
E_DEPRECATED Is Inappropriate
Concerns were raised that the normal deprecation process isn't appropriate for such a widely used extension. Again, quoting Anthony Ferrara:
There's one important thing that I think you all are missing here. You keep bringing up that we should just use the normal “deprecation” process. The problem is that the deprecation process was never designed for a feature like this.
Look at what was deprecated and removed so far. We deprecated register globals and magic quotes. The process worked there. But was it because of the process? Or was it because those features were already dead by that point. Think of this: when 5.3 shipped (introducing E_DEPRECATED for those features), how many current versions of open source tools relied on those features? None.
Now, you could point to call-time-pass-by-reference as well. E_DEPRECATED was added in 5.3 for it. But most of the projects that used it only used it in a few minor places. The majority of usages were relatively isolated.
Now, look at ext/mysql. The landscape is completely different. Major projects still rely on it in their most recent versions. Wordpress's latest trunk uses ext/mysql. And as was said here, it's not a trivial change to switch from mysql to mysqli or PDO. ext/mysql is still very heavily relied upon.
What I would suggest, is not adding E_DEPRECATED for 5.5. Instead, officially deprecate it in the docs. Then start a PR campaign to get projects like WP to switch away from it. Get the word out there as much as possible. Then in 1 to 2 years when 5.6/6 is released, add E_DEPRECATED.
It's Not Broken
Quoting Ángel González:
The extension is not broken. The problem is the bad usage. It can be used safely, and good developers have been doing so for ages, by creating php wrappers. In magic quotes, the work has been the opposite. The developers had been detecting the feature in php and *disabling* it.
Hosting Providers Don't Provide Alternatives
No numbers were provided for this, but an additional concern is that hosting providers almost universally provide ext/mysql, but the deployment state of MySQLi and PDO is less certain.
Possible Future Action
Some future release of PHP will presumably unbundle ext/mysql, at which point it can be moved out to PECL to slowly bitrot. That future release is not part of this RFC, however.
Converting to MySQLi or PDO
Suppressing deprecation warnings
While code is being converted to MySQLi, E_DEPRECATED errors can be suppressed by setting error_reporting in php.ini to exclude E_DEPRECATED:
error_reporting = E_ALL ^ E_DEPRECATED
Note that this will also hide other deprecation warnings, however, which may be for things other than MySQL.
- 1.2.1 (2012-12-10): Update status to Implemented.
- 1.2 (2012-12-07): Close voting; attempt to summarise the arguments on Internals into a few paragraphs; add links to the discussions for avid readers.
- 1.1.2 (2012-11-28): Replace the Oracle Wiki link with a link to Ulf's new blog post; moved to voting phase.
- 1.1.1 (2012-11-19): Added the wording of the deprecation message that was already in the patch.
- 1.1 (2012-11-13): Added workarounds; fixed formatting on the quote of Johannes' e-mail.
- 1.0 (2012-11-12): Initial version.