zoukankan      html  css  js  c++  java
  • PHP-MySQL,PHP-MySQLi,PDO的差异

      PHP-MySQL是PHP操作MySQL数据库最原始的Extension ,PHP-MySQLi的i代表Improvement ,提供了更加高级的功能,就Extension而言,本身也增加了安全性。而PDO(PHP Data Object) 则是提供了一个 Abstraction Layer来操作数据库。我们通过代码来初步比较它们之间的差异。

      先来看一段PHP-MySQL的通用代码:

    <?php
     
        mysql_connect($db_host, $db_user, $db_password);
        mysql_select_db($dn_name);
     
        $result = mysql_query("SELECT `name` FROM `users` WHERE `location` = '$location'");
     
        while ($row = mysql_fetch_array($result,  MYSQL_ASSOC)) {
            echo $row['name'];
        }
     
        mysql_free_result($result);
     
    ?>

      这种方式的问题是不能Bind Column,容易被SQL注入(SQL注入后续会有文章讲到)。所以后来发展出mysql_escape_string() (注意:5.3.0之后弃用) 以及 mysql_real_escape_string()来解决这个问题。一般就会写成这样:

    <?php
     
        $query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
                mysql_real_escape_string($user),
                mysql_real_escape_string($password));
     
        mysql_query($query);
     
    ?>

      在PHP-MySQLi中有了不少改进,除了通过Bind Column来解决上述问题,而且也支持Transaction, Multi Query ,並且同時提供了Object oriented style,示例代码如下:

    <?php
     
        $mysqli = new mysqli($db_host, $db_user, $db_password, $db_name);
     
        $sql = "INSERT INTO `users` (id, name, gender, location) VALUES (?, ?, ?, ?)";
        $stmt = $mysqli->prepare($sql);
     
        $stmt->bind_param('dsss', $source_id, $source_name, $source_gender, $source_location);
     
        $stmt->execute();
     
        $stmt->bind_result($id, $name, $gender, $location);
     
        while ($stmt->fetch()) {
            echo $id . $name . $gender . $location;
        }
     
        $stmt->close();
        $mysqli->close();
     
    ?>

      可以看出这只中方式已经把PHP-MySQL的问题解决了,当然用MySQL是没有问题了,如果有一天我的数据库换成了oralce,postgresql,那就不好办了,代码需要大改。所以就PDO就出来了,它把数据库的操作抽象出来了,而不需要管底层用的是何种数据库。示例代码如下:

    <?php
     
        $dsn = "mysql:host=$db_host;dbname=$db_name";
        $dbh = new PDO($dsn, $db_user, $db_password);
     
        $sql = "SELECT `name`, `location` FROM `users` WHERE `location` = ? , `name` = ?";
        $sth = $dbh->prepare($sql);
     
        $sth->execute(array($location, $name));
     
        $result = $sth->fetch(PDO::FETCH_OBJ);
        echo $result->name . $result->location;
     
        $dbh = NULL;
     
    ?>

      这样做的好处有很多:

      1. PDO连接数据库时通过Connection String(如例子中的"mysql:host=$db_host;dbname=$db_name")来决定连接哪种数据库。

      2. PDO可以通过PDO::setAttribute来设置连接时的参数,像是Persistent Connection, 返回错误的方式(Exception, E_WARNING, NULL),甚至是返回类名称的大小等等。
      2. PDO支持Bind Column,除了基本的 Prepare, Execute 以外,也可以Bind单一列,并且知道列类型。
      4. PDO 是 Abstraction Layer,所以更换数据库所需修改的代码量很少。

    当然还有DBI方式,如ActiveRecord 以及 Propel ORM(Object-Relational Mapping)都非常好用。

    如ActiveRecord,如果现在要用PHP操作这样的sql语句:

    INSERT INTO `users` (id, name, gender, location) VALUES(1, 'roga', 'male', 'tpe')

    PDO的写法:

    <?php
     
        $sql = "INSERT INTO `users` (id, name, gender, location) VALUES(?, ?, ?, ?)";
        $sth = $dbh->prepare($sql);
     
        $sth->execute(array(1, 'roga', 'male', 'tpe'));
     
    ?>

    ActiveRecord的写法

    <?php
     
        $user = new User();
     
        $user->id = 1;
        $user->name = 'roga';
        $user->gender = 'male';
        $user->location = 'tpe';
     
        $user->save();
    ?>

      后者在写法上大大降低了对SQL的依赖性!

  • 相关阅读:
    use paramiko to connect remote server and execute command
    protect golang source code
    adjust jedi vim to python2 and python3
    install vim plugin local file offline
    add swap file if you only have 1G RAM
    datatables hyperlink in td
    django rest framework custom json format
    【JAVA基础】网络编程
    【JAVA基础】多线程
    【JAVA基础】String类的概述和使用
  • 原文地址:https://www.cnblogs.com/zhutianpeng/p/4075101.html
Copyright © 2011-2022 走看看