37

我刚刚完成了 PHP 入门课程,在整个 stackoverflow 论坛上,人们都建议我切换到 PDO、prepared statements 或 MYSQLi,我简要地查看了手册,但大部分内容都让我头疼。

到目前为止,我一直在使用 mysql_* 函数,所以这些概念对我来说是新的。我认为它们用于访问和执行特定于数据库的操作,但我不确定。

那么 PDO、prepared statements 和 MySQLi 之间有什么区别,它们是完成相同任务的不同功能吗?它们在脚本中是兼容的还是“选择一个或另一个”?最后,哪个提供最佳性能?

更新:感谢您的回答,我将寻找更多 PDO 教程。

作为参考,我还发现以下帖子很有用:

哪一个又快又轻——mysqli还是PDO

mysqli 或 PDO - 有什么优点和缺点?

4

6 回答 6

39

在基本层面上,mysql、mysqli 和 PDO 扩展都回答了我如何与数据库通信的问题?它们都提供连接到数据库并从中发送和检索数据的功能和功能。您可以同时使用它们,一次建立与数据库的多个连接,但这通常是无稽之谈。

mysql* 是一个非常简单的扩展,基本上允许您连接到数据库,向其发送 SQL 查询,仅此而已。
mysqli 通过添加参数化查询和其他一些东西来改进这一点(顾名思义)。
PDO 是一种将多个数据库驱动程序抽象到一个包中的扩展,即它允许您使用相同的代码连接到 MySQL、Oracle、MS SQL Server 和许多其他数据库,而无需使用特定于数据库的扩展或重写您的代码您切换数据库(至少在理论上)。它还支持参数化查询。

如果您知道您将专门使用 MySQL,那么 mysqli 是一个不错的选择。特别是因为您可以以程序方式使用它,您已经习惯了 mysql 扩展。如果您不熟悉 OOP,那会很有帮助。否则,PDO 是一个很好的面向对象、灵活的数据库连接器。


* 请注意,现在不推荐使用mysql 扩展,并将在将来的某个时候将其删除。那是因为它很古老,充满了不良做法,缺乏一些现代特征。不要用它来编写新代码。

于 2012-05-22T14:03:30.647 回答
16

PDO是“PHP 数据对象”。我主要使用PDO,所以我只能说它的优点:

  • 适用于更多的数据库,而不仅仅是 MySQL(对你来说可能无关紧要)
  • 编译C,所以它更快(据说)
  • 准备好的陈述(虽然其他人有这些)
  • SO似乎很喜欢,所以你至少可以在这里得到很多帮助
  • 您可以即时设置和更改各种获取/错误处理模式

你问

那么 PDO、prepared statements 和 MySQLi 有什么区别...

PDO并且MySQLi是数据库包装器。“准备好的陈述”是一个完全不同的概念。您可以准备一个可以多次执行的查询,并且正确参数化的语句是 SQL 注入安全的(尽管可能不是证明)。后一个原因是您应该使用 PDO(或 MySQLi)的大部分原因,但准备好的语句也为查询带来了一定程度的清晰度。

/* mysql_* version */
mysql_connect("host");
$query = "SELECT column FROM db1.t1 WHERE id = ";
foreach ($_GET['id'] as $id) {
   $id = mysql_real_escape_string($id);
   $result = mysql_query($query . "'$id'";
   while ($row = mysql_fetch_assoc($result)) {
      echo "$row[column]\n";
   }
}
//NOTE: it would probably be better to store the resource returned by
//mysql_connect and use that consistently (in query/escape)

/* PDO version */
$pdo = new PDO('mysql:host=HOST', 'user', 'pass');
$query = $pdo->prepare("SELECT column FROM db1.t1 WHERE id = ?";
foreach ($_GET['id'] as $id) {
   $query->execute($id);
   echo $query->fetch(PDO::FETCH_COLUMN);
}
//Notice that you skip the escape step.

你可以用 做基本相同的事情MySQLi,但我更喜欢PDO's 语法。它也可能更快,但我可以弥补。还有MDB2很少被提及的 PEAR,我敢肯定还有更多。既然PDO是内置的,我会去的。

于 2012-05-22T14:03:39.990 回答
4

如果您习惯了这些mysql_xxx功能,那么我将首先转到MySQLi扩展程序。

如果您愿意,您可以改用 PDO,但如果您需要开始支持多个数据库,这只会在第一个实例中真正值得。出于您的目的,我建议切换到 MySQLi,因为它对您来说更容易,而且您不会立即获得 PDO 的好处。

mysql_xxMySQLi 可用的功能与您习惯使用的功能非常相似;通常可以采用现有代码,在它们之间进行直接交换,并且代码应该可以继续正常工作。

所以这是一个很好的起点——让你的代码使用mysqli_xxx而不是 mysql_xxx`。

如果可能的话,我建议使用面向对象的语法而不是过程语法。MySQLi 两者都支持,而且过程语法会更接近你习惯的,但是 OO 语法从长远来看更加灵活,而且一旦你习惯了,实际上并没有太大的不同。

一旦您将代码转换为使用 MySQLi 库,并且您对基础知识感到满意,您就可以开始使用更高级的功能,例如准备好的语句。但首先要让自己对基础知识感到满意。

于 2012-05-22T14:11:36.520 回答
1

来自和你一样的观点。从我的角度来看,我认为差异并不明显(取决于您使用它的目的)。看起来 PDO 只是一个将所有其他数据库 api 合并为一个的数据库 api。因此,如果您需要连接到 MS Sql 服务器和 MySQL 服务器,您可以简单地调用 PDO api 并指定特定数据库的驱动程序。我的猜测也是,MySQL 中的任何未来特性和能力都将仅在 PDO 中可用。所以基本上只需使用 PDO 来确保您可以访问所有最新功能。

于 2012-05-22T14:02:58.827 回答
1

PDO 的一大优势是平台独立性。这意味着您可以在某个时候迁移到不同的 DBMS,而无需重新编码所有函数调用。这就是在 Java(通过 JDBC)、.Net (ADO) 和大多数其他环境中通常完成的事情。优点不仅在于您可以切换 DBMS 本身,还在于您只需学习一个 API。

关于您的问题,PDO 层提供了执行准备好的语句的工具。准备好的语句背后的想法是您为 SQL 语句的部分创建占位符,这些部分直到运行时才知道。许多学习者首先将 SQL 创建为通过调用 mysqli::query($someQuery) 执行的字符串。由于许多原因,这是有问题的,其中最突出的是 SQL 注入漏洞(有关类似问题和答案,请参见 stackoverflow.com/questions/5315351)。使用 PDO,您可以避免 SQL 注入以及处理引号、反斜杠等字符的所有问题。最终结果是您的代码更加安全、可读和可预测。

如果您已经知道如何使用 mysqli,那么使用 PDO 并没有太大的不同。上面链接的问题和答案显示了使用 PDO 准备语句提交的查询示例,该语句应作为有用的指南。

于 2012-05-22T14:15:36.230 回答
-2

那么 PDO、prepared statements 和 MySQLi 之间有什么区别,它们是完成相同任务的不同功能吗?

区别很简单。
PDO 可用于准备好的语句,而 mysqli不能

只需使用本机准备好的语句对这两个 API 运行一些常用查询,您就会清楚地看到差异。

于 2013-04-23T06:36:50.273 回答