php5.3.8中编译pdo_mysql的艰难历程

我们的一个项目,用了PDO_MYSQL拓展,准备迁移服务器,新环境需要编译安装环境。昨天,运维同事抽空编译了一下,一直编译不上pdo_mysql,同时,公司的一款新webgame临近上线,他们实在太忙,我这个三流运维技术的程序员来试试吧。

运维同事描述:
服务器系统版本:Linux version 2.6.32-71.el6.x86_64 (mockbuild@c6b6.centos.org) (gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) ) #1 SMP Fri May 20 03:51:51 BST 2011

编译PHP的参数

...
tar zxvf $soft_dir/php-5.3.8.tar.gz -C $soft_tmp
cd  $soft_tmp/php-5.3.8
 ./configure  --prefix=$soft_install/php --with-config-file-path=$soft_install/php/etc --with-mysql=$soft_install/mysql --with-mysqli=mysqlnd  --with-gd=$soft_install/gd --with-jpeg-dir=$soft_install/jpeg --with-png-dir=$soft_install/png --with-freetype-dir=$soft_install/freetype --enable-bcmath --with-mcrypt  && make && make install
...

之后再次编译 pdo_mysql 拓展

...
cd $soft_tmp/PDO_MYSQL-1.0.2/
$soft_install/php/bin/phpize
./configure --with-php-config=$soft_install/php/bin/php-config  --with-pdo-mysql=$soft_install/mysql/  && make && make install
...

之后, shell里执行 php -i 和 php -m都没有看到 pdo_mysql拓展。搜pdo_mysql,在将路径添加到php.ini中,仍找不到这个扩展,判断为编译失败。

这里是将pdo_mysql作为一个拓展引入使用的。在php5.3中,PHP开发组把mysqlnd作为默认的连接MYSQL的数据库驱动来使用,据官方描述,节省内存40%,速度更快,当然或许是为了解决许可协议的问题。之前PHP连接MYSQL,是调用MYSQL官方提供的C/C++编写的lib_mysql的dll/so,来实现。这个类库同样可以给PYTHON等脚本语言调用,只要按照API规范来。我们改用mysqlnd之后,就不用再为了lib_mysql去安装mysql client了。详情见:mysqlnd插件mysqlnd_ms的介绍
两种方法都可以,运维同事都尝试了,由于时间关系,他们没做过多的尝试研究,就转向更紧急的项目了。

运维同事下载使用的PDO_MYSQL拓展的地址是 http://pecl.php.net/package/PDO_MYSQL ,里面用很耀眼的颜色,标注如下几行字

This package is not maintained anymore and has been superseded. Package has moved to channel http://svn.php.net/viewvc/php/php-src/trunk/ext/pdo_mysql/, package ext/pdo_mysql.

也就是说,早在2006年5月1(我是根据最后一个打包文件日期猜的,或许不准)之后,PHP已经将这个pdo拓展放到PHP源码的 ext/pdo_mysql下内置了。这里的这个包,将不会在更新维护了。

在PHP官方文档上对pdo_mysql使用mysqlnd的时候,是这么描述的
在php5.3中,已经支持mysqlnd作为数据库连接驱动了。而在将来的php5.4中,将变为默认的连接驱动。如图:

mysqlnd-pdo_mysql

开启这个类库的

./configure --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd

之后,我的编译参数如下

./configure  --prefix=/usr/local/services/php --with-config-file-path=/usr/local/services/php/etc --with-pdo-mysql=mysqlnd --with-mysql=mysqlnd --with-mysqli=mysqlnd  --with-iconv-dir=/usr/local/services/libiconv --disable-phar --with-gd=/usr/local/services/gd --with-jpeg-dir=/usr/local/services/jpeg --with-png-dir=/usr/local/services/png --with-freetype-dir=/usr/local/services/freetype --enable-bcmath --with-mcrypt

区别是使用php内置的pdo_mysql类库,使用mysqlnd作为连接驱动。

make之后,提示如下错误

soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1070: undefined reference to `mysql_eof'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1070: undefined reference to `mysql_fetch_row'
ext/mysql/php_mysql.o: In function `zif_mysql_error':
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1727: undefined reference to `mysql_error'
ext/mysql/php_mysql.o: In function `zif_mysql_errno':
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1758: undefined reference to `mysql_errno'
ext/mysql/php_mysql.o: In function `php_mysql_do_connect':
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:705: undefined reference to `mysql_get_client_version'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:963: undefined reference to `mysql_init'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:976: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:980: undefined reference to `mysql_real_connect'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1002: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:706: undefined reference to `mysql_get_client_version'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:844: undefined reference to `mysql_init'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:850: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:853: undefined reference to `mysql_real_connect'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:871: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:989: undefined reference to `mysql_error'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:992: undefined reference to `mysql_errno'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:898: undefined reference to `mysql_ping'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:899: undefined reference to `mysql_errno'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:901: undefined reference to `mysql_real_connect'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:911: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:862: undefined reference to `mysql_error'

这种错误,让我手足无措,GOOGLE搜了下,也没找到相关案例,而且,一直被墙,打不开国外网页。百度搜的结果,还是算了。(中文还行,E文的话,百度确实不行,尤其是程序相关)
之后,尝试make clean,清除之前的编译结果缓存之类。
再次make,有个小意外

ERROR: invalid PHP executable specified by TEST_PHP_EXECUTABLE  = .....

再次搜索,这倒是很多网友遇到过,大部分的建议就是无视这个错误,不影响编译。照做。make install ,一路挺顺畅。

接着,php -i / php -m 也没发现pdo_mysql模块。
郁闷无比,决定看下web下的phpinfo结果,发现居然有了。问题终于解决了。。。万岁。。

可是!!!
1,为啥php -i 、php -m 的结果里看不到呢? 思考,为什么呢?
结合刚刚的报错,联想到CLI 模式下的php 脚本(以及相关的php.ini)跟刚刚从web下访问的php程序不是同一个。检查环境变量,以及切换到编译好的目录下执行php -i,发现pdo_mysql、mysqlnd等相关添加的模块了。

2,php.ini里没启用pdo_mysql拓展,为什么还能看的到呢?
这次使用的是PHP内置的类库,不是以新拓展方式加载运行的,所以,不用更改php.ini,再添加相关so路径。

综上所述,文章没有高深的东西,只是有几个需要细心的点。
1,以官方文档为准,一切跟着官方文档来,不轻易采信网络上网友提供的编译参数,包括这边博文。不论对方是老手、大牛,还是其他什么什么有威望的人。他们提供的方法或许跟你当前的环境不一致,时间也相差很大,或许相隔好几年了。
2,确认得到的结果是准确的,怎么说呢,文中的例子中php-i的路径不是我们新编译的,而是之前编译,或者yum安装的,一定要到自己编译的程序目录下,用自己新编译的脚本去执行测试,获得测试结果,下结论,不为了偷懒,不敲路径,直接写程序名进行测试。
3,遇到诡异的错误,我总会想要一个全新的系统,进行安装,以确保不被各种冗余、缓存等垃圾文件干扰。例子中用了make clean进行清除相关缓存,来解决文件缓存问题。(感谢@ivon_lee 的帮助)
4,自动安装脚本要及时更新,当然,不是意味着追求最新版本。例子中的pdo_mysql的拓展,官方提供了更好的方式,不论是效率,资源占用,都有更好的提升,为啥不使用呢。

备注:mysqlnd 的相关有点对比见http://developer.51cto.com/art/200903/115995.htm

PS:文中出现的我搜索无果两次错误,如果有人知道,请告诉我,谢谢。

您可能喜欢下面几篇博文

发表评论

2 Comments.

  1. 顶!
    我喜欢这个验证码,AJIAO… :mrgreen:

  2. 深刻的学习了,昨天编译也尝试过该种方法,但是只是用php -m验证,没有phpinfo验证。结果…. 就没有结果了。

Leave a Reply



[ Ctrl + Enter ]

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word

CNXCT小组的博客 is Stephen Fry proof thanks to caching by WP Super Cache