提问人:Polsonby 提问时间:8/17/2008 最后编辑:Polsonby 更新时间:3/4/2013 访问量:149627
mysqli 或 PDO - 有什么优点和缺点?[已结束]
mysqli or PDO - what are the pros and cons? [closed]
问:
在我们的位置上,我们分为使用 mysqli 和 PDO 来处理预准备语句和事务支持等内容。有些项目使用一个,有些使用另一个。我们转向另一个RDBMS的可能性很小。
我更喜欢 PDO,因为它允许为准备好的语句命名参数,而据我所知,mysqli 没有。
当我们整合项目以仅使用一种方法时,选择其中一种作为标准还有其他优点和缺点吗?
答:
将应用程序从一个数据库移动到另一个数据库并不常见,但迟早您可能会发现自己使用不同的 RDBMS 处理另一个项目。如果您在家使用 PDO,那么在这一点上至少会少学一件事。
除此之外,我发现 PDO API 更直观一些,而且感觉更真正面向对象。mysqli 感觉它只是一个被客观化的过程 API,如果你明白我的意思的话。简而言之,我发现 PDO 更容易使用,但这当然是主观的。
就我个人而言,我使用 PDO,但我认为这主要是一个偏好问题。
PDO具有一些有助于SQL注入(预准备语句)的功能,但是如果您谨慎使用SQL,也可以使用mysqli来实现。
移动到另一个数据库并不是使用 PDO 的理由。只要您不使用“特殊 SQL 功能”,就可以从一个数据库切换到另一个数据库。但是,一旦您使用例如“SELECT ...LIMIT 1“,你不能转到 MS-SQL,因为它是”SELECT TOP 1 ...”。所以无论如何这都是有问题的。
评论
我开始使用 PDO,因为在我看来,语句支持更好。我使用的是 ActiveRecord 式的数据访问层,实现动态生成的语句要容易得多。MySQLi 的参数绑定必须在单个函数/方法调用中完成,因此,如果您在运行时之前不知道要绑定多少个参数,则被迫使用(我相信这是正确的函数名称)进行选择。忘记简单的动态结果绑定。call_user_func_array()
最重要的是,我喜欢PDO,因为它是一个非常合理的抽象层次。在完全抽象的系统中使用它很容易,因为你不想编写 SQL,但它也使使用更优化、更纯查询类型的系统或混合和匹配两者变得容易。
评论
PDO是标准,是大多数开发人员期望使用的。mysqli 本质上是针对特定问题的定制解决方案,但它具有其他特定于 DBMS 的库的所有问题。PDO是所有辛勤工作和聪明思维的去处。
有一件事要记住。
Mysqli 不支持 fetch_assoc() 函数,该函数将返回带有表示列名的键的列。当然,可以编写自己的函数来做到这一点,它甚至不是很长,但我真的很难写它(对于非信徒:如果这对你来说似乎很容易,请自己尝试一段时间,不要欺骗:))
评论
PDO具有MySQLi所没有的一点,我真正喜欢的是PDO能够将结果作为指定类类型的对象(例如)返回。MySQLi只会返回一个对象。$pdo->fetchObject('MyClass')
fetch_object()
stdClass
评论
还有一点要记住:目前(PHP 5.2)PDO库有问题。它充满了奇怪的错误。例如:在变量中存储 a 之前,该变量应该避免大量错误。其中大部分已在 PHP 5.3 中修复,它们将于 2009 年初在 PHP 5.3 中发布,其中可能还有许多其他错误。如果你想要一个稳定的版本,你应该专注于使用 PDO for PHP 6.1,如果你想帮助社区,你应该专注于使用 PDO for PHP 5.3。PDOStatement
unset()
评论
好吧,你可以争论面向对象的方面,准备好的语句,它成为标准的事实,等等。但我知道,大多数时候,说服某人使用杀手级功能效果更好。所以就是这样:
PDO的一个好处是你可以获取数据,将其自动注入到一个对象中。如果你不想使用ORM(因为它只是一个快速脚本),但你确实喜欢对象映射,这真的很酷:
class Student {
public $id;
public $first_name;
public $last_name
public function getFullName() {
return $this->first_name.' '.$this->last_name
}
}
try
{
$dbh = new PDO("mysql:host=$hostname;dbname=school", $username, $password)
$stmt = $dbh->query("SELECT * FROM students");
/* MAGIC HAPPENS HERE */
$stmt->setFetchMode(PDO::FETCH_INTO, new Student);
foreach($stmt as $student)
{
echo $student->getFullName().'<br />';
}
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
评论
$mysqliResult->fetch_object("student");
AS A BEST PRACTICE
从执行速度的角度来看,MySQLi胜出,但除非你有一个好的包装器使用MySQLi,否则它处理准备好的语句的函数是很糟糕的。
我的错误仍然存在,但如果有人想要它,它就在这里。
简而言之,如果您正在寻找速度提升,那么 MySQLi;如果您想要易用性,那么 PDO。
评论
insert
select
PDO
在我的基准测试脚本中,每个方法都经过 10000 次测试,并打印每个方法的总时间差。你应该在自己的配置上这样做,我相信结果会有所不同!
这些是我的结果:
- "
SELECT NULL" -> PGO()
快 ~ 0.35 秒 - "
SHOW TABLE STATUS" -> mysqli()
快 ~ 2.3 秒 - "
SELECT * FROM users" -> mysqli()
快 ~ 33 秒
注意:通过对mysqli使用->fetch_row(),列名不会添加到数组中,我在PGO中没有找到这样做的方法。但即使我使用 ->fetch_array() ,mysqli 也比 PGO 稍慢,但仍然比 PGO 快(SELECT NULL 除外)。
评论
关于PDO的另一个值得注意的(好的)区别是它的PDO::quote()
方法会自动添加括起来的引号,而mysqli::real_escape_string()(
和类似方法)则不:
PDO::quote() 在输入字符串周围放置引号(如果需要)和 使用引号转义输入字符串中的特殊字符 适合基础驱动程序的样式。
如果您的站点/Web 应用程序真正成为现实,PDO 将使扩展变得更加容易,因为您可以每天设置主站和从站连接以在数据库中分配负载,而且 PHP 正朝着将 PDO 作为标准的方向发展。
编辑的答案。
在对这两个 API 都有一些经验之后,我会说有 2 个阻塞级别的功能使 mysqli 无法与本机预准备语句一起使用。
他们已经在 2 个优秀(但被低估)的答案中被提及:
(本回答中也提到了两者)
由于某种原因,mysqli 两者都失败了。
如今,它对第二个(get_result)进行了一些改进,但它仅适用于 mysqlnd 安装,这意味着您不能在脚本中依赖此功能。
然而,直到今天,它仍然没有按价值绑定。
所以,只有一个选择:PDO
所有其他原因,例如
- 命名占位符(这种语法糖被高估了)
- 支持不同的数据库(实际上没有人使用过它)
- fetch into object(只是无用的语法糖)
- 速度差(没有)
并不重要。
同时,这两个 API 都缺少一些真正重要的功能,例如
- 标识符占位符
- 复杂数据类型的占位符,使动态绑定不那么费力
- 更短的应用程序代码。
因此,为了满足现实生活中的需求,必须基于这些 API 之一创建自己的抽象库,实现手动解析的占位符。在这种情况下,我更喜欢mysqli,因为它的抽象程度较低。
评论