首页 > 代码库 > PHP-MySQL,PHP-MySQLi,PDO的差异

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的依赖性!

PHP-MySQL,PHP-MySQLi,PDO的差异