PDO
1. PDO概述
PDO,PHP Data Object,也是PHP操作数据库的一个扩展
pdo扩展有一个很硬的后台PHP,在数据安全、执行效率方面,做了进一步的优化
PDO对操作数据库提供一致的接口,不仅可以操作MySQL数据库、SQL Server、Oracle等这些数据库,便于将来数据库的移植(而mysqli扩展只能连接MySQL数据库)
image.png
image.png
2. 开启PDO扩展
在php.ini配置文件中开启扩展
在php.ini里面搜索pdo,找到pdo扩展的位置,将前面的;分号去掉即可
image.png
测试一下:
创建phpinfo.php文件,打印一下php的信息即可
image.png
3. 实例化PDO对象
mysql扩展连接数据库:
- mysql_conenct();
- mysql_select_db(); 选择数据库
- mysql_query(); 设置字符集
- mysql_query($sql); 执行sql语句,返回结果集对象
-
fetch 数据处理
通过pdo连接数据库
image.png
注意:
$dsn=””这里面不要有任何空格
4. 使用PDO执行SQL语句
创建一个测试数据库进行测试
create database php_3 default character set utf8;
create table user(
id int primary key auto_increment,
username varchar(30),
password varchar(50)
) ;
image.png
(1)query():查询类:查询
返回PDOStatement对象
fetchAll() 查询所有的数据,返回二维数组
fetch() 返回一条记录,该记录既有关联类型的数据、索引类型的数据
我们可以通过参数配置返回结果的格式
PDO::FETCH_ASSOC 指定返回的结果是关联类型的数据
PDO::FETCH_NUM 指定返回的结果是索引类型的数据
PDO::FETCH_BOTH 指定返回的结果是既有关联类型、索引类型
image.png
fetchColumn() 查询的是一条记录的某个字段的值,
注意:参数是字段的索引、序号,而不是字段的名称
注意:fetchColumn()方法获得的是当前的记录,如果之前没有查询,则返回第一条记录的某个字段,如果fetchColumn之前有查询,数据指针会向后面移动,这个时候,fetchColumn返回的是当前的记录
image.png
(2)exec():非查询类:增加、删除、修改
插入一条数据:
image.png
给大家一点时间,大家练习
更新、删除操作
5. PDO对象的常用方法
(1)exec()
(2)query()
(3)errorCode()****:****返回错误的代码
(4)errorInfo()****:****返回错误的信息
image.png(5)quote()****数据转义并使用引号包裹
举例说明
image.png
image.png
测试一把,我们在用户名输入框输入的内容是:1' or 1 or '
image.png
分析原因:
问题出在哪里?
image.png
解决之道:
pdo对象的quote()方法,对提交的数据(POST、GET、COOKIE等)进行引号转义、并包裹
image.png
image.png
不仅转义、而且使用引号包裹
image.png
(6)事务处理:
是逻辑上的一组操作,组成这组操作的各个单元要么全部成功,要么全部失败
创建测试数据表,模拟宋江给李逵转账
CREATE TABLE cash(
id int primary key auto_increment,name varchar(30),
mone
y decimal(7,2)
)engine innodb default charset=utf8;
image.png
插入测试数据
image.png
使用事务,模拟转账
image.png image.png
(7)lastInsertId()
上次执行插入数据返回的主键值,如果一次增加多条记录,返回的是前面的那条记录的主键
image.png
(8)prepare()****预处理sql语句
举个例子:
通过下面的练习,我们发现,会将所有数据删除,问题出在 id的值上,删除的时候,将所有满足条件的都删除了
image.png
解决之道:
我们的总体思路就是:id的值,就应该是一个固定的数字,不应该有运算
使用$pdo对象的prepare方法,进行处理
- 先解析SQL语句的结构部分,数据暂时使用占位符代替
-
解析SQL语句之后,prepare()之后,再将占位符替换成真实的数据
bindValue(),第一个?使用1表示,第二个?问号使用2表示,依次类推
3. 执行:execute()
image.png
预处理查询sql语句
在执行完execute()方法之后,继续执行pdo_statement对象的fetch()系列方法进行查询
image.png
image.png
占位符除了 ? 之外,还有其他的站位符号,例如: :占位符
预处理的优点
(1)因为在prepare()的时候,已经将SQL语句的结构部分解析处理并保存到pdostatement对象身上,以后的操作仅仅是替换占位符,sql语句就不再解析,所以提高执行效率
image.png
(2)因为使用占位符代替真实数据,从而防止非法的数据,进而提高数据的安全
6. PDOStatement对象的常用方法
(1)fetch
(2)fetchAll()
(3)fetchColumn
(4)bindValue()
(5)execute()
(6)closeCursor() 关闭游标、指针,便于下次查询
image.png
(7)errorInfo errorCode 分别获得sql语句错误信息以及错误代码
image.png
(8)rowCount()统计受影响的记录数(查询、增加、删除、修改)
如果是查询语句,返回的是查询的记录数
image.png
如果是非查询语句,删除、修改、增加,则返回受影响的记录数
image.png
7. 基于PDO再次封装DAO类
DAOMySQLi.class.php------>操作数据库 Android
DAOMySQL.class.php------>操作数据 iphone
DAOPDO.class.php--------->操作数据库 window phone
提出一个疑问:DAOPDO.class.php类里面的方法能随便定义吗?
接口的概念,是一个规范,约束一个类有哪些功能、方法
接口不实现这些方法,而是类去完成这些方法
通过接口规范了所有功能类的方法,将来我们在切换数据操作类的时候,因为规范都是一样的,所以更加灵活
如何定义接口呢?
(1)通过interface关键字定义接口,并在接口中规范有哪些功能
image.png
(2)在具体的功能类里面实现接口中规定的方法
implements
image.png
思考:我们在执行数据库的操作时,连接一次数据库就可以了,不需要连接很多次
如何保证我们的DAOPDO这个类只实例化一个对象呢?
单例模型
- new 构造函数
- 静态方法
-
克隆
通过三私一公的方法实现
私有的构造方法
私有的静态属性保存对象
私有的克隆方法
1个公共的静态方法实例化
image.png
通过公共的静态方法获得单例对象
image.png
在构造方法中,我们初始化服务器信息以及实现初始化PDO对象
image.png
image.png
到此我们可以获得PDO对象了,接下来我们通过查询所有数据测试一下我们的接口
image.png
因为在类中我们只实现了3个方法,为了测试,我们暂时将接口中的其他方法注释
image.png
8. 作业
大家完成接口中定义的如下方法:
getRow
getOne
exec
affectedRows
lastInsertId
escapeData
网友评论