标签:
从 PHP 5.1 开始附带了 PDO,PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口。PDO 提供了一个 数据访问 抽象层,这意味着,不管使用哪种数据库(比如mysql,oracle,mssql…),都可以用相同的函数(方法)来查询和获取数据。
使用PDO扩展必须在php.ini文件中打开相应的扩展,下图打开了pdo_mysql的扩展:
那怎么创建一个pdo对象呢?
<?php
//$dsn = "mysql:host=服务器地址/名称; port=端口号; dbname=数据库名";
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
//输出: object(PDO)#1 (0) { }, 拿到pdo对象表示连接成功了
var_dump($dbh);
更多详见:
在拿到PDO对象后,执行sql语句:
$sql = "select * from product";
$stmt = $dbh -> query($sql);
上述代码的 $stmt 就是PDOStatement对象,它是执行sql语句后返回的结果集。
PDOStatement对象主要方法:
1. PDOStatement::bindColumn — 绑定一列到一个 PHP 变量
2. PDOStatement::bindParam — 绑定一个参数到指定的变量名
3. PDOStatement::bindValue — 把一个值绑定到一个参数
4. PDOStatement::closeCursor — 关闭游标,使语句能再次被执行。
5. PDOStatement::columnCount — 返回结果集中的列数
6. PDOStatement::debugDumpParams — 打印一条 SQL 预处理命令
7. PDOStatement::errorCode — 获取跟上一次语句句柄操作相关的 SQLSTATE
8. PDOStatement::errorInfo — 获取跟上一次语句句柄操作相关的扩展错误信息
9. PDOStatement::execute — 执行一条预处理语句
10. PDOStatement::fetch — 从结果集中获取下一行
11. PDOStatement::fetchAll — 返回一个包含结果集中所有行的数组
12. PDOStatement::fetchColumn — 从结果集中的下一行返回单独的一列。
13. PDOStatement::fetchObject — 获取下一行并作为一个对象返回。
14. PDOStatement::getAttribute — 检索一个语句属性
15. PDOStatement::getColumnMeta — 返回结果集中一列的元数据
16. PDOStatement::nextRowset — 在一个多行集语句句柄中推进到下一个行集
17. PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数
18. PDOStatement::setAttribute — 设置一个语句属性
19. PDOStatement::setFetchMode — 为语句设置默认的获取模式。
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
$sql = "update product set price = 1998 where pro_id = 1";
#执行更新语句
$result = $dbh->exec($sql);
if($result){
echo "执行成功,受此语句影响的行数=".$result;
}else{
echo "<br>错误码:". $dbh->errorCode();
echo "<pre>";
var_dump( $dbh->errorInfo());
}
?>
运行结果:
现在故意把sql写错:
$sql = “update productxx set price = 1998 where pro_id = 1”;
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
//故意写错sql--------------------
$sql = "update productxx set price = 1998 where pro_id = 1";
$result = $dbh->exec($sql);
if($result){
echo "执行成功,受此语句影响的行数=".$result;
}else{
echo "<br>错误码:". $dbh->errorCode();
echo "<pre>";
var_dump( $dbh->errorInfo());
}
?>
运行结果:
使用事务:
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
$dbh->beginTransaction();//开启事务
$sql = "update product set price = 1998 where pro_id = 1";
$result = $dbh->exec($sql);
$intrans = $dbh->inTransaction();
var_dump($intrans);//bool(true)
if($result !== false){
$dbh->commit();//事务提交
}else{
$dbh->rollBack();//事务回滚
echo "<br>错误码:". $dbh->errorCode();
echo "<pre>";
var_dump( $dbh->errorInfo());
}
$intrans = $dbh->inTransaction();
var_dump($intrans);//bool(false)
?>
获取不同形式的结果集:
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
$sql = "select pro_id,pinpai from product";
$stmt = $dbh->query($sql);
//返回的结果以字段名为key
$row = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($row);
echo ‘<hr>‘;
//返回的结果以数字下标为key
$row = $stmt->fetch(PDO::FETCH_NUM);
print_r($row);
echo ‘<hr>‘;
//PDO::FETCH_ASSOC + PDO::FETCH_NUM
$row = $stmt->fetch(PDO::FETCH_BOTH);//默认就是PDO::FETCH_BOTH
print_r($row);
echo ‘<hr>‘;
//返回结果是内置标准类stdClass ,数据库字段名作为属性名
$row = $stmt->fetch(PDO::FETCH_OBJ);//默认就是PDO::FETCH_BOTH
print_r($row);
echo ‘<hr>‘;
class Row{}
//返回结果是指定类对象 ,数据库字段名作为属性名
$stmt->setFetchMode(PDO::FETCH_CLASS,‘Row‘);
$row = $stmt->fetch();//默认就是PDO::FETCH_BOTH
print_r($row);
echo ‘<hr>‘;
//获取所有的结果集
$sql = "select pro_id,pinpai from product limit 2";
$stmt = $dbh->query($sql);
//这里得到的结果是二维数组
$rows = $stmt->fetchAll();//fetchAll([PDO::FETCH_BOTH]) 默认是PDO::FETCH_BOTH
echo "<pre>";
print_r($rows);
?>
PDO 提供了三种不同的错误处理模式,以满足不同风格的应用开发:
1.PDO::ERRMODE_SILENT
此为默认模式。 PDO 将只简单地设置错误码,可使用 PDO::errorCode() 和 PDO::errorInfo() 方法来检查语句和数据库对象。如果错误是由于对语句对象的调用而产生的,那么可以调用那个对象的 PDOStatement::errorCode() 或 PDOStatement::errorInfo() 方法。如果错误是由于调用数据库对象而产生的,那么可以在数据库对象上调用上述两个方法。
2.PDO::ERRMODE_WARNING
除设置错误码之外,PDO 还将发出一条传统的 E_WARNING 信息。如果只是想看看发生了什么问题且不中断应用程序的流程,那么此设置在调试/测试期间非常有用。
3.PDO::ERRMODE_EXCEPTION
除设置错误码之外,PDO 还将抛出一个 PDOException 异常类并设置它的属性来反射错误码和错误信息。此设置在调试期间也非常有用,因为它会有效地放大脚本中产生错误的点,从而可以非常快速地指出代码中有问题的潜在区域(记住:如果异常导致脚本终止,则事务被自动回滚)。
异常模式另一个非常有用的是,相比传统 PHP 风格的警告,可以更清晰地构建自己的错误处理,而且比起静默模式和显式地检查每种数据库调用的返回值,异常模式需要的代码/嵌套更少。
#pdo设置异常模式
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
注意:不管当前是否设置了 PDO::ATTR_ERRMODE ,如果连接失败, PDO::__construct() 将总是抛出一个 PDOException 异常。未捕获异常是致命的。
PDO错误静默模式: PDO :: ERRMODE_SILENT
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_SILENT );
//这是一句错误的sql
$sql = "select pro_id,pinpai from productxxxx";
$stmt = $dbh->query($sql);
if(!$stmt){
$errArray = $dbh->errorInfo();
var_dump($errArray);
}
?>
PDO错误警告模式: PDO :: ERRMODE_WARNING
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_WARNING );
//这是一句错误的sql
$sql = "select pro_id,pinpai from productxxxx";
$stmt = $dbh->query($sql);
PDO错误异常模式: PDO :: ERRMODE_EXCEPTION
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
//这是一句错误的sql
$sql = "select pro_id,pinpai from productxxxx";
try {
$stmt = $dbh->query($sql);
} catch (PDOException $e) {
echo $e->getMessage();
}
预处理的意思是先提交sql语句到mysql服务端,执行预编译,客户端执行多条结构相同的sql语句时,只需上传输入参数即可,这点和存储过程有点相似。
有两种语法形式:
#问号占位符形式
select pro_id,pinpai from product WHERE protype_id > ? and pinpai = ?;
#命名占位符形式
select pro_id,pinpai from product WHERE protype_id > :v1 and pinpai = :v2;
1.问号占位符代码如下:
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
$sql = "select pro_id,pinpai from product WHERE pro_id > ? and pinpai = ?";
try {
$stmt = $dbh->prepare($sql);
//给占位符赋值形式1
$stmt->bindValue(1, 5);
$stmt->bindValue(2, ‘索尼‘);
$stmt->execute();
$resultSet = $stmt->fetchAll();
$stmt->closeCursor();
print_r($resultSet);
echo "<hr>";
//给占位符赋值形式2
$stmt->execute(array(3,‘索尼‘));
$resultSet = $stmt->fetchAll();
print_r($resultSet);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
2.命名占位符代码如下:
<?php
$dsn = "mysql:host=localhost; port=3306; dbname=db7";// =号两边最好不要有空格
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => ‘set names utf8‘);//可选参数
$username = "root";//用户名
$passwd = "root";//密码
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo ‘Connection failed: ‘ . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
$sql = "select pro_id,pinpai from product WHERE pro_id > :v1 and pinpai = :v2";
try {
$stmt = $dbh->prepare($sql);
//给占位符赋值形式1
$stmt->bindValue(":v1", 5);
$stmt->bindValue(":v2", ‘索尼‘);
$stmt->execute();
$resultSet = $stmt->fetchAll();
$stmt->closeCursor();
print_r($resultSet);
echo "<hr>";
//给占位符赋值形式2
$stmt->execute(array(":v1"=>3,":v2"=>‘索尼‘));
$resultSet = $stmt->fetchAll();
print_r($resultSet);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
标签:
原文地址:http://blog.csdn.net/readyyes/article/details/51239728