PHP接口mysql()无法工作,但mysqli()可以工作;为什么?

6
简介:在dump/restore之后,无法从Web应用程序连接到MariaDB。这似乎是MariaDB中处理PHP mysql()和mysqli()接口方式之间的某些差异。
操作系统为MacOS X 10.6.8(Snow Leopard),使用MariaDB 10.1.8、PHP 5.3.8和Apache 2.2.24。
由于硬盘驱动器损坏,出现了“数据库腐败”问题,一些InnoDB表变得无法访问,最终导致服务器崩溃。我按照服务器错误日志条目指向的网页上的说明进行操作,并能够使用“mysqld --innodb_force_recovery=2”以只读模式运行它。(级别1仍然崩溃,我不敢尝试级别3。)
在“force_recovery”模式下,我对所有数据库进行了逻辑(SQL代码)转储(11 GB),重命名了有问题的数据目录,并运行了“scripts/mysql_install_db.sh”来初始化一个空数据目录。然后我加载了逻辑备份,只有一些小问题。
现在情况变得令人困惑。我可以使用各种工具轻松访问数据库,包括mysql CLI、phpMyAdmin、Sequel Pro、Valentia等。
但是我无法通过任何托管的网站进入数据库,包括几个版本的MediaWiki和几个自制图像库实例。mysql_connect()失败,而mysql CLI使用相同的登录凭据可以正常工作。但是phpMyAdmin可以使用相同的登录凭据!
因此,我浏览了phpMyAdmirn代码,并发现它正在使用mysqli(),而破损的Web应用程序似乎正在使用mysql()。phpMyAdmin有一个配置变量来控制这个问题;我将其从“mysqli”更改为“mysql”,结果出现错误。将其改回“mysqli”,它又可以正常工作。
我没有更改任何PHP代码。我没有更改任何apache设置。我没有更改/etc/my.cnf。我没有更改/etc/php.ini。我没有更改任何登录凭据。唯一改变的是对所有数据库进行了dump、重新初始化和还原。
我认为可能是某些MySQL系统变量设置没有通过dump/restore周期。我运行了phpinfo(),指示mysqli()正在使用正确的socket:/tmp/mysql.sock,但是mysql()正在使用/var/mysql/mysql.sock,这在/etc/php.ini中未启用。在/var/mysql中有一个指向/tmp/mysql.sock的符号链接,这让我想起我曾经走过这条路……我尝试将其变成硬链接;仍然无法解决问题。
我运行了“php -info”,确实,编译的socket是/var/mysql/mysql.sock。因此,我在/etc/my.cnf中放置了“socket=/var/mysql/mysql.sock”,删除了/var/mysql中的符号链接,并重新启动了mysql和apache。socket在/var/mysql中。现在,使用mysqli()的Web应用程序不再工作,但是使用mysql()的应用程序也不起作用!
我很困惑。尤其是在我进行mysql数据目录的转储/初始化/还原之前一切都正常工作。
非常感谢您提供的任何建议!
(我知道mysql()已经被弃用,但我已经在最前面注明了“PHP 5.3.8”。感谢那些没有通过指出不应该使用废弃代码来进行新开发而回答问题的人。现在如果您够聪明,请试着回答问题!我需要维护旧代码!)

3
警告:此扩展在PHP 5.5.0中已被弃用,并在PHP 7.0.0中移除。应使用MySQLi或PDO_MySQL扩展。另请参阅MySQL:选择API指南。此函数的替代方法包括: - Abhishek Sharma
请查看http://php.net/manual/zh/migration55.deprecated.php。 - Chetan Ameta
是的,我知道它已经被新版本的PHP弃用了!但是,除非它能正常工作,否则我不会升级。我需要维护旧代码,建议我现在参与大规模移植工作并没有什么帮助。当然,我不会在新项目中使用废弃的代码,同样地,如果我对最近还在工作的旧代码进行大规模更改,我肯定会破坏很多东西。 - Jan Steinman
1
脚本显示了哪些错误,如果有的话?如果没有,您是否设置了 error_reporting 来显示所有错误? - Revenant
1
我的猜测是:这与MySQL服务器使用的密码方案有关。请参阅https://dev.mysql.com/doc/refman/5.5/en/old-client.html。 - VolkerK
显示剩余3条评论
2个回答

2
在这种情况下,问题出在socket位置上。
尽管我提到将正确的socket位置放在/etc/php.ini中,但是phpinfo()中的另一个信息引起了我的注意:"扫描此目录以获取其他.ini文件:/usr/local/php5/php.d"。显然,在读取主/ etc /php.ini文件之后会执行此操作。真糟糕。
于是我进去看了一眼,果然有一个文件将mysql的套接字(但不是mysqli)设置为错误位置。双倍的倒霉。
我编辑了那个有问题的文件,指向/tmp/mysql.sock,并执行了“apachectl graceful”,很好!(或者对于那些不喜欢弦乐器的人来说,是“voila!”)。它重新工作了!
我不知道为什么在这两个位置之间创建硬链接或符号链接(如我的问题中所解释的)可以解决问题,也不知道为什么简单的备份并恢复数据库会导致事情崩溃,而多年来一切都按原来的方式进行。我只是知道找到并更改错误的套接字位置可以解决问题。
因此,如果您遇到一个接口有问题,而另一个接口没有问题,请务必仔细阅读phpinfo(),并检查所有修改php运行状态的位置,而不仅仅是/etc/php.ini。
非常感谢那些周到和有用的评论!

0
警告:此扩展在PHP 5.5.0中已被弃用,并在PHP 7.0.0中删除。应使用MySQLi或PDO_MySQL扩展。另请参阅MySQL:选择API指南。此函数的替代方法包括:使用MySQLi或PDO。
mysqli_connect()

PDO::__construct()

1
换句话说:“谁在乎为什么,你必须切换,所以就这么做吧!” - Rick James
2
这是粗鲁而无益的。是的,我需要切换。不,除非我可以让事情恢复原状,否则我不会这么做。任何专业程序员都知道当你遇到问题时,你需要逐个更改内容直到解决问题。任何一个负责维护遗留代码的人都知道当你遇到问题时你不能随处升级。 - Jan Steinman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接