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

就我们而言,我们将使用mysqli和PDO来分割准备好的语句和事务支持。 有些项目使用一个,另一个使用另一个。 我们转向另一个RDBMS几乎没有现实的可能性。

我更喜欢PDO,因为它允许准备好的语句的命名参数,并且据我所知,mysqli没有。

在我们巩固我们的项目使用一种方法时,是否有任何其他的利弊select作为一个标准?

那么你可以用面向对象的方面,准备好的陈述,它成为一个标准的事实来进行争论。但是我知道大多数时候,说服某个人用杀手function更好地工作。 所以那里是:

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(); } 

将应用程序从一个数据库移到另一个数据库不是很常见,但迟早你可能会发现自己正在使用另一个RDBMS工作。 如果你在PDO的家里,那么至less有一件事要学习。

除此之外,我发现PDO API更直观一点,感觉更真实的面向对象。 如果你知道我的意思,mysqli觉得它只是一个被客观化的程序API。 总之,我发现PDO更容易处理,但这当然是主观的。

我已经开始使用PDO了,因为在我看来,声明支持更好。 我使用的是一个ActiveRecord-esque数据访问层,实现dynamic生成的语句更容易。 MySQLi的参数绑定必须在一个函数/方法调用中完成,所以如果你直到运行时才知道你想绑定多less个参数,那么你不得不使用call_user_func_array() (我相信这是正确的函数名)进行select。 而忘记简单的dynamic结果绑定。

最重要的是,我喜欢PDO,因为它是一个非常合理的抽象层次。 在不想编写SQL的完全抽象的系统中使用它很容易,但是它也使得使用更优化的纯查询types的系统或者混合和匹配两者变得容易。

PDO是标准,这是大多数开发人员所期望使用的。 mysqli本质上是一个特定问题的定制解决scheme,但它具有其他DBMS特定库的所有问题。 PDO是所有艰苦工作和聪明的想法将去的地方。

这里有一些其他的要记住:现在(PHP 5.2)的PDO库是越野车 。 它充满了奇怪的错误。 例如:在将PDOStatement存储在一个variables中之前,该variables应该是unset()以避免大量的错误。 其中大部分已经在PHP 5.3中修复,并将在2009年初发布,PHP 5.3中可能会有很多其他的错误。 如果你想要一个稳定的版本,并且使用PHP 5.3的PDO,如果你想帮助社区的话,你应该把重点放在使用PDO for PHP 6.1上。

关于PDO的另一个值得注意的(好的)区别是它的PDO::quote()方法自动添加了封闭的引号,而mysqli::real_escape_string() (和mysqli::real_escape_string() )不会:

PDO :: quote()在inputstring周围加上引号(如果需要的话),并在inputstring中使用适合于底层驱动程序的引用样式来转义特殊字符。

如果您的站点/ Web应用程序变得真正存在,您可以每天设置主站和从站连接以在数据库中分配负载,而PDO将作为标准移动到PDO,PDO将使它更容易扩展。

PDO信息

缩放Web应用程序

从MySQLi的执行速度来看,除非你有一个很好的使用MySQLi的包装,否则它处理准备好的语句的function是非常糟糕的。

我的问题依然存在,但是如果有人想要的话, 就是这样 。

所以简而言之,如果你正在寻找一个速度增益,那么MySQLi; 如果你想易用,那么PDO。

我个人使用PDO,但我认为这主要是一个偏好的问题。

PDO有一些function,可以帮助再次SQL注入( 准备语句 ),但是如果你对你的SQL小心,你也可以用mysqli来实现。

移动到另一个数据库并不是使用PDO的理由。 只要你不使用“特殊的SQLfunction”,你可以从一个DB切换到另一个。 然而,只要你使用例如“SELECT … LIMIT 1”你不能去MS-SQL那里是“selectTOP 1 …”。 所以这是有问题的。

编辑答案。

在对这两个API有一些经验之后,我会说有2个阻塞级别的特性使得mysqli不能用原生预处理语句来使用。
他们已经提到了两个很好的(但被低估)的答案:

  1. 将值绑定到任意数量的占位符
  2. 将数据作为单纯的数组返回

(在这个答案中也提到)

由于某种原因mysqli在两者都失败了。
现在它对第二个( get_result )有了一些改进,但是它只对mysqlnd安装起作用,意味着你不能在脚本中依赖这个函数。

但即使到今天,它也没有价值的约束。

所以,只有一个select: PDO

所有其他原因,如

  • 命名的占位符(这种语法糖被高估)
  • 不同的数据库支持(没有人曾经使用过)
  • 进入对象(只是无用的语法糖)
  • 速度差(没有)

没有任何重要的意义。

同时这两个API都缺乏一些真正的重要特性 ,比如

  • 标识符占位符
  • 复杂数据types的占位符使dynamic绑定变得更加困难
  • 应用程序代码更短

因此,为了满足现实生活需要,必须基于这些API之一创build自己的抽象库,实现手动parsing的占位符。 在这种情况下,我更喜欢mysqli,因为它具有较低的抽象级别。

在我的基准脚本中 ,每种方法都被testing10000次,每种方法的总时间差异都被打印出来。 你应该在你自己的configuration上,我相信结果会有所不同!

这些是我的结果:

  • SELECT NULL" -> PGO()更快〜0.35秒
  • SHOW TABLE STATUS" -> mysqli()更快SHOW TABLE STATUS" -> mysqli()
  • SELECT * FROM users" -> mysqli()更快SELECT * FROM users" -> mysqli()

注意:通过对mysqli使用 – > fetch_row(),列名不会被添加到数组中,我没有find在PGO中这样做的方法。 但即使我使用 – > fetch_array(),mysqli稍慢,但仍然比PGO(SELECT NULL除外)更快。

有一件事PDO有MySQLi不是我真正喜欢的是PDO能够返回结果作为指定类types的对象(例如$pdo->fetchObject('MyClass') )。 MySQLi的fetch_object()将只返回一个stdClass对象。

有一件事要记住。

Mysqli不支持fetch_assoc()函数,它将返回表示列名的键。 当然可以写自己的function来做这件事,这个时间不是很长,但是我真的很难写出来(对于非信徒来说:如果你觉得很容易,可以自己试一试, t作弊:))

Interesting Posts