在我们的位置上,我们在使用mysqli和PDO进行准备语句和事务支持之类的工作之间有所分歧。有些项目使用一个,另一些使用。我们迁移到另一个RDBMS的现实可能性很小。
我更喜欢PDO,原因是它允许预准备语句使用命名参数,而据我所知mysqli不允许。
在我们将项目合并为仅使用一种方法时,是否有其他选择作为标准的利弊?
在我们的位置上,我们在使用mysqli和PDO进行准备语句和事务支持之类的工作之间有所分歧。有些项目使用一个,另一些使用。我们迁移到另一个RDBMS的现实可能性很小。
我更喜欢PDO,原因是它允许预准备语句使用命名参数,而据我所知mysqli不允许。
在我们将项目合并为仅使用一种方法时,是否有其他选择作为标准的利弊?
Answers:
好吧,您可以与面向对象方面,准备好的语句,它成为标准的事实等进行争论。但是我知道,在大多数情况下,说服某人使用杀手级功能会更好。就是这样:
使用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
只是...哈哈:) Google不使用公共字段,仅使用访问者:google-styleguide.googlecode.com/svn/trunk/…。
我开始使用PDO,因为我认为语句支持会更好。我使用的是ActiveRecord风格的数据访问层,实现动态生成的语句要容易得多。MySQLi的参数绑定必须在单个函数/方法调用中完成,因此,如果您直到运行时才知道要绑定多少个参数,您将被迫使用call_user_func_array()
(我相信这是正确的函数名)进行选择。不用担心简单的动态结果绑定。
最重要的是,我喜欢PDO,因为它是非常合理的抽象级别。在不需要编写SQL的完全抽象的系统中使用它很容易,但是也可以使它使用更优化的纯查询类型的系统,或者将两者混搭在一起。
还有一点要记住:目前(PHP 5.2),PDO库存在错误。它充满了奇怪的错误。例如:在将a存储到PDOStatement
变量中之前,该变量应unset()
避免大量错误。其中大多数已在PHP 5.3中修复,它们将在2009年初以PHP 5.3发行,可能还会有许多其他错误。如果您想要一个稳定的发行版,那么您应该集中精力使用PDO for PHP 6.1,而如果想帮助社区,则应该专注于使用PDO for PHP 5.3。
关于PDO的另一个显着(良好)区别是,它的PDO::quote()
方法会自动添加封闭的引号,而mysqli::real_escape_string()
(和类似的)则不会:
PDO :: quote()使用适合底层驱动程序的引号样式将引号放在输入字符串(如果需要)周围,并在输入字符串内转义特殊字符。
如果您的站点/ Web应用程序真正成为现实,那么PDO将使扩展变得容易得多,因为您可以每天设置主连接和从属连接以在数据库中分配负载,此外PHP正朝着将PDO迁移为标准的方向发展。
从执行速度的角度来看,MySQLi会胜出,但是除非您使用MySQLi有很好的包装器,否则它处理预准备语句的功能会很糟糕。
我的里面仍然有虫子,但是如果有人想要,它就在这里。
简而言之,如果您正在寻找速度上的增长,那么MySQLi;如果您想易于使用,请使用PDO。
insert
s-几乎相等,select
s-mysqli对于未准备好的语句快约2.5%,对于准备好的语句快约6.7%。考虑到性能损失很小,使用的功能和灵活性PDO
通常会超过性能损失。
编辑答案。
在对这两种API都有一定的经验之后,我会说有2种阻止级别的功能,这些功能使mysqli无法与本机预处理语句一起使用。
他们已经在2个出色的答案中被提及(但被低估了):
(在此答案中也都提到了)
由于某种原因,mysqli都失败了。
如今,第二个版本(get_result)有了一些改进,但是它仅适用于mysqlnd安装,这意味着您不能在脚本中依赖此功能。
但是直到今天,它都没有按值绑定。
因此,只有一种选择:PDO
所有其他原因,例如
并不重要。
同时,这两个API都缺少一些真正重要的功能,例如
因此,为了满足现实生活的需求,必须基于这些API之一创建自己的抽象库,以实现手动解析的占位符。在这种情况下,我更喜欢mysqli,因为它的抽象级别较低。
在我的基准脚本中,每种方法经过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快(SELECT NULL除外)。
PDO具有MySQLi我真正不喜欢的一件事是PDO能够将结果作为指定类类型的对象(例如$pdo->fetchObject('MyClass')
)返回。MySQLi fetch_object()
只会返回一个stdClass
对象。
要记住一件事。
Mysqli不支持fetch_assoc()函数,该函数将返回带有表示列名的键的列。当然,可以编写自己的函数来做到这一点,虽然还不算太长,但是我确实很难编写它(对于非信奉者:如果您觉得很容易,可以花一些时间自己尝试一下,不要这样做。 t作弊:))