PHP: mysql v mysqli v pdo

18

我一直在阅读关于在php中使用mysqli和pdo来使用mysql的问题。

我看到了一些问题,比如mysqli或PDO-优缺点是什么?从mysql转移到mysqli或pdo?,它们都专门涉及mysqli v pdo。我对这两种方法哪种更好不是很感兴趣。

我在想为什么要避免使用mysql_函数。当然,根据PHP文档http://php.net/manual/en/faq.databases.php#faq.databases.mysql.deprecated的说法,它们正在被弃用,线程PHP PDO and MySQLi建议使用PDO和MySQLi,线程What is the difference between MySQL, MySQLi and PDO?表明这些新方法更安全、更强大。
总体而言,我想知道mysql_方法的主要弱点是什么,以及避免使用它的原因(比仅仅因为它已经被弃用更具体)。我计划更新我的受影响脚本,并对为什么这种旧方法被弃用感到好奇。
谢谢!

5
当然,根据PHP的文档,它们正在被废弃的过程中。你需要知道更多吗?PHP正在淘汰它们。它们正在逐渐消失。这不是关于是否应该停止使用它们的问题,而是你必须停止使用它们,因为它们最终将不存在。有成千上万的其他资源可以告诉你为什么使用PDO而不是mysqli_*函数很重要,但这超出了Stack Overflow的讨论范围。 - user229044
1
我问为什么PHP会让他们崩溃,而不是询问是否使用它们是个好主意。 - Vlad
“mysql_query”是一个如此糟糕的函数,我很惊讶Zend支持它,却没有发起集体诉讼。 - tadman
3个回答

23

mysql_query函数的设计要求您小心地转义每个注入其中的数据,如果您遗漏了任何一个细节,整个应用程序就会被自动 SQL 漏洞利用工具摧毁。

mysqli和 PDO 都支持占位符,这是为了确保查询不受 SQL 注入漏洞的影响而必需的。在每个数据上调用 mysql_real_escape_string 不仅繁琐,而且容易出错,这就是问题所在。

mysql 函数是 PHP 早期阶段的产物,与新的面向对象特性相比显然更加有限,而使用 mysqli 或 PDO 提供了更好的选择。

有很多非常好的理由使用这两个新接口中的任意一个,但最重要的原因是,mysql_query 函数在生产代码中使用太危险了。它让您离很严重的问题只有一步之遥。

数据库密码和信用卡号码的泄露事件层出不穷,其中一个显而易见的 SQL 注入点几乎让黑客轻易掌握网站控制权。


很好的回答。请包含更多的例子和解释,这样就不需要在每个点上进一步搜索了。 - anusree
这个答案已经过时了,因为mysql_query在PHP的7版本中被移除。现在应该使用PDO,或者更好的是像DoctrinePropelEloquent这样的ORM。 - tadman

8

从选择PHP.net的MySQL API开始:

// 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']);

// mysql
$c = mysql_connect("example.com", "user", "password");
mysql_select_db("database");
$result = mysql_query("SELECT 'Hello, dear MySQL user!' AS _message FROM DUAL");
$row = mysql_fetch_assoc($result);
echo htmlentities($row['_message']);

创建一个对象,像mysqli和PDO一样,是编写任何现代软件的推荐方式。mysql库是针对PHP 2.0版本发布的,自那以后没有进行过重大改写。PHP 2.0于1997年发布,这就足以解释为什么不应该使用它。


1
这个例子是一种欺骗行为,因为它没有使用预处理语句。 - Your Common Sense
说实话,我并没有批评这段代码,因为它是直接从PHP手册中摘取的。但我并不认为这是作弊;它只展示了基本部分,并没有涉及到预处理语句或真正的转义字符串。 - Henrik Karlsson
实际转义字符串并不等同于预处理语句。 - Your Common Sense

2

首先,如果您没有正确地手动清理输入,mysql函数极易受到SQL注入攻击。mysqli和pdo具有参数化sql语句选项,避免了这种风险。在我看来,它们通常具有更好的编码风格。


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