2.2. 连接并查询 MySQL 数据库

未匹配的标注

使用 PDO 及其预处理语句功能。

在 PHP 中,有许多方法可以连接到 MySQL 数据库。PDO (PHP 数据对象)是其中最新、最健壮的。它在多种不同类型的数据库之间具有一致的接口,使用面向对象的方式,支持更多新数据库提供的特性。

你应该使用 PDO 的预处理语句函数来帮助防止 SQL 注入攻击。使用 bindValue() 函数确保 SQL 免于一阶 SQL 注入攻击。(但这并不是100%安全的,更多细节请参阅 延伸阅读。)在过去,这必须通过一些难懂的 “魔术引号(magic quotes)” 函数组合来实现。PDO 使那堆东西变得不再必要。

范例

<?php
// 创建一个新连接。
// 你可能要用 localhost 替换第一个参数的 hostname。
// 注意我们如何将字符集声明为 utf8mb4。这会告知连接,我们将传递 UTF-8 格式的数据。根据你的配置这可能不是必选的,但如果你准备在数据库中存储 Unicode 字符串,这样做能为你减少很多麻烦。参见“要点”一节。
// 我们传入的 PDO 选项执行以下操作:
// PDO::ATTR_ERRMODE 允许在错误时抛出异常。这是个可选项,但相当有用。
// PDO::ATTR_PERSISTENT 禁用持续连接,因为在某些情况下会导致并发问题。参见"要点"一节。

$link = new PDO(    'mysql:host=your-hostname;dbname=your-db;charset=utf8mb4',
                    'your-username',
                    'your-password',
                    array(
                        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                        PDO::ATTR_PERSISTENT => false
                    )
                );

$handle = $link->prepare('select Username from Users where UserId = ? or Username = ? limit ?');

$handle->bindValue(1, 100);
$handle->bindValue(2, 'Bilbo Baggins');
$handle->bindValue(3, 5);

$handle->execute();

// 如果同时查询行数过多,使用 fetchAll() 方法可能会占用大量资源。
// 在这种情况下,可以使用 fetch() 方法循环遍历每个结果行。
// 你还可以返回数组和其他格式,而不是对象类型。有关详情请参阅 PDO 文档。
$result = $handle->fetchAll(PDO::FETCH_OBJ);

foreach($result as $row){
    print($row->Username);
}

要点

  • 未将连接字符串中的字符集设置为 utf8mb4,可能会导致 Unicode 数据在数据库中存储不正确,这会取决于你的配置。
  • 即使已经将字符集声明为 utf8mb4,也要确认实际的数据库表的确使用了 utf8mb4 字符集。关于为什么使用 utf8mb4 而不仅仅是 utf8,请查看 PHP and UTF-8 章节。
  • 启用持久连接可能会导致奇怪的并发问题。这不是 PHP 层面的问题,而是应用程序级的问题。只要分析考虑过后果,持久连接也是可以安全使用的。请参阅 这个 Stack Overflow 问题

延伸阅读

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/phpbestpractice...

译文地址:https://learnku.com/docs/phpbestpractice...

上一篇 下一篇
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~