文章目录
PDO
概述
- PDO是PHP数据对象(PHP Data Object)的缩写
- PDO是一个第三方类,默认以集成到PHP中
- 使用PDO可以轻松对接各种不同类型的数据库,且操作方式和方法调用都基本一样
- PDO作用是统一各种数据库的访问接口
开启PDO扩展
开启mysql扩展为例
- 前期:php文件中的ext文件夹中包含php_pdo_mysql.dll扩展文件
- 修改php.ini文件,把extension = php_pdo_mysql.dll(extension=pdo_mysql)前的
;
去掉,然后重新启动php.exe程序(或重启apache); - 使用phpinfo()进行检查是否已启动PDO扩展
创建PDO类对象
-
语法:
PDO::__construct ( string
d s n ‘ [ , s t r i n g ‘ dsn` [, string ` dsn‘[,string‘username[, string
p a s s w o r d ‘ [ , a r r a y ‘ password` [, array ` password‘[,array‘driver_options]]] )
- $dsn 数据源
- $username 用户名
- $password 密码
-
代码实现
<?php
/* 创建一个连接mysql数据库的pdo对象 */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1;charset=utf8';
$user = 'dbuser';
$password = 'dbpass';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
?>
PDO对象常用方法
PDO::exec()方法
- 描述:执行一条sql语句,并返回受影响的行数(注意:select查询的sql语句,不会返回结果)
- 语法:int PDO::exec(String $sql)
- 参数:$sql 需要被预处理和执行的sql语句
- 返回:返回被修改或删除的sql语句影响的行数,如果没有受影响的行,则返回0;
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
$sql = "INSERT INTO user (id,name,age,sex) VALUES(null,'xiaode',99,1)";
$rel=$pdo->exec($sql);
var_dump($rel);
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
}
PDO::query()方法
- 描述:执行一条sql语句,返回一个结果集对象,一般用于select、show语句
- 语法:public PDOStatemet PDO::query(String $statement)
- 返回:执行成功返回PDOstatement对象,执行失败返回false;
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
//查询结果集
$sql = "SELECT * FROM user ORDER BY id DESC";
$rel = $pdo->query($sql);
var_dump($rel);
//输出结果
//object(PDOStatement)#2 (1) { ["queryString"]=> string(35) "SELECT * FROM user ORDER BY id DESC" }
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
}
PDO::lastInsertId()方法
- 描述:返回最后插入的ID或序列值
- 语法:String PDO::lastInsertId(void)
- 返回值:最后出入行的ID
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
//插入语句
$sql = "INSERT INTO user (id,name,age,sex) VALUES(null,'xiaode',99,1)";
$rel=$pdo->exec($sql);
//获取最后插入的id获取序列号
$rel=$pdo->lastInsertId();
var_dump($rel);//输出结果为4
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
}
PDO::setAttribute()方法
-
描述:设置数据库句柄的属性
-
语法:bool PDO::setAttribute(int $attribute,mixed $value)
-
注意:PDO内置了以下可用的通用属性,使用参考 手册
- PDO::ATTR_CASE 强制列名为指定的大小写
- PDO::ATTR_ERRMODE 错误报告
- PDO::ATTR_DEFAULT_FETDH_MODE 默认的提取模式
-
返回值:成功返回true,失败返回false
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
//设置PDO属性 设置从结果集中提取值 FETCH_ASSOC为关联数组 FETCH_NUM枚举
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
//查询结果集
$sql = "SELECT * FROM user ORDER BY id DESC";
$rel = $pdo->query($sql);
//遍历结果集
foreach($rel as $v){
echo "<pre>";
var_dump($v);
}
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
}
输出结果如下:
array(4) {
["id"]=>
string(1) "4"
["name"]=>
string(6) "xiaode"
["age"]=>
string(2) "99"
["sex"]=>
string(1) "1"
}
PDO预处理
预处理过程
- sql语句执行分两个阶段,编译和执行
- 第一次执行sql语句,需要先编译,编译过程复杂和耗系统资源,相对不安全
- 同一条sql语句执行,直接从缓存中读取执行,效率提高,也比较安全,从而避免sql注入等安全问题
预处理步骤
- PDO完成预处里需要的步骤
- 提取相同结构的sql部分(把数据部分,可变部分进行去除)
- 编译相同的结构,并把编译结果保存
- 把不同的数据部分进行替换
- 执行sql
- 提取相同结构的sql语句
- 在sql语句中,使用命名参数和问号参数,来代替可变的数据
- 使用占位符“:value"和"?"来代替可变的数据
预编译方法
- 描述: 准备要执行的语句,并返回语句对象
- 语法: public PDO::prepare ( string
$statement
[, array$driver_options
= array() ] ) - 参数:需要预处理的sql语句
给占位符绑定数据
- 描述:绑定一个值到预处理的sql语句中对应的命名占位符或问好占位符。
- 语法:bool PDOStatement::bindValue(mixed $parmeter,mixed $value);
- parameter,参数标识符,对应命名占位符的预处理语句,应该是类似
:name
形式的参数名,对于问号占位符的预处理语句,应该是以1开始的索引参数位置 - $value ,绑定的参数值
- parameter,参数标识符,对应命名占位符的预处理语句,应该是类似
- 返回值:成功返回true 失败返回false
执行预处理的sql语句
- 描述:执行一条预处理的语句
- 语法:bool PDOStatement::execute()
- 返回:成功返回true,失败返回false
示例1:使用命名参数方式示例
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
//设置异常捕捉
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
//使用命名参数进行绑定
$sql = "INSERT INTO user(name,age,sex) VALUES(:name,:age,:sex)";
//对内容进行预编译
$stmt = $pdo->prepare($sql);
//对占位数据进行绑定
$stmt->bindValue(':name','rufeike');
$stmt->bindValue(':age',30);
$stmt->bindValue(':sex',0);
//执行已预编译的sql
$rel=$stmt->execute();
//获取最后插入的id
$id=$pdo->lastInsertId();
var_dump($id);
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
echo "错误编号:".$e->getCode();
echo "错误行号:".$e->getLine();
}
示例2:使用问号参数绑定
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
//设置异常捕捉
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
//使用问号参数绑定方式
$sql = "INSERT INTO user(name,age,sex) VALUES(?,?,?)";
//对sql语句进行预编译
$stmt = $pdo->prepare($sql);
//对占位符进行数据绑定
$stmt->bindValue(1,'如非客2');
$stmt->bindValue(2,28);
$stmt->bindValue(3,1);
//执行已编译的sql
$rel = $stmt->execute();
//获取最后出入的主键
$id = $pdo->lastInsertId();
var_dump($id);
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
echo "错误编号:".$e->getCode();
echo "错误行号:".$e->getLine();
}
从结果集提取数据
PDOStatement::fetch()方法
- 描述:从结果集中获取一行,并向下移动指针
- 语法:mixed PDOStatement::fetch([int $fetch_style])
- PDO::FETCH_ASSOC,返回一个索引为关联数组的结果值
- PDO::FETCH_BOTH(默认),返回一个包含索引为0开始的索引数组和关联数组
- PDO::FETCH_NUM,返回一个索引以0开始的结果集数组
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
$sql = "SELECT * FROM user ORDER BY id DESC";
$stmt = $pdo->query($sql);
//每次从结果集中提取一行数据
while($rel=$stmt->fetch(PDO::FETCH_ASSOC)){
echo "<pre>";
var_dump($rel);
}
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
}
结果输出
array(4) {
["id"]=>
string(1) "4"
["name"]=>
string(6) "xiaode"
["age"]=>
string(2) "99"
["sex"]=>
string(1) "1"
}
array(4) {
["id"]=>
string(1) "3"
["name"]=>
string(6) "xiaode"
["age"]=>
string(2) "99"
["sex"]=>
string(1) "1"
}
PDOStatement::fetchAll()方法
- 描述:返回一个包含结果集中所有行的数组
- 语法:array PDOStatement::fetchAll([int $fetch_style])
- PDO::FETCH_ASSOC,返回一个索引为关联数组的结果值
- PDO::FETCH_BOTH(默认),返回一个包含索引为0开始的索引数组和关联数组
- PDO::FETCH_NUM,返回一个索引以0开始的结果集数组
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
$sql = "SELECT * FROM user ORDER BY id DESC";
$stmt = $pdo->query($sql);
//一次性全部取出
$rel=$stmt->fetchAll(PDO::FETCH_ASSOC);
echo "<pre>";
var_dump($rel);
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
}
输出结果
array(4) {
[0]=>
array(4) {
["id"]=>
string(1) "4"
["name"]=>
string(6) "xiaode"
["age"]=>
string(2) "99"
["sex"]=>
string(1) "1"
}
[1]=>
array(4) {
["id"]=>
string(1) "3"
["name"]=>
string(6) "xiaode"
["age"]=>
string(2) "99"
["sex"]=>
string(1) "1"
}
}
PDOStatement::rowCount()方法
- 描述:返回上一个sql语句影响的行数
- 语法:int PDOStatem::rowCount(void)
- 返回值:返回上一个由对应的PDOStatement 对象执行 select、delete 、insert或update语句受影响的行数
- 前提:需要使用PDO::query() 返回的PDOStatement对象
<?php
//创建一个连接mysql数据库的PDO对象
$dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try{
$pdo = new PDO($dsn,$user,$password);
//获取查询结果集数
$sql = "SELECT * FROM user ORDER BY id DESC";
$stmt = $pdo->query($sql);
$count=$stmt->rowCount();
var_dump($count);
}catch(PDOException $e){
echo "Connection faile:".$e->getMessage();
}
输出结果:
int(4)
PDO错误处理
静默模式
-
静默模式:错误发生后,不会主动报错
- 可以通过PDO::erroCode和PDO::errorInfo()两个方法获取
- 默认为静默模式
<?php //创建一个连接mysql数据库的PDO对象 $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8'; $user = 'root'; $password = 'root'; try{ $pdo = new PDO($dsn,$user,$password); //静默模式下获取错误信息 $sql = "SELECT * FROM user WHERE abc = 'abc'"; $stmt = $pdo->query($sql); echo "查询错误编号:".$pdo->errorCode(); echo "查询错误信息:".print_r($pdo->errorInfo()); }catch(PDOException $e){ echo "Connection faile:".$e->getMessage(); }
错误信息打印结果:
查询错误编号:42S22Array ( [0] => 42S22 [1] => 1054 [2] => Unknown column 'abc' in 'where clause' ) 查询错误信息:1
没有错误是的打印结果 errorCode为00000时表示没有错误
查询错误编号:00000Array ( [0] => 00000 [1] => [2] => ) 查询错误信息:1
警告模式
-
警告模式:错误发生后,通过PHP标准来报错误
- 设置错误模式为警告模式,错误结果根据php错误模式,直接在页面中输出
- PDO::setAttribute(PDO::Attr_ERRMODE,PDO::ERRMODE_WARNING);
- 这种方式不安全,会暴露系统相关信息
<?php //创建一个连接mysql数据库的PDO对象 $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8'; $user = 'root'; $password = 'root'; try{ $pdo = new PDO($dsn,$user,$password); //设置警告模式 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING); //警告模式下获取错误信息 数据库中没有i字段 $sql = "SELECT * FROM user WHERE i = 2"; $stmt = $pdo->query($sql); }catch(PDOException $e){ echo "Connection faile:".$e->getMessage(); }
错误打印结果
Warning: PDO::query(): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'i' in 'where clause' in C:\Users\rufeike\Desktop\phasher\test\index.php on line 52
异常模式
-
异常模式:错误发生后,抛出异常,需要捕捉和处理
- 提示:可以通过PDO::setAttribute()更改模式
<?php //创建一个连接mysql数据库的PDO对象 $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8'; $user = 'root'; $password = 'root'; try{ $pdo = new PDO($dsn,$user,$password); //设置异常模式 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); //异常模式下获取错误信息 $sql = "SELECT * FROM user WHERE i = 2"; $stmt = $pdo->query($sql); }catch(PDOException $e){ echo "Connection faile:".$e->getMessage(); echo "错误编号:".$e->getCode(); echo "错误行号:".$e->getLine(); }
错误打印结果
Connection faile:SQLSTATE[42S22]: Column not found: 1054 Unknown column 'i' in 'where clause'错误编号:42S22错误行号:52