我想重写使用的是InnoDB(mysql_query中的MyISAM现在)我的目的PDO和交易的一些开放源代码的应用程序。
我的问题是:哪些情况下是合理的使用预处理语句?
因为无论我正在读的规定(即使在这里的很多文章),我应该用准备好的语句每次和无处不在,因为1.安全性和性能2中。 即使PHP手册建议使用预处理语句,而不是提逃生的事情。
你不能否认的安全机制。 但遍地谈到介意,有准备的发言,每次再使用一次。它没有任何意义想它。 虽然有单语句插入1000次一些变数,这是有道理的,但它是显而易见的。 但是,这是不是有什么常见的网上商店或板在建。
那么如何克服呢? 我可以准备我的报表应用程序范围,并给他们具体的名字? 我可以准备几个不同的财务报表和名称使用它们? 因为这是唯一合理的解决方案我想到的(除了1000倍的东西)。
我发现有这个mysql_real_escape名为$ pdo->报价以及对单个查询的目的。 为什么不用呢? 为什么有准备费心呢?
那你认为这是什么好文章吗? http://blog.ulf-wendel.de/2008/pdo_mysqlnd-prepared-statements-again/
你引起的编制报表的开销同意吗?
谢谢
我认为这属于“过早优化”的范畴。
如何显著是开销? 你已经测量了吗? 它会影响您的服务器的性能呢?
奇怪的是它没有。
从积极的一面,你必须在安全方面一个不可否认的增益(这应该是任何基于互联网的商店一个主要问题)。
不利的一面,你有,它可能会影响性能的风险。 在你所提供的链接,它表明,在比在某些情况下非事先准备好的声明中性能稍有降低执行不力PDO准备的结果。 在5000组的运行性能差异0.298秒。
微不足道。 更所以,当你认识到“不备”查询,而不输入消毒,将被要求使他们在实际环境中安全运行的程序。 如果你不使用准备查询,你需要某种形式的输入消毒,以防止SQL攻击,这取决于它是如何做,你可能需要按摩背部的结果集。
底线,没有显著的性能问题,但有一个显著的安全利益。 因此,使用预处理语句的官方推荐。
在您的问题,“常见的网上商店”的发言。 “共同网上商店”永远不会有足够的流量,不用担心性能问题,如果有一个。 在另一端的安全问题...
我的问题是:哪些情况下是合理的使用预处理语句?
他们都是。 社区是公开,反对的使用mysql_*
功能。
注:建议方案
这个扩展的使用气馁。 相反,应使用的MySQLi或PDO_MYSQL扩展。 另请参见MySQL的:选择一个API的更多信息。
替代该功能包括:
-
mysqli_connect()
-
PDO::__construct()
资源
但思前想一遍又一遍谈到介意,有准备的发言每次都再一次使用它。它没有任何意义
你的交易在一个地理的捷豹和你抱怨你不喜欢捷豹的,因为你不经常使用的座椅加热器。 您不必使用图书馆的每一个功能意味着它是很好的一致。
我发现有这个mysql_real_escape名为$ pdo->报价以及对单个查询的目的。 为什么不用呢? 为什么有准备费心呢?
如果您在使用此功能来构建SQL语句,我们强烈建议您使用PDO ::准备()准备与绑定参数,而不是使用PDO ::引用()的SQL语句对用户输入插成的SQL语句。 与绑定参数准备好的语句不仅更加轻便,更加方便,不受SQL注入,但往往要快得多比插值查询执行,同时作为服务器和客户端可以缓存查询的编译形式。 资源
我的问题是:哪些情况下是合理的使用预处理语句?
嗯,事实上,这是很难说。 尤其是当你甚至没有告诉你谈谈这里它的开源应用。
给你举个例子:对于准备语句的超跛脚留言板应用程式PDO将是完美的选择,以及99%其他开源应用程式的外面。 但对于一些这实际上可以有所作为。 这里最重要的部分是:你还没告诉有关应用程序的任何事情。
由于数据库不是不重要的应用程序,这是另一种方式圆以及:应用程序是不是不重要的数据库。
所以,你要么需要分享更多关于你问有关“神秘”的开放源代码的应用程序或您的需要告诉我们,正是你想知道什么。 因为一般情况下,这很简单:以PDO。 但在具体的,有差异,所以你需要告诉我们具体的应用是什么,否则你的问题已经回答。
和顺便说一句,如果应用程序是mysql_ *的风格,它更容易只是mysqli_ *接口替代。 如果你已经做了一些实际重写,甚至只是为了好玩,你会看到这一点。
因此,更好地在这里添加更多的肉或一些不那么准确的答案居住。
虽然这个问题已很旧,有的题目并没有真正讨论此处应该概括为他人研究一样的OP。
总结下的所有内容:
- 是始终使用准备的语句
- 是对MySQL使用PDO了mysqli的。 这样,如果你切换数据库系统,所有你需要做的是更新查询,而不是查询,函数调用和参数给出它支持预处理语句。
- 总是清理用户尽管使用准备的语句与参数提供的数据
- 寻找到一个DBAL(数据库抽象层),以缓和与所有这些因素和操作查询工作,以满足您的需求。
有PDO :: ATTR_EMULATE_PREPARES这将增加在MySQL> = 5.1.21时仿真关闭,这是默认启用的调用缓存查询性能的话题。 含义PHP将模拟运行准备之前将其发送到实际的数据库。 之间仿真和非模拟的时间是可以忽略不计,通常,除非与外部数据库的工作(不是localhost),如在云,可具有异常高的平率。
缓存取决于在my.cnf你的MySQL设置为好,但这篇文章的范围之外的MySQL优化。
<?php
$pdo = new \PDO($connection_string);
$pdo->setAttribute( \PDO::ATTR_EMULATE_PREPARES, false );
?>
所以,请记住这一点,因为mysqli_不提供客户端仿真的API,并总是将使用MySQL准备语句。 http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
尽管有类似的功能有差异,您可能需要一个API提供,而其他没有的功能。 看到比其他选择一个API PHP的参考: http://www.php.net/manual/en/mysqlinfo.api.choosing.php
因此,这几乎与你的要求与定义你的报表应用程序范围内,可缓存查询将MySQL服务器上缓存,并且不会需要准备的应用范围随之而来。 另一个好处是,在您的查询的例外是在准备)被抛出(而不是执行()在开发这有助于确保您的疑问是正确的。
不管有使用准备与否没有现实世界中的性能优势。
预处理语句的另一个好处与交易工作,如果你使用InnoDB为MySQL。 你就可以开始交易,插入一条记录,得到最后插入的ID,更新另一个表,从另一个删除,如果有什么沿途失败,您可以回滚()之前交易发生。 如果你选择,否则提交更改。 例如一个新的秩序工作,并设置用户的最后订单列到新的订单ID,并删除挂单,但所提供的付款方式不符合标准从order_flags表订货,所以你可以回滚()并且向用户显示一个友好的错误消息。
至于安全,我宁愿莫名其妙没有人谈到这一点。 当发送任何用户提供的数据于包括PHP和MySQL任何系统,消毒和规范它。 是准备语句提供了一些安全性,当涉及到逃避的数据,但它不是100%防弹。
所以总是使用预处理语句远比不是更有益,没有真正的性能损失,并与缓存一些好处,但你还是应该净化你的用户提供的数据。 一个步骤是将变量强制转换为您正在使用所需的数据类型。 因为你,而不是让您每次使用相同的数据的工作时间来记住它的数据类型的单一模式中工作使用对象将进一步缓解这一点。
要添加到上面的你应该考虑使用PDO数据库抽象层。 例如主义DBAL: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/query-builder.html
用DBAL + PDO工作的附加好处是,
- 您可以标准化,缩短你所要做的工作量。
- 有助于用户提供的数据的消毒
- 轻松处理复杂查询
- 使用嵌套事务
- 数据库之间轻松切换
- 你的代码变得在其他项目中更便于携带和使用
比如我伸出PDO和推翻查询(),使用fetchall(),并获取()方法,使他们总是使用准备好的语句,并让我可以写SQL语句中取()使用fetchall(),而不必写再次一切了。 例如:
<?php
$pdo = new PDOEnhanced( $connection );
$pdo->fetchAll( "SELECT * FROM foo WHERE bar = 'hi'", PDO::FETCH_OBJ );
//would automatically provide
$stmt = $pdo->prepare( "SELECT * FROM foo WHERE bar=?" );
$stmt->execute( array( 'hi' ) );
$resultSet = $stmt->fetchAll( PDO::FETCH_OBJ )
?>
至于人们暗示mysql_ *的风格,是很容易只是mysqli_ * API取代。 这是不是这样的。 的mysql_ *函数的很大一部分被冷落或曾与mysqli_参数的变化*请参阅: http://php.net/manual/en/mysqli.summary.php
但是,您可以得到由Oracle发布了一个转换器,以缓解这一进程: https://wikis.oracle.com/display/mysql/Converting+to+MySQLi
请记住,它是一个文件源文本解析器,而不是100%准确的将它们合并之前,所以验证变更。 它还将增加开销显著量为它创建的全局。