gpt4 book ai didi

php - 为什么模拟的准备好的语句不与数据库服务器通信?

转载 作者:行者123 更新时间:2023-11-29 01:49:55 25 4
gpt4 key购买 nike

我正在学习 PHP PDO,对模拟的准备好的语句感到困惑。什么是模拟准备语句和 native 准备语句。

引用链接说:

Emulated prepared statements does not communicate with the database server so PDO::prepare() does not check the statement.

引用链接:Resource

最佳答案

“不与服务器通信”的说法可能不清楚。说“调用 prepare() 时不与服务器通信”会更清楚。

通常在准备和执行序列期间,当您调用 prepare() 时,客户端会将 SQL 作为字符串发送到服务器。服务器解析SQL语法,如果SQL语法有错误,或者引用了不存在的表,或者其他错误,则返回错误。如果查询有效,它会将查询保存在服务器上。如果您的 SQL 字符串中有类似 ? 的参数占位符,服务器会记录这些占位符。

随后,您调用 execute(),并在那时传递任何值以替换占位符。这可能不涉及字符串替换,因为查询在被解析和分析后不再存储为字符串。查询的每个元素都存储为一个对象,包括常量值和参数占位符。

通过模拟准备,PDO 在 prepare() 期间跳过将 SQL 字符串发送到服务器。它只是将 SQL 字符串保存在客户端的 PDO 代码内存中。这也跳过了检查 SQL 查询是否有错误,因为 PDO 客户端不包括 SQL 解析器或任何关于存在哪些表的知识等。

当您执行()一个保存为模拟准备查询的查询时,PDO 对保存的 SQL 字符串进行字符串替换,然后将最终的 SQL 字符串提交给服​​务器。这是服务器第一次看到该查询,因此它会在那时解析语法并优化查询。

模拟准备至少有三个可能的原因:

  1. 允许 PDO 为某些本身不支持该用法或不支持查询参数的 SQL 数据库品牌支持 prepare()/execute()。

    但我想不出任何常用品牌的 SQL 数据库不支持查询参数。

  2. 允许 PDO 支持任何品牌的 SQL 数据库的位置参数 (?) 和命名参数 (:user_id)。 MySQL 本身只支持位置参数。 Oracle 仅支持命名参数。 SQLite 支持这两种样式。

    但 PDO 确实找到了一种在 prepare() 之前将一种类型的参数映射到另一种类型的参数的方法,因此即使在使用非模拟准备时,您也可以在 MySQL 中使用命名参数。 PDO 可以在通过 prepare() 发送之前重写查询字符串,将命名参数转换为位置参数,并记住哪个位置对应哪个名称,因此当您调用 execute() 时,它确保以正确的顺序发送值。

  3. PDO 0.1 alpha 可追溯到 2004 年。当时,有些人可能担心如果每次查询都必须与数据库服务器通信两次,网络开销会太高。因此,为了减少网络传输,可能已经创建了使用模拟的准备好的语句。

    但是如果您的应用程序对性能如此敏感,您应该在 1Gbps 或 10Gbps 的快速网络上将应用程序和数据库服务器彼此靠近运行。任何重视性能的现代数据中心都应该在内部使用这些快速网络。

关于php - 为什么模拟的准备好的语句不与数据库服务器通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48489306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com