您的位置:首页 > 编程语言 > PHP开发

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

2014-11-04 22:54 337 查看
  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的依赖性!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: