【问题标题】:What are client-side prepared statements?什么是客户端准备好的语句?
【发布时间】:2012-04-26 03:59:06
【问题描述】:

尝试学习新的东西 - 特别是尝试在使用 MySQL 时选择是否使用 MySQLiPDO 用于未来的项目 - 我偶然发现了 this page,它显示了可供我使用的选项的概述。

本页底部是一个表格,比较了与 mysql 通信的三种主要方法的功能。在“API 支持客户端预处理语句”行中,它表示 PDO 支持这一点,而 MySQLi 不支持。

我知道准备好的语句是什么。 this question 的答案是我认为是服务器端准备好的语句的一个简单示例。而 PHP 是一种服务器端语言,这反过来意味着客户端准备好的语句是否可用并不重要。但这让我想知道为什么那甚至在 PHP 手册中列出。

那么什么是客户端准备好的语句?

【问题讨论】:

  • 我假设这在与 Web 模型不同的上下文中使用客户端/服务器 - 即 MySQL 是服务器,PHP 是此上下文中的客户端。即使他们都在同一台计算机上。
  • 当然这指的是PDO::ATTR_EMULATE_PREPARES,这是一个模拟带有插值和转义的准备好的语句的设置。这是在库中完成的,因此在技术上是客户端,在请求被传输到数据库服务器之前。
  • @MattFenwick 虽然这很有意义,但这并不能解释为什么同一张表显示支持所有库的服务器端准备语句,但如果我们只有其中一个支持客户端接受 PHP 是客户端的前提。

标签: php mysql pdo mysqli prepared-statement


【解决方案1】:

显然,客户端准备好的语句是由客户端而不是服务器准备的语句。​​

PDO 是一个支持多个 DBMS 接口(驱动程序)的数据访问抽象层,其中一些支持服务器端准备好的语句(例如:MySQL 4.1+),而另一些则不支持(例如:MySQL 3)。

如果 PDO 驱动程序不支持服务器端准备好的语句,PDO 将在客户端模拟它们并使用通用查询接口来执行它们。

MySQLi 不支持它们的原因很简单:MySQLi 是一个 MySQL 特定的扩展,一个确实支持服务器端预处理语句的 RDBMS,所以没有理由模仿它们。

【讨论】:

    【解决方案2】:

    就像在 cmets 中所说的那样,在这种情况下,“客户端”指的是 PHP,“服务器”指的是 MySQL。 PDO 支持 MySQL 以外的数据库。并非所有这些数据库/数据库驱动程序本身都支持准备好的语句,在这些情况下,PDO 将自己模拟这些语句。 MySQLi 不会(我不确定它什么时候必须这样做——也许是在它处理旧的 MySQL 驱动程序时?)。

    您可能需要考虑的另一个因素 - 某些 PHP 框架需要 PDO 并且不支持 mysqli。

    【讨论】:

      【解决方案3】:

      使用 PDO,您可以使用准备好的语句(在代码中),无论您使用 PDO 连接到的数据库是否支持它们。

      如果服务器处理准备好的语句,那么 PDO 将让服务器处理它们(服务器端)。如果不是,那么 PDO 只是在 PDO(客户端)中模拟准备好的语句,但最终必须将每个查询发送到服务器。

      【讨论】: