我对PDO有很多疑问......
我是否应该在有参数绑定时使用prepare()
?当我需要执行select * from table order by ...
这样的简单查询时,我应该使用query()
吗?
我在更新和删除操作时需要使用exec()
并且需要获取受影响的行数,还是应该使用PDOStatement->rowCount()
?
当我执行closeCursor
,insert
和update
时,我应该使用delete
,或者当我需要另外select
时{I} select
{1}}
$con = NULL;
是否真的关闭了连接?
使用bindParam
与foreach
一起使多个插页成为一个好点?我的意思是表现明智,因为我认为在同一insert
上做(...),(...)更好不是吗?
使用PHP PDO MySQL时,您能否提供一些有关性能点的更多信息(URL)?如果有人有其他提示,那将非常有用。
答案 0 :(得分:4)
当我在Zend Framework 1.0中开发数据库层时,我默认使用prepare / execute进行所有查询。这样做有一点缺点。* PHP方面有一点开销,但在MySQL方面,prepared queries are actually faster。
我的做法是对所有类型的查询使用query(),并在更新后调用rowCount()。您也可以致电SELECT
ROW_COUNT()
。
如果结果集中有待处理的行,或者多结果集查询中有待处理的结果集,则CloseCursor在MySQL中很有用。使用INSERT,UPDATE,DELETE时没有必要。
PDO_mysql测试套件关闭与$con=NULL
的连接,这是正确的方法。这实际上不会关闭由libmysqlnd管理的持久连接,但这是故意的。
一次执行一行准备好的INSERT语句不如执行具有多个元组的单个INSERT快。但差别很小。如果要插入大量行,并且性能很重要,则应该使用LOAD DATA LOCAL INFILE
。有关其他提示,另请参阅http://dev.mysql.com/doc/refman/5.6/en/insert-speed.html。
您可以谷歌搜索“PDO MySQL基准”(例如)以查找各种结果。然而,最重要的是,选择PDO与Mysqli没有明显的赢家。差别很小,相对于其他更重要的优化技术(例如choosing the right indexes),它会减少,确保索引适合RAM,并巧妙地使用应用程序端缓存。
*某些语句不能在MySQL中作为预准备语句运行,但每个主要版本的此类语句列表都会变小。如果您仍在使用无法使用prepare()运行某些语句的古老版本的MySQL,那么您应该在几年前进行升级!
重新评论:
是的,在大多数情况下,使用查询参数(例如使用bindValue()和bindParam())被认为是防范SQL注入的最佳方法。
请注意,使用PDO查询参数的方法更简单 - 您只需将数组传递给execute(),这样您就不必费心使用bindValue()或bindParam():
$sql = "SELECT * FROM MyTable WHERE name = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute( array("Bill") );
您也可以这样使用命名参数:
$sql = "SELECT * FROM MyTable WHERE name = :name";
$stmt = $pdo->prepare($sql);
$stmt->execute( array(":name" => "Bill") );
使用quote()然后将结果插入到查询中也是一种防止SQL注入的好方法,但是恕我直言使代码更难以阅读和维护,因为你总是想弄清楚你是否有关闭你的报价,把你的点放在正确的位置。使用参数占位符然后传递参数要容易得多。
您可以在我的演示文稿SQL Injection Myths and Fallacies中阅读有关SQL注入防御的更多信息。
答案 1 :(得分:-1)
大多数问题都可以通过常识来回答。所以,我在这里。
实际上并不重要。
绝对肯定 - 不。 Exec不使用准备好的陈述。就是这样。
真的不重要。如果您需要它,您的程序架构可能是错误的。
您可以自行轻松测试。个人经验总是首选。
差异被认为可以忽略不计。但是,如果您的多个插入速度非常慢(例如,在INNODB上使用默认设置),您必须使用一个事务,这将使它们再次快速。
没有。 PDO只是一个 API 。但API与性能无关。他们只是将您的命令转换为服务。这可能是您的命令或服务可能会影响性能,但不仅仅是API。
所以,经验法则是: