在我们这里,我们在使用mysqli和PDO时进行预处理语句和事务支持之类的操作方面存在分歧。一些项目使用其中之一,而另一些项目则使用另一种方法。实际上,我们几乎没有可能转移到另一个关系型数据库管理系统。
我更喜欢使用PDO,因为它允许使用命名参数进行预处理语句,据我所知mysqli并不支持。
在我们将项目整合为只使用一种方法的时候,是否有其他优缺点可以选择其中一种作为标准?
在我们这里,我们在使用mysqli和PDO时进行预处理语句和事务支持之类的操作方面存在分歧。一些项目使用其中之一,而另一些项目则使用另一种方法。实际上,我们几乎没有可能转移到另一个关系型数据库管理系统。
我更喜欢使用PDO,因为它允许使用命名参数进行预处理语句,据我所知mysqli并不支持。
在我们将项目整合为只使用一种方法的时候,是否有其他优缺点可以选择其中一种作为标准?
我知道你可以从面向对象的角度、准备好的语句、成为标准等方面进行争论。但我知道大多数情况下,通过一个杀手级功能来说服某人更有效。因此,这里它是:
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")
有区别吗? - Andy Fleming将一个应用程序从一个数据库移动到另一个数据库并不是很常见,但迟早你会发现自己在另一个使用不同RDBMS的项目上工作。如果你熟悉PDO,那么至少在这一点上就有一件事情需要学习。
除此之外,我认为PDO API更直观,并且它感觉更真正地面向对象。mysqli感觉像是已经被对象化的过程API,如果你知道我的意思的话。简而言之,我发现使用PDO更容易,但这当然是主观的。
我开始使用PDO,因为我认为它的语句支持更好。我正在使用类似ActiveRecord的数据访问层,用起来比较容易实现动态生成语句。MySQLi的参数绑定必须在单个函数/方法调用中完成,所以如果你直到运行时才知道要绑定多少个参数,那么你就不得不使用call_user_func_array()
(我相信这就是正确的函数名)用于选择查询。同时忘掉简单的动态结果绑定。
最重要的是,我喜欢PDO,因为它提供了一个非常合理的抽象级别。它易于在完全抽象化的系统中使用,您不想编写SQL,但它也使得使用更优化、更纯净的查询类型系统变得容易,或是混合使用两者。
PDO是标准,大多数开发人员都会期望使用。mysqli本质上是一个为特定问题量身定制的解决方案,但它具有其他基于DBMS的库的所有问题。PDO是所有艰苦工作和聪明思考的归宿。
需要记住的另一件事是:目前(PHP 5.2),PDO库存在许多错误。它充满了奇怪的错误。例如:在将PDOStatement
存储在变量中之前,应该unset()
变量以避免大量的错误。这些问题中的大部分已经在PHP 5.3中得到解决,并将在2009年早期发布PHP 5.3,但该版本可能仍然有许多其他错误。如果您想要一个稳定的版本,则应专注于使用PHP 6.1的PDO,如果您想帮助社区,则应使用PHP 5.3的PDO。
PDO值得注意的优点之一是它的PDO::quote()
方法会自动添加引号,而mysqli::real_escape_string()
及其类似方法则不会:
PDO::quote()方法会在输入字符串周围加上引号(如果需要),并使用适合底层驱动程序的引号样式转义输入字符串中的特殊字符。
insert
几乎相等,select
对于非预处理语句mysqli约快2.5% /预处理语句约快6.7%。考虑到性能惩罚很小,使用PDO
的功能和灵活性通常超过性能损失。 - Adam编辑后的答案。
在使用这两个API之后,我发现有两个阻塞级别的特性使mysqli无法与本机准备好的语句一起使用。
它们已经在两个优秀(但被低估了)回答中提到:
(都在这个答案中提到)
由于某种原因,mysqli在这两个方面都失败了。
现在第二个问题(get_result)已经得到了改善,但它仅适用于mysqlnd安装,意味着您不能在脚本中依赖此函数。
然而,即使到今天,它也没有绑定值的功能。
所以,只有一个选择:PDO
所有其他原因,例如
都不是非常重要。
同时,这两个API也缺少一些真正重要的功能,例如
因此,为了满足真实的生活需求,必须创建自己的抽象库,基于其中一个API,并手动实现解析占位符。在这种情况下,我更喜欢mysqli,因为它的抽象级别较低。
个人而言,我使用PDO,但我认为这主要是偏好的问题。
PDO具有一些功能可帮助防止SQL注入(prepared statements),但如果您对SQL小心谨慎,您也可以使用mysqli实现。
更改到另一个数据库并不是使用PDO的主要原因。只要您不使用“特殊的SQL功能”,您就可以从一个DB切换到另一个DB。但是,一旦您使用例如“SELECT ... LIMIT 1”,您就不能转到MS-SQL,因为它是“SELECT TOP 1 ...”。所以这仍然是有问题的。