文档章节

PDO详解

lonelydawn
 lonelydawn
发布于 2016/06/16 20:23
字数 1469
阅读 468
收藏 24
点赞 0
评论 3

一、PDO诞生的意义

PHP对数据库支持的抽象度不够,接口不统一。每一种数据库环境都必须重新定义数据库的操作。在这种背景下,统一操作接口PDO诞生了。

在PHP中,有三种数据库连接方式:

(1)mysql 最常用,过程式风格的一种应用

(2)mysqli,mysql函数的增强版,提供面向对象和过程两种风格的API,增加了预编译和参数绑定等新的特性

(3)PDO统一抽象接口,更类似于mysqli

 

二、PDO常用函数

PDO中包含三个预定义类:PDO、PDOStatement和PDOException

(1)PDO类中的常用方法有:

beginTransaction():开启事务机制

commit():提交事务

exec():执行一条SQL语言并返回影响的行数

prepare():为执行准备一条SQL语句,返回语句执行后的联合结果集

query():执行一条SQL语句并返回一个结果集

rollBack():回滚一个事务

getAttribute():获取一个数据库连接属性

setAttribute():设置一个数据库连接属性

 

(2)PDOStatement类中常用方法有:

bindParam():绑定一个PHP变量到一个预处理语句中的参数

execute():执行一条预处理语句

fetch():从结果集中取出一行

fetchAll():从结果集中取出一个包含所有行的数组

fetchColumn():返回结果集中某一列的数据

 

(3)PDOException是对exception类的简单重写,这里不作介绍

 

 

三、PDO的简单使用

1.在windows系统下,开启PDO需要在php.ini中将

;extension=php_pdo_mysql.dll

前面的分号去掉,如果使用的数据库不是mysql,则将对应的数据库扩展配置前面的分号去掉

在linux或者ngnix系统下,开启PDO也需要在php配置文件中将对应的拓展前的注释符号去掉。

 

2.在数据库中建立test数据库和一张test表,如下图所示

 

在服务器目录下新建一个php脚本如下:

<?php

try{

//配置数据源,数据库服务器IP和数据库名

$dsn="mysql:host=127.0.0.1;dbname=test";

$db=new PDO($dsn,"root","");


//设置异常可捕获

$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

 

$db->exec("set names utf8");

//插入新数据

$sql="insert into test(name) values('HeCheng')";

$db->exec($sql);

 

}catch(PDOException $err){

echo $err->getMessage();

}

?>

结果如下:

 

三、PDO预编译和参数绑定

预编译:

<?php

try{

//数据库地址,数据库,数据库账户和密码

$dsn="mysql:host=127.0.0.1;dbname=test";

$db=new PDO($dsn,"root","");

 

$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

$insert=$db->prepare("insert into test(name) values(?);");

//插入

$insert->execute(Array("HeChengLei"));

 

//异常语句

//$insert->execute(Array("ZhangJun","1983-09-21"));

 

//查找

$select=$db->prepare("select * from test");

$select->execute();

var_dump($select->fetchAll(PDO::FETCH_ASSOC));

 

}catch(PDOException $err){

echo $err->getMessage();

}

?>

 

结果:

 

 

参数绑定:

<?php

$name='HeCheng';

$dsn="mysql:host=127.0.0.1;dbname=test";

 

$db=new PDO($dsn,"root","");

 

//用?代替param

$sth=$db->prepare("select * from test where name=?");

//参数绑定

$sth->bindParam(1,$name,PDO::PARAM_STR,12);

$sth->execute();

var_dump($sth->fetchAll(PDO::FETCH_ASSOC));

 

//用:param代替param

$sth=$db->prepare("select * from test where name=:name");

$sth->bindParam(':name',$name,PDO::PARAM_STR,12);

$sth->execute();

var_dump($sth->fetchAll(PDO::FETCH_ASSOC));

?>

 

结果:

 

PDO最大的特点就是引入了预编译和参数绑定,二者的关系其实就是同一件事情的不同阶段,参数绑定使用bindParam()函数传入参数。

 

四、SQL注入与参数绑定

1.SQL注入的原理

MySQL注入又称为SQL Injection,通过构造特定的SQL语句获取权限外的数据。

SQL注入的原理非常简单,就是在原有SQL语句上添加一些布尔条件语句。

例,在浏览器中执行下列请求:

http://127.0.0.1/index.php?name=HeCheng

数据库执行对应的SQL语句如下

select * from test where name=’HeCheng’;

但如果一些不良客户构造这样的请求如:

