当我尝试从PHP连接到MySQL服务器时,出现以下错误:


不推荐使用:不推荐使用mysql扩展,以后将其删除:use第123行的/path/to/filename.php中的mysqli或PDO代替


引用行上的代码是:

mysql_connect($server, $username, $password);


我确信这些参数是正确的,并且这种精确的代码已经运行了好多年没有问题。的确,我是从PHP上一个来源丰富的教程中获得的。


为什么会发生这种情况?
我该如何解决?

我了解通过将error_reporting中的php.ini设置为排除E_DEPRECATED来抑制折旧错误是可能的:

评论

这里有一个用于将mysql转换为mysqli的源扫描工具:转换为MySQLi(2011年12月;作者Keith Larson; Oracle Mysql Wiki)

使用pdo_query()。这是从mysql_开始的最简单的升级路径,并使用PDO。这是两种选择中的一种。 MYSQLI实际上只是一个权宜之计。起初,由于名称相似,听起来对新手来说很诱人,但由于函数签名的移位,需要进行更多的重写,然后甚至使参数化查询更加费力。

至于回答问题标题-PDO更通用,通常它是一个更好的解决方案。 @DennisDegryse =>尽管我更喜欢面向对象的PDO,但MySQLi也有一种面向对象的方式使用它(搜索“ mysqli类”)。有关code.tutsplus.com/tutorials/…上的PDO | MySQLi与php.net/manual/en/mysqli.overview.php之间的比较的更多信息

在Oracle Mysql Wiki上找不到任何内容(上面的链接已注释)。

@hakre感谢您提供该工具的链接。就像一般评论一样,请注意,对于某些命令,您不能简单地将mysql_转换为mysqli_,因为它们的功能有所不同。

#1 楼




为什么会发生这种情况?


整个ext/mysql PHP扩展,提供了以前缀mysql_命名的所有功能,已在PHP中正式弃用。 v5.5.0并已在PHP v7中删除。

它最初是在PHP v2.0(1997年11月)中针对MySQL v3.20引入的,自2006年以来未添加任何新功能。其中的新功能是在复杂的安全漏洞中难以维护这样的旧代码。

自2011年6月以来,该手册已包含警告,禁止其在新代码中使用。



如何解决它?


错误消息提示,您还可以考虑另外两个MySQL扩展:MySQLi和PDO_MySQL,可以使用其中任意一个代替的ext/mysql。自v5.0以来,两者都已成为PHP核心,因此,如果您使用的版本会引发这些弃用错误,则几乎可以肯定地立即开始使用它们,即无需任何安装工作。

它们略有不同,但与旧扩展相比,具有许多优点,包括对事务的API支持,存储过程和准备好的语句(从而提供了克服SQL注入攻击的最佳方法) 。 PHP开发人员Ulf Wendel已对这些功能进行了全面的比较。

Hashphp.org提供了有关从ext/mysql到PDO迁移的出色教程。



>我知道可以通过将error_reporting中的php.ini设置为排除E_DEPRECATED来抑制折旧错误:

error_reporting = E_ALL ^ E_DEPRECATED


如果这样做,会发生什么?


是的,可以抑制此类错误消息,并暂时继续使用旧的ext/mysql扩展名。但是,您实际上不应该这样做-这是开发人员的最后警告,即该扩展可能不会与将来的PHP捆绑在一起(实际上,如前所述,它已从PHP v7中删除)。相反,您应该趁此机会迁移应用程序,以免为时已晚。

还要注意,该技术将禁止所有E_DEPRECATED消息,而不仅仅是与ext/mysql扩展有关的消息:因此,您可以不了解即将对PHP进行的其他更改,这些更改可能会影响您的应用程序代码。当然,可以通过使用PHP的错误控制运算符来仅抑制出现问题的表达式上出现的错误。在相关行的前面加上@-但是,这将抑制该表达式引发的所有错误,而不仅仅是E_DEPRECATED的错误。



您应该怎么做?



您正在开始一个新项目。

完全没有理由使用ext/mysql-选择另一个更现代的扩展来代替,并从中获得收益他们提供的好处。


您拥有(自己的)旧代码库,当前依赖于ext/mysql

执行回归测试将是明智的:您确实在您确定所有潜在影响领域,针对每个潜在影响领域进行计划,然后在分阶段环境中全面测试您的解决方案之前,不应进行任何更改(尤其是升级PHP)。 >
按照良好的编码习惯,您的应用程序是以松散集成/模块化的方式开发的,并且数据库访问方法都是独立存在的,可以轻松交换调出其中一个新扩展名。

花半小时重写此模块,以使用另一个更现代的扩展;彻底测试。您稍后可以进行进一步的改进,以获取它们提供的好处。 。

考虑此时是否真的需要升级到PHP v5.5。

您应该开始计划用另一个更现代的扩展程序替换ext/mysql。为了使您可以从他们提供的利益中获得回报;您也可以借此机会将数据库访问方法重构为更具模块化的结构。

但是,如果您迫切需要立即升级PHP,则可以考虑取消针对暂时存在:但是首先请确保确定还会引发任何其他弃用错误。




您正在使用依赖于ext/mysql的第三方项目。

考虑此时您是否真的需要升级到PHP v5.5。

检查开发人员是否针对此特定版本发布了任何修复程序,解决方法或指南问题;或者,如果没有,请他们注意此事,迫使他们这样做。如果您迫切需要立即升级PHP,则可以暂时考虑抑制弃用错误:但是首先请确保确定还会抛出的其他弃用错误。

这绝对是对执行回归测试至关重要。



评论


请也建议/建议使用准备好的语句“,”,很多时候我看到用户以与mysql相同的方式使用pdo或mysqli查询,即使他们没有转义单引号也更危险

–NullPoiиteя
2012年12月19日下午4:25

@NullPointer:它已经说过“它们……提供……准备好的语句(从而提供了克服SQL注入攻击的最佳方法)”。我真的不想在此答案中提供参数化查询的示例,因为它与手头的问题并不真正相关。您如何看待它更清晰?

– eggyal
2012年12月19日上午9:19

如果您想要快速而肮脏的修复程序,只需在mysql_connect之前加上@即可禁止它。例如。 @mysql_connect(...);通过这种方式,您不必更改任何其他配置。可以使用其余的mysql_函数。只有mysql_connect()给出此消息。

–Bimal Poudel
2015年5月4日13:03

@BimalPoudel:我已经在回答中说过:“当然,通过使用PHP的错误控制运算符,仅可能抑制出现问题的表达式上出现的错误,即在相关行的前面加上@,但是这将抑制所有该表达式引起的错误,而不仅仅是E_DEPRECATED的错误。”

– eggyal
15年5月4日在20:43

@FranKee:如果不将这些用户生成的标题存储在数据库中,该存储在哪里?您所指的“跟我说话”攻击是什么?在没有MySQL数据库的情况下使用mysql_real_escape_string()绝对不是击败任何事物的正确方法(因为它会根据MySQL数据库连接的字符集来转义字符串,而您没有!)如果要防止XSS攻击,则应使用htmlentities()。对于其他任何攻击,请详细说明确切的威胁。

– eggyal
2015年10月6日15:38