Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 何时*不*使用准备好的语句?_Php_Mysql_Pdo_Prepared Statement - Fatal编程技术网

Php 何时*不*使用准备好的语句?

Php 何时*不*使用准备好的语句?,php,mysql,pdo,prepared-statement,Php,Mysql,Pdo,Prepared Statement,我正在重新设计一个使用最小数据库的PHP驱动的网站。原始版本使用“伪准备语句”(进行引用和参数替换的PHP函数)来防止注入攻击,并将数据库逻辑与页面逻辑分离 用一个使用PDO和real prepared语句的对象替换这些特殊函数似乎很自然,但在阅读了它们之后,我不太确定。PDO似乎仍然是一个好主意,但预处理语句的主要卖点之一是能够重用它们……我永远不会这样做。以下是我的设置: 这些陈述都非常简单。大多数都是selectfoo,bar frombaz,其中qux=?按条订购限制1。该批次中最复杂

我正在重新设计一个使用最小数据库的PHP驱动的网站。原始版本使用“伪准备语句”(进行引用和参数替换的PHP函数)来防止注入攻击,并将数据库逻辑与页面逻辑分离

用一个使用PDO和real prepared语句的对象替换这些特殊函数似乎很自然,但在阅读了它们之后,我不太确定。PDO似乎仍然是一个好主意,但预处理语句的主要卖点之一是能够重用它们……我永远不会这样做。以下是我的设置:

  • 这些陈述都非常简单。大多数都是
    selectfoo,bar frombaz,其中qux=?按条订购限制1
    。该批次中最复杂的语句就是三个这样的选择与
    UNION ALL
    s连接在一起
  • 每个页面命中最多执行一条语句,并且只执行一次
  • 我在一个托管环境中,因此对通过亲自进行任何“压力测试”来关闭他们的服务器持谨慎态度
考虑到使用预先准备好的语句至少会使我进行的数据库往返次数增加一倍,我最好避免使用它们吗?我可以使用
PDO::MYSQL\u ATTR\u DIRECT\u QUERY
来避免多次数据库访问的开销,同时保留参数化和注入防御的好处吗?或者,与执行我不必担心的未准备好的查询相比,准备好的语句API使用的二进制调用的性能是否足够好

编辑:

谢谢你们的建议,伙计们。这是一个我希望我可以标记多个答案为“接受”-许多不同的观点。不过,最终,我不得不给他应得的……如果没有他的回答,我会很高兴地离开,做了一件完全错误的事情,即使是在听从了所有人的建议之后。:-)


模拟准备好的声明,它是

今天的软件工程规则:如果它对你没有任何帮助,就不要使用它。

老实说,我认为你不应该担心它。然而,我记得许多PHP数据访问框架支持prepare语句模式和non-prepare语句模式。如果我没记错的话,PEAR:DB在那一天做过

我遇到了与您相同的问题,我也有自己的保留意见,因此我没有使用PDO,而是编写了自己的轻量级数据库层,它支持prepares和标准语句,并在这两种情况下执行正确的转义(sql注入预防)。我对prepares的另一个不满是,有时将一些不可转义的输入附加到一个语句(如。。。其中id位于(1、2、3…)


我对PDO的了解还不够,无法告诉您使用它还有哪些其他选择。然而,我确实知道PHP为它支持的所有数据库供应商提供了转义功能,您可以将自己的小层放在任何数据访问层之上。

准备好的语句被成千上万的人使用,因此经过了很好的测试(因此可以推断它们是相当安全的)。您的自定义解决方案仅由您使用


您的自定义解决方案不安全的可能性非常高。使用事先准备好的陈述。这样,您必须维护更少的代码。

准备好的语句的好处如下:

  • 每个查询只编译一次
  • mysql将使用更高效的传输格式向服务器发送数据
但是,准备好的语句仅在每个连接中保持。除非您使用连接池,否则如果您每页只执行一条语句,将没有任何好处。简单的查询也不会从更高效的传输格式中受益


就我个人而言,我不想麻烦。伪准备语句可能对引用它们可能提供的安全变量很有用。

我认为您需要PDO::ATTR_EMULATE_PREPARES。这将关闭本机数据库准备语句,但仍然允许查询绑定来防止sql注入并保持sql整洁。据我所知,PDO::MYSQL\u ATTR\u DIRECT\u QUERY完全关闭查询绑定。

什么时候不使用准备好的语句?在db连接断开之前只运行一次语句

什么时候不使用绑定查询参数(这是大多数人使用预处理语句得到的)?我倾向于说“从不”,我真的很想说“从不”,但事实是,大多数数据库和一些db抽象层都有某些特定的情况,在这些情况下,它们不允许您绑定参数,因此在这些情况下,您不得不不使用它们。不过,在其他任何时候,使用它们都会使您的生活更简单,代码更安全

我不熟悉PDO,但我敢打赌它提供了一种机制,可以使用同一个函数调用中给定的值运行参数化查询,如果您不想准备,那么可以作为单独的步骤运行。(例如,类似于
run_query(“SELECT*FROM users,其中id=?”,1)
或类似的内容。)


此外,如果您仔细观察,大多数db抽象层将准备查询,然后运行它,即使您只是告诉它执行静态SQL语句。因此,不管怎样,您可能没有通过避免显式准备来节省到数据库的行程。

您错过了一个:智能地引用传递给它的数据。错过了一个,但不是那个。准备好的语句的参数通过一个单独的通道传递给db服务器(即,不作为SQL语句的一部分),因此它们根本不需要转义,因为它们明确地以数据的形式传入,而不是作为一个潜在的命令。这不会改变任何效率,或者更糟。SQL是在服务器上编译的,而不是在客户端。因此,当您发送一个带有绑定参数的准备好的语句时,您实际上向服务器发送了多个数据包(一个用于t