http://127.0.0.1/index.php?name=HeCheng or 1=1

数据库即执行下列SQL语句

select * from test where name=’HeCheng’; or 1=1;

将会把数据库表中所有客户的信息查找出来,造成客户信息泄露

 

2.SQL注入的防范

实际上,SQL注入的技术含量并不高,防范也非常简单。

在处理客户输入的信息时,如果是整型变量,就是用intval()把传入的参数转化为一个数值。对于字符型变量,可以使用addslashes()把所有单引号、双引号、反斜线和空字符转化为含有反斜线的溢出字符。对于可能出现的特殊字符,进行转译和过滤。

 

3.使用PDO参数绑定防范SQL注入

PDO的参数绑定就是防范SQL注入的一种好办法。

其函数原型为:

<?php

function bindParam(&$sql,$location,$var,$type){

switch ($type) {

default:

case 'STRING':

$var=addslashes($var);

$var="'".$var."'";

break;

case "INTEGER":

case "INT":

$var=(int)$var;

//还可以拓展多种类型

}

for($i=1,$pos=0;$i<=$location;$i++)

$pos=strpos($sql,'?',$pos+1);

 

$sql=substr($sql,0,$pos).$var.substr($sql,$pos+1);

}

?>

 

五、PDO的事务机制

PDO中使用beginTransaction()创建事务,使用commit()或者rollback()结束事务。

在使用beginTransaction()后,如果事务中有异常出现或者没有提交事务即关闭数据库连接和结束脚本,事务会自动回滚,即终止前的所有语句都不会生效。这体现了事务的原子性。

如:

$db->beginTransaction();

$db->exec(“insert into test(name) values(‘ZhangDa’)”);

$db->exec(“insert test(name) values(‘WangGang’)”);//这条语句是错误的,无法执行

$db->commit();

 

在这段代码中,因为使用了事务机制,第二个插入语句错误会导致第一个插入语句也不会生效。

 

六、PDO的效率问题

PDO比mysql、mysqli的连接更为稳定,但在效率上却不一定比直连更好。而且在实际应用中,数据库迁移的情况不是很多,PDO更无法保证一次编写,到处运行。所以推荐在新应用中考虑使用PDO,在旧的应用中则没有必要进行重构。

© 著作权归作者所有

共有 人打赏支持
lonelydawn
粉丝 41
博文 50
码字总数 52905
作品 0
闵行
前端工程师
加载中

评论(3)

os790858223
os790858223
21313232132
Fenying
Fenying
旧的应用如果要升级到PHP7,必须抛弃mysql扩展,改用mysqli或者PDO。
Loveni
Loveni
好用否
PHP PDOStatement对象bindpram()、bindvalue()和bindcolum

PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别 PDOStatement::bindParam ― 绑定一个参数到指定的变量名。 绑定一个PHP变量到用作预处理的SQL语句中的对应命名占位符或...

开元中国2015
2015/07/31
233
0
PHP中的PDO详解

PDO 是一个“数据库访问抽象层”,作用是统一各种数据库(MySQL、MSSQL、Oracle、DB2、PostgreSQL……)的访问接口,能轻松的在不同的数据库之间完成切换,使得数据库间的移植容易实现。 PD...

freedonn
2015/10/12
227
0
Ubuntu16.04手动编译PHP5.6.30详解

记录下爬坑过程,以便以后使用 原料: Ubuntu16.04 Server PHP5.6.30 步骤: 手动编译源码之前需要提前安装编译环境,以下为所需要的安装包: apt-get -y install gcc libxml2-dev libssl-de...

luweiv998
2017/03/17
0
0
SylixOS-IgH系统平台搭建

1.参考手册 下面7个文件存放在本地服务器“\10.9.1.113.研发部9.ExchangeFolder郑磊”路径下 《RealEvo-IDE使用手册》 《SylixOS应用开发手册》 《SylixOSshell用户手册》 《SylixOS-IgH使用...

zhengleich
05/15
0
0
微擎数据库缓存的增、删、改和查函数详解

函数所在文件:framework/function/cache.mysql.func.php 目前微擎的个人真实调用: $setting = $this->module['config']; $aaaaa = $setting['copyright']; 在微擎微信公众号系统里面可以分...

gutaotao1989
06/27
0
0
PHP 自 5.2 到 5.6 中新增的功能详解[转]

本文将会介绍自 PHP5.2 起,直至 PHP5.6 中增加的新特征。 PHP5.2 以前:autoload, PDO 和 MySQLi, 类型约束 PHP5.2:JSON 支持 PHP5.3:弃用的功能,匿名函数,新增魔术方法,命名空间,后期...

