mysqli或PDO - 有什么优缺点?

Pol*_*nby 342 php mysql mysqli pdo database-abstraction

在我们的位置,我们将使用mysqli和PDO分为准备语句和事务支持之类的东西.有些项目使用一个,另一个项目.我们很难有可能转移到另一个RDBMS.

我更喜欢PDO,因为它允许为预准备语句提供命名参数,据我所知,mysqli没有.

在我们整合项目时只使用一种方法,是否还有其他优点和缺点选择其中一种作为标准?

e-s*_*tis 243

好吧,你可以争论面向对象的方面,准备好的陈述,它成为标准的事实等等.但我知道大多数时候,说服某人使用杀手功能更好地工作.那就是:

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();
}
Run Code Online (Sandbox Code Playgroud)

  • @outis我希望我在这里不是少数,但我觉得不应该根据他们对新开发者的安全来判断答案.听起来很苛刻,但这是真的.回答SO的目的不仅仅是提供复制和粘贴代码,还要提供理解.确保每个安全漏洞或模式缺陷都在一个示例中,这不是回答者的工作,因为让我们面对它,代码被复制到的应用程序本质上与使用相同代码的每个其他应用程序不同. (15认同)
  • 上面和`$ mysqliResult-> fetch_object("student")之间是否有区别;`? (12认同)
  • @ e-satisf:很抱歉跳入,但是如果你想控制变量变化时会发生什么,那么必须使用getter和setter.否则你简单无法保证你的对象的内部状态(如果你有另一个对象,这尤其是一个问题).这完全与语言无关.@OZ_:放松一下.个人批评只会让其他人处于守势. (6认同)
  • @ e-satisf no,我使用PHP.公共字段违反了封装,所以"作为最佳实践"它只是...大声笑:)谷歌不使用公共字段,只使用访问者:https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml #访问控制 . (2认同)
  • @monadic:同意.当处理核心组件或复杂对象等时,封装当然是一个有效的参数,但是作为记录的表示,否则这些记录将是读写关联的.数组,这是可以接受的.此外,当记录在系统中浮动时,它允许更容易的类型检查. (2认同)
  • @Mattygabe:遗憾的是,太多刚刚开始的开发人员将不会意识到示例代码存在问题并且会复制它而不是理解它.如果不应复制部分示例代码,则代码应附有效果说明. (2认同)

The*_*heo 57

将应用程序从一个数据库移动到另一个数据库并不常见,但迟早您可能会发现自己正在使用不同的RDBMS处理另一个项目.如果你在家中使用PDO,那么至少在这一点上要学习一件事.

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


Bri*_*haw 25

我已经开始使用PDO了,因为在我看来,语句支持更好.我正在使用ActiveRecord-esque数据访问层,并且实现动态生成的语句要容易得多.MySQLi的参数绑定必须在单个函数/方法调用中完成,所以如果你直到运行时才知道你要绑定多少个参数,你就不得不使用call_user_func_array()(我相信这是正确的函数名)来选择.忘记简单的动态结果绑定.

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

  • 结果与动态生成的查询绑定是可能的,我们在我们的应用程序中进行.然而,这是一个巨大的痛苦. (2认同)

Dav*_*ory 17

PDO是标准,它是大多数开发人员期望使用的标准.mysqli本质上是针对特定问题的定制解决方案,但它具有其他DBMS特定库的所有问题.PDO是所有努力工作和聪明思考的基础.


Tom*_*Tom 15

这里还要记住一些事情:就目前而言(PHP 5.2),PDO库是错误的.它充满了奇怪的错误.例如:在存储PDOStatement变量之前,变量应该是unset()为了避免大量的错误.其中大部分已在PHP 5.3中修复,它们将于2009年初在PHP 5.3中发布,这可能还有许多其他错误.如果你想要一个稳定的版本并使用PDO for PHP 5.3,你应该专注于使用PDO for PHP 6.1,如果你想帮助社区.

  • 嗯,很奇怪,我从来没有遇到任何PDO的错误.我经常使用它. (11认同)
  • 我认为PDO提供的收益值得理解并解决这些问题.PHP本身充满了非常严重的错误,有些甚至无法有效地解决,但它提供了许多好处,使我们使用它而不是其他选项. (2认同)

Ali*_*xel 10

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

PDO :: quote()在输入字符串周围放置引号(如果需要),并使用适合底层驱动程序的引用样式转义输入字符串中的特殊字符.


Dfr*_*373 8

如果您的站点/ Web应用程序真正存在,PDO将使其更容易扩展,因为您可以每天设置主从连接以在数据库中分配负载,而且PHP正朝着转向PDO作为标准.

PDO信息

扩展Web应用程序


小智 6

从执行速度来看,MySQLi获胜,但除非你有一个使用MySQLi的好包装器,否则它处理预处理语句的功能很糟糕.

我的房子里还有虫子,但是如果有人想要它,就在这里.

所以总之,如果你正在寻找速度增益,那么MySQLi; 如果你想要易用性,那么PDO.

  • Jonathen Robson在http://jonathanrobson.me/2010/06/mysqli-vs-pdo-benchmarks上对两者进行了不错的速度比较.总结:`insert`s - 几乎相同,`select`s - mysqli对于未准备好的语句快〜2.5%/对准备语句快~~ 6.7%.考虑到性能损失的小,使用"PDO"的功能和灵活性通常超过性能损失. (8认同)
  • 在速度方面,你能给出基准吗? (2认同)

Bla*_*laM 5

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

PDO有一些功能可以帮助SQL注入(准备好的语句),但如果你小心你的SQL,你也可以用mysqli实现.

移动到另一个数据库并不是使用PDO的原因.只要您不使用"特殊SQL功能",就可以从一个DB切换到另一个DB.但是,只要您使用例如"SELECT ... LIMIT 1",就不能转到MS-SQL,它是"SELECT TOP 1 ...".所以这无论如何都是有问题的.

  • MySQLi准备了声明. (22认同)
  • 我支持rFactor ...... (2认同)

You*_*nse 5

编辑回答.

在对这两个API有一些经验之后,我会说有2个阻塞级别的功能使得mysqli无法使用本机预处理语句.
他们已经在2个优秀(但被低估)的答案中被提及:

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

(这个答案中也提到了)

出于某种原因,mysqli都失败了.
现在它对第二个(get_result)有了一些改进,但它只适用于mysqlnd安装,意味着你不能在脚本中依赖这个功能.

然而,直到今天它还没有按价值绑定.

所以,只有一个选择:PDO

所有其他原因,如

  • 命名占位符(这种语法糖被高估了)
  • 不同的数据库支持(没有人真正使用它)
  • 获取对象(只是无用的语法糖)
  • 速度差(没有)

没有任何重要意义.

同时,这两个API都缺少一些真正重要的功能,比如

  • 标识符占位符
  • 复杂数据类型的占位符使动态绑定更少麻烦
  • 更短的应用代码.

因此,为了满足现实生活需求,必须基于其中一个API创建自己的抽象库,实现手动解析的占位符.在这种情况下,我更喜欢mysqli,因为它具有较低的抽象级别.