PHP有3种mysql访问API:mysql、mysqli、pdo。泛泛而言,mysql是最古老的访问方式,只提供面向过程的函数,对安全性支持一般,目前不建议使用了。mysqli和pdo都是官方建议的方式,稳定性、安全性都较好,且都提供面向对象的方式,其中mysqli也支持面向过程方式。性能3者差别不大,而且对于一般业务来说,这三种API本身的损耗都可以忽略不计。

那么,为什么官方会建议用mysqli和pdo,而逐步淘汰mysql呢?

对于这三者,官方给出了功能方面的比较:

ext/mysqli PDO_MySQL ext/mysql
PHP version introduced 5.0 5.1 2.0
Included with PHP 5.x Yes Yes Yes
Development status Active Active Maintenance only
Lifecycle Active Active Long term deprecation announced
Recommended for new projects Yes Yes No
OOP Interface Yes Yes No
Procedural Interface Yes No Yes
API supports non-blocking, asynchronous queries with mysqlnd Yes No No
Persistent Connections Yes Yes Yes
API supports Charsets Yes Yes Yes
API supports server-side Prepared Statements Yes Yes No
API supports client-side Prepared Statements No Yes No
API supports Stored Procedures Yes Yes No
API supports Multiple Statements Yes Most No
API supports Transactions Yes Yes No
Transactions can be controlled with SQL Yes Yes Yes
Supports all MySQL 5.1+ functionality Yes Most No

其中server-side prepared statements有助于安全性和性能的提升。由于sql句子和参数分开解析,降低了sql注入的风险。对于同一模板sql、不同参数多次执行的sql,由于sql句子本身的解析和优化仅需执行一次,所以有助于性能提升。但是,单次执行sql时,反而由于这种机制略微降低性能。并且,根据wiki上的阐述,某些mysql版本还会由于不cache query结果等原因,可能会降低性能。

PDO扩展还支持client-side prepared stat,从而可以对应用层提供一致性的prepare接口,并且由于扩展本身的安全性考虑,也可以有效防止sql注入。client-side的方式相当于在扩展层中拼装sql发送给mysql server端,在单次查询时性能可能还会略好于server-side方式,但是多次查询时会略差。(这里的性能区别都可以忽略)

个人感觉上表中其他区别都是编程习惯方面的,可以无视之。

其实除了API层面的区别,PHP官方还搞了mysql的client端C库mysqlnd。之前不论是mysql、mysqli还是PDO,其实都是在PHP扩展层面对mysql提供的libmysql C库的封装,而mysql被oracle收购后,据传闻是由于License的原因,PHP引入了自己的mysql客户端mysqlnd库,并且也作为PHP扩展存在。

Leave a Reply