当我在 Zend Framework 1.0 中开发 DB 层时,我让它默认对所有查询使用准备/执行。这样做几乎没有缺点。* PHP 端有一点开销,但在 MySQL 端,准备好的查询实际上更快。
我的做法是对所有类型的查询使用 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 benchmark”(例如)以查找各种结果。然而,底线是选择 PDO 与 Mysqli 并没有明确的赢家。差异很小,以至于相对于其他更重要的优化技术(例如选择正确的索引、确保索引适合 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 注入神话和谬误”中阅读有关 SQL 注入防御的更多信息。