前言
可能是我火星了。
在早期编译 PHP 的时候,为了使其支持 Mysql/MariaDB(以下统称为Mysql) 都会加上这样的编译选项
--with-mysqli=/path/to/mysql_config \
--with-pdo-mysql=/path/to/mysql_config \
--with-mysql=/path/to/mysql_config
注:with-mysql在PHP7已被移除
导致后来一段时间,升级数据库版本都要重新编译一遍PHP。
不重新编译会出现很奇怪的错误。(参考这篇文章:https://www.junorz.com/archives/337.html)
最近一次升级数据库版本中真是折腾死人。
后来查了查PHP的文档发现我的做法已经不适合这个版本了。
不能说我的做法不正确,只是不太适合新版本。
我所使用的是 MySQL 官方所提供的连接库(libmysqlclient),而现在 PHP 官方提倡使用 mysqlnd 驱动。
这篇文章主要讲一讲 mysqlnd 和 libmysqlclient 之间的区别。
What is different
mysqlnd 指的是 MySQL Native Driver,是由 PHP 提供的数据库驱动。
libmysqlclient 指的是 MySQL Client Library,是由 MySQL 提供的数据库驱动。
PHP 对 MySQL 进行数据库通信的时候,可以使用 MySQLi 或者 PDO API(前者只支持对 MySQL 的通信,后者像一个接口,可以对很多种数据库通信,就像 Java 里的 JDBC Interface.)。它们底层调用 mysqlnd 或者 libmysqlclient 驱动。
<?php
// mysqli
$mysqli = new mysqli("example.com", "user", "password", "database");
$result = $mysqli->query("SELECT 'Hello, dear MySQL user!' AS _message FROM DUAL");
$row = $result->fetch_assoc();
echo htmlentities($row['_message']);
// PDO
$pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password');
$statement = $pdo->query("SELECT 'Hello, dear MySQL user!' AS _message FROM DUAL");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['_message']);
这里是 PHP 官方文档里给出的区别。(http://php.net/manual/en/mysqlinfo.library.choosing.php)
MySQL native driver (mysqlnd) | MySQL client server library (libmysqlclient) | |
---|---|---|
Part of the PHP distribution | Yes | No |
PHP version introduced | 5.3.0 | N/A |
License | PHP License 3.01 | Dual-License |
Development status | Active | Active |
Lifecycle | No end announced | No end announced |
PHP 5.4 and above; compile default (for all MySQL extensions) | Yes | No |
PHP 5.3; compile default (for all MySQL extensions) | No | Yes |
Compression protocol support | Yes (5.3.1+) | Yes |
SSL support | Yes (5.3.3+) | Yes |
Named pipe support | Yes (5.3.4+) | Yes |
Non-blocking, asynchronous queries | Yes | No |
Performance statistics | Yes | No |
LOAD LOCAL INFILE respects the open_basedir directive | Yes | No |
Uses PHP's native memory management system (e.g., follows PHP memory limits) | Yes | No |
Return numeric column as double (COM_QUERY) | Yes | No |
Return numeric column as string (COM_QUERY) | Yes | Yes |
Plugin API | Yes | Limited |
Read/Write splitting for MySQL Replication | Yes, with plugin | No |
Load Balancing | Yes, with plugin | No |
Fail over | Yes, with plugin | No |
Lazy connections | Yes, with plugin | No |
Query caching | Yes, with plugin | No |
Transparent query manipulations (E.g., auto-EXPLAIN or monitoring) | Yes, with plugin | No |
Automatic reconnect | No | Optional |
区别就显而易见了,而且官方明确地指出5.3之后推荐使用 mysqlnd,所以以后就不需要再依赖 MySQL 自己分发的驱动包了。
结论
官方给出的推荐配置有两种。
// Recommended, compiles with mysqlnd
$ ./configure --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-mysql=mysqlnd
// Alternatively recommended, compiles with mysqlnd as of PHP 5.4
$ ./configure --with-mysqli --with-pdo-mysql --with-mysql
要注意的是,第二种没有明示 mysqlnd 的情况下,5.3及以下版本编译会使用像 /lib 目录下的库。比如有的CentOS7就自带了MySQL库。
所以以后编译 PHP 的时候请使用第一种配置。