W_Lu
2014/02/07
0
2
Memcache的安装使用及与mysql交互实例

一、Memcache介绍 Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等...

行者PHPer
2012/05/06
0
0
PHP 5.2、5.3、5.4、5.5、5.6 对比以及功能详解

PHP 5.2、5.3、5.4、5.5、5.6 对比以及功能详解 截至目前(2014.2), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已经不在维护 [注] 的 PHP5.2, 其余的一半用户在使用 PHP5.3...

mickelfeng
2014/09/24
0
0
PHP PDO在SWOOLE模式下关闭数据库连接一些注意点

最近在swoole中使用php pdo扩展访问数据库的时候,发现了一个很有意思的事情。 我测试用的版本是 PHP 7.1.13 官方手册明确到告诉我们,使用PDO是这样关闭数据库连接的,只需要将PDO对象置为n...

anoty
02/11
2
0
再论php 5.3.6以前版本中的PDO SQL注入漏洞问题

我曾经写一篇《PDO防注入原理分析以及使用PDO的注意事项》,里面描述到php 5.3.6之前的PDO可能存在SQL注入之问题,并给出了彻底的解决方案,有的朋友给我发电子邮件,对此有疑问,说是在php 5...

月影又无痕
2013/09/22
0
3

没有更多内容

加载失败,请刷新页面

加载更多

下一页

线程安全,底层实现原理和JMM

让多线程下的类安全起来:无状态、加锁、让类不可变、栈封闭(方法封装) 、安全的发布对象(不暴露成员) 死锁 一定发生在多个线程争夺多个资源里的情况下,发生的原因是每个线程拿到了某个(某...

这很耳东先生
5分钟前
0
0
MyBatis源码解读之延迟加载

1. 目的 本文主要解读MyBatis 延迟加载实现原理 2. 延迟加载如何使用 Setting 参数配置 设置参数 描述 有效值 默认值 lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延...

无忌
11分钟前
0
0
javascript 类变量的实现

代码如下: function echo(){ for(let i=0;i<arguments.length;i++) console.log(arguments[i]);}function extend(o, p){for (prop in p) {o[prop] = p[prop]}retur......

backbye
15分钟前
0
2
编程语言对比分析:Python与Java和JavaScript(图)

编程语言对比分析:Python与Java和JavaScript(图): 凭什么说“Python 太慢,Java 太笨拙,我讨厌 JavaScript”?[图] 编程语言生而为何? 我们人类从原始社会就是用语言表达自己,互相沟通...

原创小博客
24分钟前
0
0
Akka构建Reactive应用《one》

看到这Akka的官网,描述使用java或者scala构建响应式,并发和分布式应用更加简单,听着很高级的样子,下面的小字写着消息驱动,但是在quickstart里面又写容错事件驱动,就是这么钻牛角尖。 ...

woshixin
35分钟前
0
0
ffmpeg源码分析 (四)

io_open 承接上一篇,对于avformat_open_input的分析还差其中非常重要的一步,就是io_open,该函数用于打开FFmpeg的输入输出文件。 在init_input中有这么一句 if ((ret = s->io_open(s, &s-...

街角的小丑
37分钟前
0
0
String,StringBuffer ,StringBuilder的区别

不同点 一、基类不同 StringBuffer、StringBuilder 都继承自AbStractStringBuilder,String 直接继承自 Object 2、底层容器“不同” 虽然底层都是字符数组,但是String的是final修饰的不可变...

不开心的时候不要学习
52分钟前
0
0
nodejs 文件操作

写文件code // 加载文件模块var fs = require("fs");var content = 'Hello World, 你好世界!';//params 文件名,内容,编码,回调fs.writeFile('./hello.txt',content,'utf8',function (er......

yanhl
55分钟前
0
0
SpringBoot mybits 查询为0条数据 但是在Navicat 中可以查询到数据

1.页面请求: 数据库查询: 2018-07-16 17:56:25.054 DEBUG 17312 --- [nio-9010-exec-3] c.s.h.m.C.selectSelective : ==> Preparing: select id, card_number, customer_id, customer_nam......

kuchawyz
今天
0
0
译:Self-Modifying cod 和cacheflush

date: 2014-11-26 09:53 翻译自: http://community.arm.com/groups/processors/blog/2010/02/17/caches-and-self-modifying-code Cache处在CPU核心与内存存储器之间,它给我们的感觉是,它具......

我叫半桶水
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部