exec 和 execute in php 的区别
Difference between exec and execute in php
我正在学习 php 但在我使用的教程中,我可以看到类似这些行的内容:
$DatabaseAdd->exec('INSERT INTO db_name......
还有这个:
$request->execute(array(.....
exec和execute有区别吗?我们可以用一个代替另一个吗?
PDO::exec() executes an SQL statement in a single function call, returning the number of rows affected by the statement.
因此,即使您使用 "SELECT",您也不会返回结果。有道理吗?
tl;dr
- 使用
PDO::exec
发出不 return 结果集的一次性非准备语句。
- 使用
PDO::query
发出一次性非准备语句 return 结果集。
如果语句只执行一次 and/or 如果它们是以准备好的语句不支持的方式动态构造的,那么这两个都是有用的。通常需要额外的工具来正确构造语句(并避免 SQL 注入漏洞之类的事情)。再加上很少需要它们的灵活性,这意味着它通常更倾向于:
- 使用
PDOStatement::prepare
和 PDOStatement::execute
准备语句并执行它们,无论它们 return 结果与否。如果在热路径中多次执行 and/or 则很有用。也不需要额外的工具来处理语句构造。几乎总是尽可能推荐。
exec
and query
act on PDO
对象,因此仅在连接的上下文中。 exec
用于不 return 结果集的语句(例如 INSERT
、UPDATE
、DELETE
),而 query
将 return 结果集(例如来自 SELECT
语句)。它们只是两个相似的接口,本质上做同样的事情(发出声明)。 SQL 语句按原样传递给服务器,因此从客户端的角度来看可能被认为是动态的。
这意味着理论上它们可能总是(即在每次调用时)被解析,interpreted/compiled并在执行之前由 DBMS 优化为查询计划。如果它们被多次执行,这在性能方面是昂贵的。
实际上,如果多次执行,它们通常会被缓存和重用,但 DBMS 只能在机会主义的情况下执行此操作,并且没有任何保证。根据它们的匹配方式,稍微更改查询可能需要 DBMS 完全重新编译它。有时客户端会动态构造查询(通常使用原始字符串连接,有时使用适当的 language-based or library-based 工具支持),这样 DBMS 根本不可能缓存查询计划。
更新:对于好奇的人,Pinq is an example of language-based query builder for PHP and Doctrine LDBAL is library-based example. Note that Pinq only parses PHP expressions for predicates (it seems) and still uses a fluent API for the rest (though some consider that fluent interfaces can form types of DSLs)。
使用适当的工具 and/or 当语句只执行一次(或很少的次数)时,这很好,有时是必要的。
对于您知道的情况,您将多次发出相同的语句,只是可能使用不同的参数(例如谓词/WHERE
子句中的不同值),如果有一种方法可以将它与 DBMS 通信,这样它就不会丢弃整个查询计划,那不是很好吗?它还可能允许它进行更多重量级优化,否则它可能不会这样做,因为它有更多时间在执行语句(可能在热路径中)之前准备语句(缓慢的初始化阶段)。
大多数数据库系统以 prepared statements (using various mechanisms, non-standard AFAIK). PDO exposes it in a unified way through the prepare
method, which returns another object 的形式提供此功能,代表准备好的语句。
然后您可以重用该对象,尤其是它的 execute
方法(它向 DBMS 发出一条语句以执行先前准备好的语句)。如果语句是参数化的,您甚至可以为每个 execute
调用传递新参数。
这也迫使您使用足够合适的工具来构建您的声明并发布它们。正如我之前提到的,基本的字符串连接和其他临时技术只能让你在搬起石头砸自己的脚之前走这么远,很可能是因为未能 escape dynamic parts/parameters properly. This is the #1 source of SQL injection 漏洞。
请注意,如果语句 return 是一个结果集(例如 SELECT
),您将需要使用各种 fetch
变体来检索结果。
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll();
print_r($result);
(Source)
另请注意,非常令人困惑的是,query
本身 return 其结果以 PDOStatement
对象的形式存在(就像 return 由 prepare
).尽管人们可能理解为什么在此处重用此接口,但它可能不是最佳设计(至少可以这样说)。例如,虽然 (a) 它似乎没有明确记录并且 (b) 我没有测试过它,但我会假设在 PDOStatement
returned 上调用 execute
query
是非法的(产生错误)。
免责声明:仅解释文档,不再是常客。
类似问题:
- PDO's query vs execute
- PDO::query vs. PDOStatement::execute (PHP and MySQL)
- PHP PDO Prepare queries
我正在学习 php 但在我使用的教程中,我可以看到类似这些行的内容:
$DatabaseAdd->exec('INSERT INTO db_name......
还有这个:
$request->execute(array(.....
exec和execute有区别吗?我们可以用一个代替另一个吗?
PDO::exec() executes an SQL statement in a single function call, returning the number of rows affected by the statement.
因此,即使您使用 "SELECT",您也不会返回结果。有道理吗?
tl;dr
- 使用
PDO::exec
发出不 return 结果集的一次性非准备语句。 - 使用
PDO::query
发出一次性非准备语句 return 结果集。
如果语句只执行一次 and/or 如果它们是以准备好的语句不支持的方式动态构造的,那么这两个都是有用的。通常需要额外的工具来正确构造语句(并避免 SQL 注入漏洞之类的事情)。再加上很少需要它们的灵活性,这意味着它通常更倾向于:
- 使用
PDOStatement::prepare
和PDOStatement::execute
准备语句并执行它们,无论它们 return 结果与否。如果在热路径中多次执行 and/or 则很有用。也不需要额外的工具来处理语句构造。几乎总是尽可能推荐。
exec
and query
act on PDO
对象,因此仅在连接的上下文中。 exec
用于不 return 结果集的语句(例如 INSERT
、UPDATE
、DELETE
),而 query
将 return 结果集(例如来自 SELECT
语句)。它们只是两个相似的接口,本质上做同样的事情(发出声明)。 SQL 语句按原样传递给服务器,因此从客户端的角度来看可能被认为是动态的。
这意味着理论上它们可能总是(即在每次调用时)被解析,interpreted/compiled并在执行之前由 DBMS 优化为查询计划。如果它们被多次执行,这在性能方面是昂贵的。
实际上,如果多次执行,它们通常会被缓存和重用,但 DBMS 只能在机会主义的情况下执行此操作,并且没有任何保证。根据它们的匹配方式,稍微更改查询可能需要 DBMS 完全重新编译它。有时客户端会动态构造查询(通常使用原始字符串连接,有时使用适当的 language-based or library-based 工具支持),这样 DBMS 根本不可能缓存查询计划。
更新:对于好奇的人,Pinq is an example of language-based query builder for PHP and Doctrine LDBAL is library-based example. Note that Pinq only parses PHP expressions for predicates (it seems) and still uses a fluent API for the rest (though some consider that fluent interfaces can form types of DSLs)。
使用适当的工具 and/or 当语句只执行一次(或很少的次数)时,这很好,有时是必要的。
对于您知道的情况,您将多次发出相同的语句,只是可能使用不同的参数(例如谓词/WHERE
子句中的不同值),如果有一种方法可以将它与 DBMS 通信,这样它就不会丢弃整个查询计划,那不是很好吗?它还可能允许它进行更多重量级优化,否则它可能不会这样做,因为它有更多时间在执行语句(可能在热路径中)之前准备语句(缓慢的初始化阶段)。
大多数数据库系统以 prepared statements (using various mechanisms, non-standard AFAIK). PDO exposes it in a unified way through the prepare
method, which returns another object 的形式提供此功能,代表准备好的语句。
然后您可以重用该对象,尤其是它的 execute
方法(它向 DBMS 发出一条语句以执行先前准备好的语句)。如果语句是参数化的,您甚至可以为每个 execute
调用传递新参数。
这也迫使您使用足够合适的工具来构建您的声明并发布它们。正如我之前提到的,基本的字符串连接和其他临时技术只能让你在搬起石头砸自己的脚之前走这么远,很可能是因为未能 escape dynamic parts/parameters properly. This is the #1 source of SQL injection 漏洞。
请注意,如果语句 return 是一个结果集(例如 SELECT
),您将需要使用各种 fetch
变体来检索结果。
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll();
print_r($result);
(Source)
另请注意,非常令人困惑的是,query
本身 return 其结果以 PDOStatement
对象的形式存在(就像 return 由 prepare
).尽管人们可能理解为什么在此处重用此接口,但它可能不是最佳设计(至少可以这样说)。例如,虽然 (a) 它似乎没有明确记录并且 (b) 我没有测试过它,但我会假设在 PDOStatement
returned 上调用 execute
query
是非法的(产生错误)。
免责声明:仅解释文档,不再是常客。
类似问题:
- PDO's query vs execute
- PDO::query vs. PDOStatement::execute (PHP and MySQL)
- PHP PDO Prepare queries