PDO - 真实的事实和最佳实践? [关闭]

Posted

技术标签:

【中文标题】PDO - 真实的事实和最佳实践? [关闭]【英文标题】:PDO - real facts and best practice? [closed] 【发布时间】:2012-07-01 22:09:10 【问题描述】:

从现在开始,我一直在使用旧的 mysql 而不是 PDO,并且我已经看到了很多建议为什么要切换到 PDO,但也有许多不同的事实(也在这里),例如:

声明PDO 稍快/稍慢 说 PDO 有助于防止 SQL 注入,但前提是您使用准备好的查询 还说使用准备好的查询很糟糕,因为它太慢了

那么,什么是真实的?尤其是使用PDO 时的最佳实践是什么?速度和安全性都很重要——如何在保持快速查询的同时最好地保护自己免受 SQL 注入?

【问题讨论】:

为什么“老”在引号里?它旧的,也被弃用了。 方便。一切都是为了方便。使用准备好的语句可以为您节省繁琐的手动转义部分。这是一个副作用,但几乎消除了 SQL 注入。您仍然会在某些时候连接动态查询,因此忽略转义和上下文不是一种选择。但准备好的陈述涵盖了大多数情况。 -- 是否更快取决于您当前的设置和使用情况,只有分析器才能判断,而不是 meme。 我知道使用PDO::quote(),这取决于你在做什么。我认为让您理解这一点的最佳方法是了解准备好的语句实际上 做什么 - 他们将查询发送到数据库服务器进行解析和准备,然后当您调用 execute() 他们发送数据这将用于占位符并检索结果。因此,对于只运行一次的语句,这是更多的数据库流量,它会(非常非常轻微地)减慢速度...... ...但是(一个常见的例子)对于许多使用略有不同数据的UPDATEs,它可以大大加快速度,因为查询被解析并且执行计划只设计一次,唯一的变体是执行期间使用的数据。 PDO::quote() 不仅会转义字符串,还会引用它。另一方面, mysql_real_escape_string() 只会转义字符串。始终建议使用准备好的语句而不是 PDO::quote() 和 mysql_real_escape_string()。 【参考方案1】:

数据库支持

PDO 相对于 MySQL 的核心优势在于其对数据库驱动程序的支持。 PDO 支持许多不同的驱动程序,例如 CUBRID、MS SQL Server、Firebird/Interbase、IBM、MySQL 等。

安全

这两个库都提供 SQL 注入安全性,只要开发人员按照预期的方式使用它们。建议将准备好的语句与绑定查询一起使用。

// PDO, prepared statement
$pdo->prepare('SELECT * FROM users WHERE username = :username');
$pdo->execute(array(':username' => $_GET['username']));

// mysqli, prepared statements
$query = $mysqli->prepare('SELECT * FROM users WHERE username = ?');
$query->bind_param('s', $_GET['username']);
$query->execute();

速度

虽然 PDO 和 MySQL 都相当快,但 MySQL 在基准测试中的执行速度微乎其微——非准备语句约为 2.5%,准备语句约为 6.5%。

命名参数

就像@DaveRandom 指出的那样,这是 PDO 的另一个特性,它比可怕的数字绑定要容易得多。

$params = array(':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600);

$pdo->prepare('
SELECT * FROM users
WHERE username = :username
AND email = :email
AND last_login > :last_login');

$pdo->execute($params);

几个链接供进一步参考MySQL vs PDO (***)Why you should be using PDO for database access (net.tutsplus.com)

【讨论】:

While both PDO and MySQL are quite fast,您是将 PDO 与 mysqli_*(如您的示例代码中所示)还是 mysql_* 进行比较?另请注意,PDO 也可以与binding values 一起使用,如果您需要/想要在调用execute() 之前绑定它们。 MySQLi 的 PDO 的其他主要优点是能够使用命名占位符,而不必处理您 需要bind_param()/@987654332 的 MySQLi 的 STUPID 接口@ 并且您不能只传递/检索数组,从而导致创建显式引用数组的可怕函数和令人讨厌的不可读 call_user_func_array() 构造 "PDO 支持许多不同的驱动程序,例如 CUBRID、MS SQL Server、Firebird/Interbase、IBM、MySQL 等" - 是的,但由于它们的 SQL 方言不同,所有 DDL 或非平凡的 DML 都会必须考虑到这一点。所以不,PDO 不是跨数据库的灵丹妙药。 谢谢 Abhishek,这是一个很棒的答案!也感谢您提供比较的实际示例!太棒了!【参考方案2】:

在大多数情况下,开发速度(编写软件需要多长时间)比性能的微小改进更重要。

我建议使用 PDO,并将其与准备好的查询一起使用。除非您是 Twitter 或 Google,否则您几乎不可能意识到任何性能差异。

【讨论】:

以上是关于PDO - 真实的事实和最佳实践? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用 PDO 处理错误的最佳实践

使用 PDO 处理错误的最佳实践

构造函数重载 - Java 中的最佳实践 [关闭]

Ansible最佳实践之委派任务和事实

Ansible最佳实践之委派任务和事实

jQuery 标准和最佳实践 [关闭]