• 从 MySQL 扩展迁移到 PDO


    本指南是一个实用概述,可帮助您开始将现有 PHP 代码从使用较旧的 MySQL 扩展迁移到较新的 PDO 数据库抽象扩展。我不会介绍 PDO 提供给您的所有功能,但我与您分享您需要了解的基本方法并提供一些提示,以便您的迁移尽可能快速和轻松。

    首先,您应该了解 PDO 在 PHP 生态系统中的位置。实际上有三种方法可以通过 PHP 与 MySQL 数据库交互:第一种是使用 MySQL 扩展,第二种是使用 MySQLi 扩展,第三种是使用 PDO。

    MySQL 扩展是三者中最古老的,并且是开发人员用来与 MySQL 通信的原始选项。由于在 PHP 和 MySQL 的较新版本中进行了改进,该扩展现在已被弃用,取而代之的是其他两个替代方案。

    MySQLi 是用于处理 MySQL 数据库的“改进”扩展。它利用了较新版本的 MySQL 服务器中可用的功能,向开发人员公开了面向函数和面向对象的接口,并做了一些其他漂亮的事情。如果 PDO 不适合您的项目,那么这就是您应该使用的扩展。

    然后最近的扩展是 PDO,它代表“PHP 数据对象”。PDO 提供了一个 API,它整合了以前分布在主要数据库访问扩展(即 MySQL、PostgreSQL、SQLite、MSSQL 等)中的大部分功能。该接口公开了高级对象,供程序员使用数据库连接、查询和结果集和低级驱动程序执行与数据库服务器的通信和资源处理。大量的讨论和工作正在进入 PDO,它被认为是在现代、专业的代码中使用数据库的适当方法。

    如果可能的话,我建议人们跳过中间人,从 MySQL 扩展迁移到 PDO 而不是 MySQLi。PDO 提供了一致的 API 来处理各种数据库,因此如果您不得不使用其他数据库,则无需修改您的 PHP 代码。此外,虽然 MySQLi 扩展目前仍在维护,但它总有可能在未来被弃用。现在选择迁移到 PDO 意味着您以后不必迁移到它并更新您的代码两次。我使用 PDO,你也应该使用!

    安装和配置 PDO

    一旦决定要对代码进行现代化改造,就需要确保正确设置和配置 PDO。正如我之前提到的,PDO 由两部分组成:暴露接口的扩展本身和特定于数据库的低级驱动程序。存在用于不断增长的数据库列表的驱动程序,包括 MySQL。

    PDO 和特定于 SQLite 的驱动程序应该是从 5.1.0 版开始的默认 PHP 安装的一部分,并且仍然需要安装特定于 MySQL 的驱动程序,但是大多数 Linux 发行版通常对如何编译和打包 PHP 有不同的想法。事实上,许多主要发行版现在都将 MySQL 扩展、MySQLi 扩展和 MySQL PDO 驱动程序打包在同一个包中。如果您在这样的系统上使用 MySQL,那么很可能已经为您设置了 PDO。

    • Ubuntu 使用 PDO 构建 PHP(但默认不打包 SQLite 驱动程序)并将 MySQL 扩展和驱动程序捆绑在一起。您可以通过运行来安装扩展和驱动程序sudo apt-get install php5-mysql
    • Fedora 还将扩展和驱动程序捆绑在一起,但将 PDO 打包为可加载模块。运行sudo yum install php-mysql会安装 MySQL 扩展和驱动程序,并且该php-pdo包将自动作为依赖项包含在内。
    • SUSE 是三者中唯一一个按照 PHP 团队推荐的 PDO 方式构建 PHP 的发行版;他们使用 PDO 构建 PHP包含 SQLite 驱动程序。yast2 --install php5-mysql将安装您需要的 MySQL 扩展和驱动程序。

    在 Windows 上,所有 PDO 驱动程序都包含在 ext 文件夹中,该文件夹是您从预编译二进制文件的存档中安装 PHP 时创建的。您只需要php.ini通过添加或取消注释来更新您的行:

    extension=php_pdo_mysql.dll
    

    在更坏的情况下,总是可以自己编译驱动程序。确保 MySQL 库和其他开发文件已安装并可在您的构建环境中访问,因为人们在尝试编译某些东西时遇到的大多数问题都是在编译器找不到各种头文件或要链接的库时导致的。

    基本查询

    使用 MySQL 扩展的函数处理数据库的基本工作流程可以被认为是一个 5 步过程:

    1. 建立与数据库服务器的连接并选择您将使用的数据库
    2. 构造查询以发送服务器
    3. 发送查询
    4. 迭代返回的结果行
    5. 释放结果使用的资源,可能还有数据库连接
    1. // Step 1: Establish a connection
    2. $db = mysql_connect("localhost", "testusr", "secretpass");
    3. mysql_select_db("testdb", $db);
    4. // Step 2: Construct a query
    5. $query = "SELECT * FROM foo WHERE bar = '" . mysql_real_escape_string($zip) . "'";
    6. // Step 3: Send the query
    7. $result = mysql_query($query, $db);
    8. // Step 4: Iterate over the results
    9. while($row = myql_fetch_assoc($result)) {
    10. print_r($row);
    11. }
    12. // Step 5: Free used resources
    13. mysql_free_result($result);
    14. mysql_close($db);

    使用 PDO,可以遵循相同的过程,如下所示:

    1. // Step 1: Establish a connection
    2. $db = new PDO("mysql:host=localhost;dbname=testdb", "testusr", "secretpass");
    3. // Step 2: Construct a query
    4. $query = "SELECT * FROM foo WHERE bar = " . $db->quote($zip);
    5. // Step 3: Send the query
    6. $result = $db->query($query);
    7. // Step 4: Iterate over the results
    8. while($row = $result->fetch(PDO::FETCH_ASSOC)) {
    9. print_r($row);
    10. }
    11. // Step 5: Free used resources
    12. $result->closeCursor();
    13. $db = null;

    连接到服务器并使用 PDO 选择数据库的过程是使用 DSN 而不是myql_connect()and执行的mysql_select_db()。DSN 是“数据源名称”的缩写,它是一个字符串,用于标识用于与数据库通信的 PDO 驱动程序,并传达任何重要的连接信息,例如主机服务器、连接端口和数据库名称。根据您的数据库,您提供的 DSN 的格式可能会有所不同。每个驱动程序所需的主要组件都记录在 php.net 上,但不幸的是,它们有时很难找到。我建议使用站点的搜索功能在在线文档中查找术语“DSN” 。

    另请注意,PDO::quote()转义引用一个值,而mysql_real_escape()只转义该值。您应该牢记这一点,这样您就不会在最终查询中出现额外的引号,并且不知道它们是从哪里来的。

    虽然有时您可以在不释放结果资源的情况下逃脱,但mysql_free_result()我建议您在使用 PDO 时不要养成这种懒惰的习惯。如果您仍然有一个SELECT尚未调用的查询的结果集,closeCursor()并且您尝试在表上执行INSERTor UPDATE,则更改可能会默默地失败,并且您将再次摸不着头脑。最好养成正确做事的习惯,以避免以后出现令人沮丧的情况。

    挖掘(稍微)更深

    到目前为止所涵盖的内容足以让您开始尽可能快速、轻松地将 PHP 应用程序从 MySQL 迁移到 PDO,但是 PDO 的内容比我向您展示的要多。我还想强调 PDO 的其他一些您可能会发现有用的特性:准备好的语句和错误处理。

    准备好的报表

    准备好的语句是将查询表示为对象。将查询表示为对象的好处是可以将额外的逻辑与它相关联,否则对于平面字符串表示而言,这些逻辑很难管理。例如,您可以在查询中指定占位符,然后将其绑定到脚本中的变量。如果您多次运行相同的查询以满足请求但使用不同的参数,这将很有帮助。查询只需要准备一次,但可以随着变量值的变化以不同的值运行多次。

    1. // collection of user information to import into the database
    2. $users = ...
    3. // specify the query "template"
    4. $query = $db->prepare("INSERT INTO users (first_name, last_name, email) VALUES (:fname, :lname, :email)");
    5. // bind the placeholder names to specific script variables
    6. $query->bindParam(":fname", $firstName);
    7. $query->bindParam(":lname", $lastName);
    8. $query->bindParam(":email", $email);
    9. // assign values to the specific variables and execute the query
    10. foreach ($users as $u) {
    11. $firstName = $u["first_name"];
    12. $lastName = $u["last_name"];
    13. $email = $u["email"];
    14. $query->execute();
    15. }

    参数不必用准备好的语句引用或转义,因为底层驱动程序会自动为您引用和转义任何绑定参数。正因为如此,许多人喜欢使用准备好的语句来防范 SQL 注入漏洞,即使查询只执行一次。

    错误处理

    您可以使用 PDO 指定三种不同的错误处理范例之一PDO::setAttribute()来设置错误处理模式。

    1. $db = new PDO($dsn, $user, $passwd);
    2. $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    模式是:

    • 静默模式 ( PDO::ERRMODE_SILENT) – 设置内部错误代码但不中断脚本的执行(这是默认设置)
    • 警告模式 ( PDO::ERRMODE_WARNING) – 设置错误代码并触发 E_WARNING 消息
    • 异常模式 ( PDO::ERRMODE_EXCEPTION) – 设置错误代码并抛出 PDOException 对象

    无论设置哪种模式,都会设置一个内部错误代码,您可以使用and对象的errorCode()anderrorInfo()方法检查。这些类似于和。返回ANSI SQL-92 中定义的 5 个字符的字符串。通常更有用,因为它返回一个数组,其中除了 5 个字符的代码之外还包含错误消息。PDOPDOStatementmysql_errno()mysql_error()errorCode()errorInfo()

    1. $query = "SELECT * FROM foo WHERE MALFORMED QUERY";
    2. $result = $db->query($query);
    3. $error = $db->errorInfo();
    4. if (!is_null($error[2])) {
    5. echo "Query failed! " . $error[2];
    6. }
    7. ...

    getMessage()如果您使用异常模式,则可以通过异常对象的方法获得对出错原因的描述。

    1. $query = "SELECT * FROM foo WHERE MALFORMED QUERY";
    2. try {
    3. $result = $db->query($query);
    4. ...
    5. }
    6. catch (PDOException $e) {
    7. echo $e->getMessage();
    8. }

    概括

    现在您应该具备开始从旧的 MySQL 扩展迁移到新的 PDO 扩展所需的基本知识。您已经看到,虽然大部分时间 PDO 已经可用,但如果由于某种原因它不可用,则很容易设置。您还看到了连接到 MySQL 数据库服务器、发出查询和接收结果是多么容易。当然,这只是一个实用的概述;要了解更多关于 PDO 必须提供什么以及如何利用它的信息,我鼓励您阅读 php.net 上的可用文档

     

  • 相关阅读:
    计算机毕设 基于大数据的抖音短视频数据分析与可视化 - python 大数据 可视化
    基于IDEA的Maven(依赖介绍和引用)
    一个 nginx 通过不同域名映射多个前端项目
    docker系列:dockerfile及其用法解析
    资深工程师整理《数字后端春招面经总结》(附下载)
    Vue思维导图,复习+预习,其中有些已经弃用了,下期总结下
    centos 7 yum install -y nagios
    【Android进阶】13、对话框
    【Acwing】背包
    C++ Qt开发:QFileSystemModel文件管理组件
  • 原文地址:https://blog.csdn.net/allway2/article/details/126869871