代码之家  ›  专栏  ›  技术社区  ›  Mouser

如何用PDO替换MySQL函数?

  •  7
  • Mouser  · 技术社区  · 10 年前

    阅读时 php.net 关于 MySQL函数 。我遇到了此消息

    警告 自PHP 5.5.0起,此扩展已被弃用,将来将被删除。相反,应该使用MySQLi或PDO_MySQL扩展。更多信息,请参见MySQL:选择API指南和相关常见问题解答。该功能的替代方案包括:

    我读过PDO。如何使用MySQL或MSSQL将代码更新为PDO?

    1 回复  |  直到 10 年前
        1
  •  19
  •   Dharman Aman Gojariya    5 年前

    我看到了很多关于SO实现的代码 my_sql函数 。其他人(包括我自己)的评论迫使提问者放弃 MySQL函数 并开始使用PDO或MySQLI。本文旨在帮助您。你可以参考它,因为它解释了为什么它们被弃用,以及什么 个人数字助理 加上实现PDO的最小代码示例。

    首先:

    转换自 mysql函数 个人数字助理 不是简单的搜索和替换。PDO是PHP语言的面向对象编程插件。 这意味着编写代码的另一种方法与 mysql函数 。首先,为什么要转换?

    为什么 mysql函数 已弃用?

    mysql扩展很古老,自15年前发布的PHP2.0(!!)以来就一直存在;这与试图摆脱过去不良做法的现代PHP截然不同。mysql扩展是mysql的一个非常原始、低级的连接器,它缺乏许多方便的特性,因此很难以安全的方式正确应用;因此,这不利于任何人。许多开发人员不理解SQL注入,而mysql API非常脆弱,即使你知道,也很难阻止它。它充满了全局状态(例如隐式连接传递),这使得编写难以维护的代码变得容易。由于它已经过时了,在PHP核心级别维护它可能是不合理的困难。

    mysqli扩展更新了很多,并修复了上述所有问题。PDO也很新,也解决了所有这些问题,还有更多问题。

    由于这些原因,mysql扩展将在未来某个时候删除。

    来源 Deceze

    如何实施PDO

    PDO为连接到多个数据库提供了一种解决方案。此答案仅涵盖 MySQL数据库 MSSQL语言 服务器。

    连接到 MySQL数据库 数据库,前提条件

    这非常简单,不需要预先设置PHP。现代PHP安装标准附带一个模块,允许PDO连接到MySQL服务器。

    模块为 php_pdo_mysql.dll

    连接到 MSSQL语言 数据库,前提条件

    这是一种更高级的设置。你需要 php_pdo_sqlsrv_##_ts.dll php_pdo_sqlsrv_##_nts.dll drivers 。它们是特定于版本的,因此 ## 。在撰写本文时,微软发布了 PHP 5.5.x的官方驱动程序。5.6驱动程序尚未由Microsoft正式发布,但可以通过 others .

    模块为 php_pdo_sqlsrv###_ts.dll 对于线程安全变体 模块为 php_pdo_sqlsrv_##_nts.dll 对于非线程安全变体

    使用PDO连接到数据库 要连接到数据库,需要创建 新PDO实例 来自 PDO构造 .

    $connection = new PDO(arguments);
    

    PDO构造函数接受1个必需参数和3个可选参数。

    1. DSN或 数字资源命名 ,通常这是一个字符串,包含有关驱动程序、主机和数据库名称的信息。从PHP 7.4开始,它还可以包括用户名和密码。
    2. 用户名
    3. 暗语
    4. 选项

    正在连接到 MySQL数据库

    $dsn = 'mysql:dbname=databasename;host=127.0.0.1';
    $user = 'dbuser';
    $password = 'dbpass';
    
    $dbh = new PDO($dsn, $user, $password);
    

    让我们来看看 $dsn :首先定义驱动程序( mysql ). 然后是数据库名称,最后是主机。

    正在连接到 MSSQL语言

    $dsn = 'sqlsrv:Server=127.0.0.1;Database=databasename';
    $user = 'dbuser';
    $password = 'dbpass';
    
    $dbh = new PDO($dsn, $user, $password);
    

    让我们来看看 $dsn美元 :首先定义驱动程序( sqlsrv ). 然后是主机,最后是数据库名称。

    创建实例时,将与数据库建立连接。在执行PHP脚本期间,只需执行一次。

    您需要将PDO实例创建包装在 try-catch条款 。如果创建失败,将显示一个回溯跟踪,显示有关应用程序的关键信息,如用户名和密码。为了避免这种情况,请抓住错误。

    try 
    {
        $connection = new PDO($dsn, $user, $password);
    }
    catch( PDOException $Exception ) 
    {   
         echo "Unable to connect to database.";
         exit;
    }
    

    要抛出SQL server返回的错误,请使用 setAttribute : $connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

    正在执行查询

    PDO使用 编制的报表 。这是 PDO的 方法和 mysql函数 后者非常容易受到 SQL注入 。可以构建如下查询:

    $SQL = 'SELECT ID FROM users WHERE user = '.$username ;
    

    当恶意网站或个人发布用户名时 injector; DROP TABLE users 。结果将是毁灭性的。您需要通过用引号转义和封装字符串和变量来验证代码。这是必须做的 对于每个查询。在较大的网站或维护较差的代码上,使用允许SQL注入的表单的风险可能会非常高。准备好的语句消除了像上面的示例一样的第一层SQL注入的机会。

    PDO驱动程序充当PHP服务器和数据库服务器之间的中间人,称为 数据访问抽象 层它不会重写SQL查询,但提供了一种连接到多个数据库类型的通用方法 并为您处理向查询中插入变量。 Mysql函数 构造了PHP代码执行的查询。使用PDO,查询实际上是在数据库服务器上构建的。

    准备好的SQL示例:

    $SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
    

    注意差异;而不是使用PHP变量 $ 在字符串之外,我们使用 : 在字符串中。另一种方法是:

    $SQL = 'SELECT ID, EMAIL FROM users WHERE user = ?';
    

    如何执行实际查询

    PDO实例提供了两种执行查询的方法。当您没有变量时,可以使用 query() ,使用变量 prepare() . 查询() 在调用时立即执行。请注意呼叫的面向对象方式( -> ).

    $result = $connection->query($SQL);
    

    制备方法

    这个 制备方法 有两个参数。第一个是SQL字符串,第二个是数组形式的选项。一个基本的例子

    $connection->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
    

    在我们的SQL字符串示例中,我们使用了一个名为 :username 。我们仍然需要将一个PHP变量、整数或字符串绑定到它。我们可以通过两种方式实现。将包含命名变量的数组构建为 key 或使用该方法 bindParam bindValue . 我将解释数组变量和方法 bindValue(绑定值) 为了简单起见。

    Array
    您可以对命名变量执行类似的操作,其中提供 变量 数组关键字 :

    $queryArguments = array(':username' => $username);
    

    对于索引变量( ? ):

    $queryArguments = array($username);
    

    添加完所需的所有变量后,可以调用该方法 execute() 以执行查询。从而将数组作为参数传递给函数 execute .

    $result = $connection->execute($queryArguments);
    

    bindValue(绑定值)
    这个 bindValue(绑定值) 方法允许您将值绑定到 PDO实例 。该方法接受两个必需参数和一个可选参数。可选参数设置值的数据类型。

    对于命名变量:

    $connection->bindValue(':username', $username);
    

    对于索引变量:

    $connection->bindValue(1, $username);
    

    将值绑定到实例后,可以调用 处决 而不传递任何参数。

    $result = $connection->execute();
    

    注意:只能使用一次命名变量!两次使用它们将导致执行查询失败。根据您的设置,这将或不会引发错误。

    正在获取结果

    再次,我将只介绍从返回集获取结果的基本知识。PDO是一个相当高级的插件。

    使用 fetch fetchAll

    如果你做了 选择查询 或执行 存储过程 返回了一个结果集:

    取来
    取来 是一个最多可以使用三个可选参数的方法。它从结果集中提取一行。默认情况下,它返回 大堆 包含列名称作为关键字和索引结果。 我们的示例查询可能返回如下内容

    ID      EMAIL
    1       someone@example.com
    

    取来 将返回为:

    Array
    (
        [ID] => 1
        [0] => 1
        [EMAIL] => someone@example.com
        [1] => someone@example.com
    )
    

    要回显结果集的所有输出,请执行以下操作:

    while($row = $result->fetch())
    {
        echo $row['ID'];
        echo $row['EMAIL'];
    }
    

    您可以在此处找到其他选项: fetch_style ;

    全部获取
    获取单个数组中的所有行。使用与相同的默认选项 取来 .

    $rows = $result->fetchAll();
    

    如果使用的查询不返回结果,例如插入或更新查询,则可以使用该方法 rowCount 检索受影响的行数。


    一个简单的类:

    class pdoConnection {
        public $isConnected;
    
        protected $connection;
    
        public function __construct($dsn, $username, $password, $options = array()) {
            $this->isConnected = true;
            try {
                $this->connection = new PDO($dsn, $username, $password, $options);
                $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                $this->connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); //sets the default to return 'named' properties in array.
            } catch (PDOException $e) {
                $this->isConnected = false;
                throw new Exception($e->getMessage());
            }
        }
    
        public function disconnect() {
            $this->connection = null;
            $this->isConnected = false;
        }
    
        public function query($SQL) {
            try {
                $result = $this->connection->query($SQL);
                return $result;
            } catch (PDOException $e) {
                throw new PDOException($e->getMessage());
            }
        }
    
        public function prepare($SQL, $params = array()) {
            try {
                $result = $this->connection->prepare($SQL);
                $result->execute($params);
                return $result;
            } catch (PDOException $e) {
                throw new PDOException($e->getMessage());
            }
        }
    }
    

    如何使用:

    $dsn = 'mysql:dbname=databasename;host=127.0.0.1';
    $user = 'dbuser';
    $password = 'dbpass';
    
    $db = new pdoConnection($dsn, $user, $password);
    
    $SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
    $result = $db->prepare($SQL, array(":username" => 'someone'));
    
    while($row = $result->fetch())
    {
        echo $row['ID'];
        echo $row['EMAIL'];
    }