在我们的地方,我们使用mysqli和PDO来处理准备好的语句和事务支持。有些项目使用其中一种,有些使用另一种。我们几乎不可能迁移到另一个RDBMS。
我更喜欢PDO,原因只有一个,它允许对预处理语句使用命名参数,而据我所知mysqli不允许。
当我们合并我们的项目只使用一种方法时,选择其中一种作为标准是否还有其他优点和缺点?
在我们的地方,我们使用mysqli和PDO来处理准备好的语句和事务支持。有些项目使用其中一种,有些使用另一种。我们几乎不可能迁移到另一个RDBMS。
我更喜欢PDO,原因只有一个,它允许对预处理语句使用命名参数,而据我所知mysqli不允许。
当我们合并我们的项目只使用一种方法时,选择其中一种作为标准是否还有其他优点和缺点?
当前回答
在我的基准测试脚本中,每个方法都要测试10000次,并打印每个方法总时间的差值。你应该在你自己的配置上这样做,我相信结果会有所不同!
以下是我的结果:
"SELECT NULL" -> PGO()更快~ 0.35秒 "SHOW TABLE STATUS" -> mysqli()加快~ 2.3秒 "SELECT * FROM users" -> mysqli()快了~ 33秒
注意:通过使用->fetch_row() for mysqli,列名不会添加到数组中,我没有找到在PGO中这样做的方法。但即使我使用->fetch_array(), mysqli略慢,但仍然比PGO快(除了SELECT NULL)。
其他回答
PDO是标准,它是大多数开发人员希望使用的。mysqli本质上是针对特定问题的定制解决方案,但它具有其他特定于dbms的库的所有问题。PDO是所有努力工作和聪明思维的归宿。
编辑回答。
在对这两个api都有一些使用经验之后,我想说有两个阻塞级别的特性使mysqli无法与本机准备好的语句一起使用。 他们已经在两个优秀(但被低估了)的答案中提到过:
将值绑定到任意数量的占位符 仅以数组形式返回数据
(在这个答案中也提到了)
出于某种原因,mysqli两者都失败了。 现在它对第二个函数(get_result)有了一些改进,但它只能在mysqlnd安装上工作,这意味着你不能在你的脚本中依赖这个函数。
然而,直到今天,它还没有按值绑定。
所以,只有一个选择:PDO
所有其他的原因,比如
命名占位符(这种语法糖被高估了) 不同的数据库支持(实际上没有人使用过) 获取到对象(只是无用的语法糖) 速度差(没有)
都不重要。
同时,这两个api都缺乏一些真正重要的特性,比如
标识符占位符 复杂数据类型的占位符,使动态绑定不那么费力 更短的应用程序代码。
因此,为了满足现实生活的需要,人们必须创建自己的抽象库,基于这些api之一,实现手动解析的占位符。在这种情况下,我更喜欢mysqli,因为它具有较低的抽象级别。
这里还有一些需要记住的事情:目前(PHP 5.2) PDO库有bug。里面充满了奇怪的虫子。例如:在将PDOStatement存储在变量中之前,应该将变量unset()以避免大量错误。其中大部分问题已经在PHP 5.3中得到了修复,并将于2009年初在PHP 5.3中发布,届时可能会有许多其他错误。如果你想要一个稳定的版本,你应该专注于使用PDO for PHP 6.1,如果你想帮助社区,你应该专注于使用PDO for PHP 5.3。
嗯,你可以反驳面向对象方面,准备好的语句,它成为标准的事实,等等。但我知道大多数情况下,使用杀手级功能更能说服别人。就是这样:
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();
}
有一件事要记住。
Mysqli不支持fetch_assoc()函数,该函数将返回带有表示列名的键的列。当然,你也可以自己写一个函数来实现它,它甚至不是很长,但我真的很难写出来(对于不相信它的人:如果它对你来说很容易,你可以自己试试,不要作弊:))