PHP数据对象(PDO)是PHP与数据库进行交互的一种替代方式。如果我们在项目中使用了PDO,那么更换数据库,只需要更改一行代码。要确定安装的PHP版本支持哪些数据库,可调用PDO类的getAvailableDrivers()方法。
print_r(PDO::getAvailableDrivers());
1、连接数据库
所有对PDO的自定义都发生在与数据库建立连接的过程中,通过创建PDO对象建立与数据库的连接。该过程通过new关键字完成。创建PDO对象需要向PDO类的构造函数传递三个参数。
$pdo = new PDO('dsn', 'username', 'password');
其中dsn是“Data Source Name”的缩写,用于指明:需要使用的数据库驱动、数据库名、主机名(可选)和端口号(可选),如果使用SQLite,还需要提供数据库文件的路径。
要构造dsn,首先要指明数据库驱动,举个例子,使用MySQL数据库驱动,访问localhost上的tset数据库,则正确的dsn为:
mysql:dbname=test;host=localhost
要关闭与数据库的连接,只要销毁PDO对象即可:
unset($pdo);
或者将PDO对象置空:
$pdo = NULL;
2、捕获异常
作为一个类,PDO不是生成错误而是抛出异常,即抛出PDOException类型异常。
try {
$pdo = new PDO('mysql:dbname=dnf_db;host=localhost', 'root', '');
unset($pdo);
} catch (PDOException $e) {
echo $e.getMessage();
}
3、执行简单查询
对于那些不返回结果的简单查询:INSERT(插入)、UPDATE(更新)和DELETE(删除),使用exec()方法,它使用需要执行的查询语句作为参数:
$q = "DELETE FROM tablename";
$pdo->exec($q);
对于这些查询,exec()方法将会返回影响到的函数(没有影响,就返回0;当查询出错时,返回false)。
如果只是执行了INSERT查询并且要知道动态生成的主键值,可调用lastInsertId()方法:
$id = $pdo->lastInsertId();
在执行简单查询时我们要防止SQL注入,我们可以使用 预处理语句来防范SQL注入。
4、执行SELECT查询
不返回记录的简单查询通过exec()方法来执行,而那些返回记录的查询需要query()方法,并将结果赋予新的变量:
$result = $pdo->query($q);
要查询返回了多少条记录,调用rowCount()方法即可:
$result->rowCount();
变量$result是与PDO、PDOException类并列为最重要的三个PDO类的PDOStatement类的对象。
一旦返回了结果,就可以使用PDOStatement类的对象(如$result)的fetch()方法,但是首先要设定PHP读取记录的方式。这通过一个常数为参数的setFetchMode()方法,常用值有:
PDO::FETCH_ASSOC,应用于关联数组
PDO::FETCH_NUM,应用于以数值为索引的数组
PDO::FETCH_OBJ,应用于泛型对象
PDO::FETCH_CLASS,应用于特定类型的对象
示例程序:
try {
$pdo = new PDO('mysql:dbname=dnf_db;host=localhost', 'root', '');
$pdo->query("SET NAMES UTF8");//设定编码
$sql = "SELECT * FROM data_tb";
$result = $pdo->query($sql);
$result->setFetchMode(PDO::FETCH_NUM);//设定读取记录的方式
while ($row = $result->fetch()) {
echo $row[6]."<br>";
}
unset($pdo);
} catch (PDOException $e) {
echo $e.getMessage();
}
运行结果:
5、使用预处理语句
传统做法中,在一个函数中完成组合查询语句并传给数据库的方式为:
$results = $pdo->query("SELECT * FROM tablename WHERE email='$email' ");
而使用预定义语句,查询语句与具体数据则分开传送,这样做执行效率会更高,安全管理更方便。同时由于数据与查询分开传送,就不需要防范SQL注入。
要使用PDO的预定义语句,首先要调用PDO的prepare()方法。将查询语句作为参数传递给该方法,查询语句中的动态数据用占位符(即?)来代替:
$stmt = $pdo->prepare('SELECT * FROM tablename WHERE email = ?');
这个方法会返回PDOStatement的对象,接下来调用PDOStatement对象的exec()方法,其参数为动态数据组成的参数:
$stmt->execute(array('me@email.com'));
如果有多个动态数据,那么在数组中的出现顺序与查询语句中的顺序应一致。
用什么符号来占位是可选的,我们也可以使用”具名占位符“:
$stmt = $pdo->prepare('SELECT * FROM tablename WHERE email=:email');
$stmt->execute(array(':email' => 'me@email.com'));
示例程序:
try {
$pdo = new PDO('mysql:dbname=dnf_db;host=localhost', 'root', '');
$pdo->query("SET NAMES UTF8");//设定编码
$stmt = $pdo->prepare('INSERT INTO data_tb (ss, soul, baozhu, useful, cost, imgsrc) VALUES (:ss, :soul, :baozhu, :useful, :cost, :imgsrc)');
$sucess = $stmt->execute(array(':ss' => '4', ':soul' => '2', ':baozhu' => '1', ':useful' => '妖刀', ':cost' => '1200',':imgsrc' => '404.jpg'));
if ($sucess) {
echo "新增数据成功";
}
else {
echo "失败";
}
unset($pdo);
} catch (PDOException $e) {
echo $e.getMessage();
}
运行结果: