mysqli 或 PDO - 优缺点是什么?

发布于 2024-07-04 06:02:47 字数 205 浏览 9 评论 0原文

在我们这里,我们分别使用 mysqli 和 PDO 来处理准备好的语句和事务支持等内容。 有些项目使用其中一种,有些则使用另一种。 我们迁移到另一个 RDBMS 的现实可能性很小。

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

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

In our place we're split between using mysqli and PDO for stuff like prepared statements and transaction support. Some projects use one, some the other. There is little realistic likelihood of us ever moving to another RDBMS.

I prefer PDO for the single reason that it allows named parameters for prepared statements, and as far as I am aware mysqli does not.

Are there any other pros and cons to choosing one over the other as a standard as we consolidate our projects to use just one approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

哆兒滾 2024-07-11 06:02:47

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

One thing PDO has that MySQLi doesn't that I really like is PDO's ability to return a result as an object of a specified class type (e.g. $pdo->fetchObject('MyClass')). MySQLi's fetch_object() will only return an stdClass object.

野生奥特曼 2024-07-11 06:02:47

有一点要记住。

Mysqli 不支持 fetch_assoc() 函数,该函数将返回带有代表列名称的键的列。 当然,可以编写自己的函数来做到这一点,它甚至不是很长,但我真的很难编写它(对于非信徒:如果你觉得这很容易,请尝试一下你自己的时间,不要作弊:))

There's one thing to keep in mind.

Mysqli does not support fetch_assoc() function which would return the columns with keys representing column names. Of course it's possible to write your own function to do that, it's not even very long, but I had really hard time writing it (for non-believers: if it seems easy to you, try it on your own some time and don't cheat :) )

成熟稳重的好男人 2024-07-11 06:02:47

在我的基准脚本中,每种方法都测试了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 除外)。

In my benchmark script, each method is tested 10000 times and the difference of the total time for each method is printed. You should this on your own configuration, I'm sure results will vary!

These are my results:

  • "SELECT NULL" -> PGO() faster by ~ 0.35 seconds
  • "SHOW TABLE STATUS" -> mysqli() faster by ~ 2.3 seconds
  • "SELECT * FROM users" -> mysqli() faster by ~ 33 seconds

Note: by using ->fetch_row() for mysqli, the column names are not added to the array, I didn't find a way to do that in PGO. But even if I use ->fetch_array() , mysqli is slightly slower but still faster than PGO (except for SELECT NULL).

第几種人 2024-07-11 06:02:47

编辑答案。

在对这两个 API 有了一些经验之后,我想说有 2 个阻塞级别的功能使得 mysqli 无法与本机准备好的语句一起使用。
它们已经在 2 个出色的(但被低估的)答案中提到过:

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

(两者也在这个答案

由于某种原因,mysqli 都失败了。
现在第二个得到了一些改进(get_result) ,但它仅适用于 mysqlnd 安装,这意味着您不能在脚本中依赖此函数。

然而直到今天它还没有按值绑定。

所以,只有一个选择: PDO

所有其他原因,例如

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

并不重要。

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

  • 标识符占位
  • 用于复杂数据类型的
  • 符占位符,以减少动态绑定的麻烦并缩短应用程序代码。

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

Edited answer.

After having some experience with both these APIs, I would say that there are 2 blocking level features which renders mysqli unusable with native prepared statements.
They were already mentioned in 2 excellent (yet way underrated) answers:

  1. Binding values to arbitrary number of placeholders
  2. Returning data as a mere array

(both also mentioned in this answer)

For some reason mysqli failed with both.
Nowadays it got some improvement for the second one (get_result), but it works only on mysqlnd installations, means you can't rely on this function in your scripts.

Yet it doesn't have bind-by-value even to this day.

So, there is only one choice: PDO

All the other reasons, such as

  • named placeholders (this syntax sugar is way overrated)
  • different databases support (nobody actually ever used it)
  • fetch into object (just useless syntax sugar)
  • speed difference (there is none)

aren't of any significant importance.

At the same time both these APIs lacks some real important features, like

  • identifier placeholder
  • placeholder for the complex data types to make dynamical binding less toilsome
  • shorter application code.

So, to cover the real life needs, one have to create their own abstraction library, based on one of these APIs, implementing manually parsed placeholders. In this case I'd prefer mysqli, for it has lesser level of abstraction.

夏见 2024-07-11 06:02:47

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

PDO 有一些有助于防止 SQL 注入的功能(准备好的语句) ,但是如果您小心使用 SQL,您也可以使用 mysqli 实现这一点。

迁移到另一个数据库并不是使用 PDO 的理由。 只要不使用“特殊 SQL 功能”,就可以从一个数据库切换到另一个数据库。 然而,一旦您使用“SELECT ... LIMIT 1”,您就无法转到“SELECT TOP 1 ...”的 MS-SQL。 所以这无论如何都是有问题的。

Personally I use PDO, but I think that is mainly a question of preference.

PDO has some features that help agains SQL injection (prepared statements), but if you are careful with your SQL you can achieve that with mysqli, too.

Moving to another database is not so much a reason to use PDO. As long as you don't use "special SQL features", you can switch from one DB to another. However as soon as you use for example "SELECT ... LIMIT 1" you can't go to MS-SQL where it is "SELECT TOP 1 ...". So this is problematic anyway.

硪扪都還晓 2024-07-11 06:02:47

PDO 的另一个显着(好的)区别是它的 PDO::quote() 方法会自动添加引号,而 mysqli::real_escape_string() (和类似的)不:

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

Another notable (good) difference about PDO is that it's PDO::quote() method automatically adds the enclosing quotes, whereas mysqli::real_escape_string() (and similars) don't:

PDO::quote() places quotes around the input string (if required) and
escapes special characters within the input string, using a quoting
style appropriate to the underlying driver.

枉心 2024-07-11 06:02:47

我开始使用 PDO 是因为我认为语句支持更好。 我正在使用 ActiveRecord 式的数据访问层,并且实现动态生成的语句要容易得多。 MySQLi 的参数绑定必须在单个函数/方法调用中完成,因此如果您直到运行时才知道要绑定多少个参数,则必须使用 call_user_func_array() (我相信这是选择的正确函数名称。 忘记简单的动态结果绑定。

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

I've started using PDO because the statement support is better, in my opinion. I'm using an ActiveRecord-esque data-access layer, and it's much easier to implement dynamically generated statements. MySQLi's parameter binding must be done in a single function/method call, so if you don't know until runtime how many parameters you'd like to bind, you're forced to use call_user_func_array() (I believe that's the right function name) for selects. And forget about simple dynamic result binding.

Most of all, I like PDO because it's a very reasonable level of abstraction. It's easy to use it in completely abstracted systems where you don't want to write SQL, but it also makes it easy to use a more optimized, pure query type of system, or to mix-and-match the two.

水中月 2024-07-11 06:02:47

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

我的仍然存在错误,但如果有人想要它, 在这里

简而言之,如果您正在寻求速度提升,那么 MySQLi; 如果你想要易用性,那么PDO。

In sense of speed of execution MySQLi wins, but unless you have a good wrapper using MySQLi, its functions dealing with prepared statements are awful.

There are still bugs in mine, but if anyone wants it, here it is.

So in short, if you are looking for a speed gain, then MySQLi; if you want ease of use, then PDO.

情愿 2024-07-11 06:02:47

PDO 是标准,它是大多数开发人员期望使用的。 mysqli 本质上是针对特定问题的定制解决方案,但它具有其他特定于 DBMS 的库的所有问题。 PDO 是所有辛勤工作和聪明思维的所在。

PDO is the standard, it's what most developers will expect to use. mysqli was essentially a bespoke solution to a particular problem, but it has all the problems of the other DBMS-specific libraries. PDO is where all the hard work and clever thinking will go.

乖乖哒 2024-07-11 06:02:47

还有一些需要记住的事情:目前(PHP 5.2)PDO 库有缺陷。 它充满了奇怪的错误。 例如:在将 PDOStatement 存储到变量中之前,应该对该变量进行 unset() 以避免大量错误。 其中大部分已在 PHP 5.3 中修复,并将于 2009 年初在 PHP 5.3 中发布,该版本可能还会有许多其他错误。 如果您想要稳定的版本,您应该重点使用 PDO for PHP 6.1;如果您想帮助社区,则应重点使用 PDO for PHP 5.3。

Here's something else to keep in mind: For now (PHP 5.2) the PDO library is buggy. It's full of strange bugs. For example: before storing a PDOStatement in a variable, the variable should be unset() to avoid a ton of bugs. Most of these have been fixed in PHP 5.3 and they will be released in early 2009 in PHP 5.3 which will probably have many other bugs. You should focus on using PDO for PHP 6.1 if you want a stable release and using PDO for PHP 5.3 if you want to help the community.

梦中楼上月下 2024-07-11 06:02:47

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

PDO 信息

扩展 Web 应用程序

PDO will make it a lot easier to scale if your site/web app gets really being as you can daily set up Master and slave connections to distribute the load across the database, plus PHP is heading towards moving to PDO as a standard.

PDO Info

Scaling a Web Application

坏尐絯℡ 2024-07-11 06:02:47

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

除此之外,我发现 PDO API 更直观一些,而且感觉更真正面向对象。 如果你明白我的意思的话,mysqli 感觉它只是一个被对象化的程序 API。 简而言之,我发现 PDO 更容易使用,但这当然是主观的。

Moving an application from one database to another isn't very common, but sooner or later you may find yourself working on another project using a different RDBMS. If you're at home with PDO then there will at least be one thing less to learn at that point.

Apart from that I find the PDO API a little more intuitive, and it feels more truly object oriented. mysqli feels like it is just a procedural API that has been objectified, if you know what I mean. In short, I find PDO easier to work with, but that is of course subjective.

浅唱ヾ落雨殇 2024-07-11 06:02:47

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

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

Well, you could argue with the object oriented aspect, the prepared statements, the fact that it becomes a standard, etc. But I know that most of the time, convincing somebody works better with a killer feature. So there it is:

A really nice thing with PDO is you can fetch the data, injecting it automatically in an object. If you don't want to use an ORM (cause it's a just a quick script) but you do like object mapping, it's REALLY cool :

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文