数据库抽象层--php高级最详细教程
来源:互联网 发布:无锡软件研究所有哪些 编辑:程序博客网 时间:2024/05/10 20:12
数据库抽象层PDO 原创
使用PDO的好处?
PDO(PHP Data Object) 的出现让PHP达到一个新的高度。PDO扩展类库为PHP访问数据库定义了一个轻量级的、一致性的接口,
它提供了一个数据访问抽象层,这个,无论你使用什么数据库,都可以通过一致的函数执行查询和获取数据。大大简化了数据库的
操作,并能够屏蔽不同数据库之间的差异。使用PDO可以很方便的进行跨数据库程序的开发,以及不同数据库间的移植,是将来
PHP在数据库处理方面的主要发展方向。
PDO所支持的数据库
PS:要确定所处环境中有可用的PDC驱动程序,可以在浏览器中通过加载phpinfo()函数
,查看PDO部分的列表,或者通过查pdo_drivers()函数返回的数组。
PDO的安装
PS:PDO随PHP5.1发行,在PHP5.0的PECL扩展中也可以使用,PDO需要PHP5核心面向对象特征
性的支持,所以它无法运行于之前的PHP版本中。
Linux环境下启动对MySQL的PDO驱动程序支持,需要在安装PHP5.1以上版本的源代码包环境时,
向configure命令中添加如下标志:
--with-pdo-mysql=/usr/local/mysql //其中“/usr/local/mysql”为MySQL服务器安装目录
PS:如果在安装PHP环境时,要开启其他各个特定PDO驱动程序的更多信息,请参考执行configure
--help命令所获得的帮助结果。
Windows环境下的配置:
在Windows环境下PHP5.1以上版本中,PDO和主要数据库的驱动同PHP一起作为扩展发布,要激活它们只需要简单的编辑php.ini文件。
extension=php_pdo.dll //所有PDO驱动程序共享的扩展,必须有
extension=php_pdo_mysql.dll //如果使用MySQL,那么就添加这一行
extension=php_pdo_mssql.dll //如果使用SQL Server,那么添加这一行
extension=php_pdo_odbc.ll //如果使用ODBC驱动程序,那么添加这一行
extension=php_pdo_oci.ll //如果使用Oracle驱动程序,那么添加这一行
保存修改的php.ini文件变化,重启Apache服务器,查看phpinfo()函数,
如下图:
创建PDO对象
PDO的构造方法:
创建PDO对象其实就是在new PDO($dsn,[,username[,password[,array driver_optionss]]]) 的括号中填写必要的参数来进行构造方法的初始化
PDO的构造方法原型如下:
__construct(string dsn [ , string username [ , string password [ , array driver_options]]]) //PDO的构造方法
构造方法参数说明:
第一个参数:
dsn (data source name) 数据源名 必选参数 用来定义一个确定的数据库和必须用到的驱动程序。
dsn 格式 如下所示:
oci:dbname=//localhost:1521/mydb //连接到Oracle服务器的DSN, oci:作为驱动前缀, 主机 localhost, 端口 1521, 数据库 mydb
mysql:host=localhost;dbname=testdb //连接到MySQL服务器的DSN,mysql:作为驱动前缀,主机 localhost, 数据库 testdb
第二个参数和第三个参数:
构造方法中的第二个参数username和第三个参数password 分别用于指定连接数据库的用户名和密码,是可选参数。
第四个参数:
最后一个参数driver_option 需要一个数组,用来指定连接所需要的所有额外选项,传递附加的调优参数到PDO或底层驱动程序。
以多种方式调用构造方法:
1.将参数嵌入到构造函数
<?php
try{
$dsn = new PDO("uri:file///usr/local/dbconnect",'webuser','password')
}catch(PDOException $ex){
echo '连接数据库失败:'.$ex->getMessage();
}
文件dbconnect的格式:
mysql:host=localhost;dbname=testdb;
PS:testdb后的分号可以不加 ,host 和dbname的顺序不是固定的。
2.将参数存放在文件中
<?php
try{
$dsn = new PDO("mysql:dbname=testdb;host=localhost;",'webuser','password')
}catch(PDOException $ex){
echo '连接数据库失败:'.$ex->getMessage();
}
3.引用php.ini文件
<?php
try{
$dsn = new PDO("oraclepdo",'webuser','password')
}catch(PDOException $ex){
echo '连接数据库失败:'.$ex->getMessage();
}
在php.ini中为DSN指定的别名为oraclepdo:
[PDO]
pdo.dsn.oraclepdo="OCI:dbname=//localhost:1521/mydb;charset=UTF-8";
PDO与连接相关的选项
PS:在创建PDO对象时,有一些与数据库连接有关的选项,可以将必要的几个选项组成数组传递给构造方法的
第四个参数 driver_option中,用来传递附加的调优参数到PDO或底层驱动程序
传入写法如下:
new PDO("mysql:host=localhost;dbname=testdb;",'root','',array(3=>2,PDO::ATTR_PERSISTENT=>true))
PDO对象中的成员方法
PS:当PDO对象创建成功以后,与数据库的连接已经建立,就可以使用该对象了。PHP与数据库服务直接的交互都是
通过PDO对象中的成员方法实现的。
使用PDO对象
调整PDO的行为属性
PDO属性的设置可以查看PHP帮助文档(http://www.php.net/pdo).
如果在创建PDO对象时,没有在构造方法中最后一个参数设置过的属性选项,也可以在创建完对象以后,通过
PDO对象中的setAttribute()和getAttribute()方法设置和获取这些属性的值
getAttribute的使用:
该方法值需要提供一个参数,传递一个特定的属性名称,如果执行成功,则返回该属性所指定的值
以下实例简写:
//try{}catch(){} 这里省略了,不写了。
$pdo = new PDO("mysql:host=localhost;dbname=test;",'root','');
$pdo->getAttribute(PDO::ATTR_ERRMODE); //当前PDO错误处理的方式
setAttribute的使用:
这个方法需要传入两个参数,第一个参数提供PDO对象特定的属性名,第二个参数则是这个指定的属性赋一个值。
以下实例简写:
//try{}catch(){} 这里省略了,不写了。
$pdo = new PDO("mysql:host=localhost;dbname=test;",'root','');
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); //设置抛出异常处理错误
PDO处理PHP程序和数据库之间的数据类型转换
如果结果集中的某列包含一个NULL值,PDO则会将其映射为PHP的NULL值。Oracle在将数据
返回到PDO时会将空字符串转换为NULL,但是PHP支持的任何其他数据库都不会这样处理,从
而导致了可移植性问题。PDO提供了一个驱动程序级属性PDO_ATTR_ORACLE_NULLS,该属
性会为其他数据驱动程序模拟此行为。此属性设置为TRUE,在获取时会把空字符串转换为NULL,
默认情况下该属性值为FALSE.如下:
$pdo->setAttribute(PDO::ATTR_ORACLE_NULLS,true);
该属性设置以后,通过$pdo对象打开的任何语句中的空字符串都将被转换为NULL.
PDO的错误处理模式
PDO提供了三种不同的错误处理模式,不仅可以满足不同风格的编程,也可以调整扩展处理错误的方式
1.PDO::ERRMODE_SILENT
这是默认模式,在错误发生时不进行任何操作,PDO将只设置错误代码。开发人员可以通过对象中的errorCode和errorInfo()方法对语句和数据库对象进行检查。
2.PDO::ERRMODE_WARNING
发出一条PHP传统E_WARNING消息,可以使用常规的PHPCUOWU 错误处理程序捕获该警告
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
3.PDO::ERRMODE_EXCEPTION
PDO还将抛出一个PDOException,并设置其属性,以反映错误代码和错误消息。这种设置在调试中
很有用,因为它会放大脚本中产生错误的地方该错误方式配合try{}catch(){}使用最好。
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
使用PDO执行SQL语句
在PHP脚本中,通过PDO执行SQL查询与数据库进行交互,可以分为三种不同的策略,使用哪一种方法取决你做什么操作。
1.使用PDO::exec()方法
当执行INSERT、UPDATE、DELETE等没有结果集的查询时,使用PDO对象中的exec()方法去执行,该方法成功执行后,
将会返回受影响行数。
示例代码如下:
$query = "UPDATE user set phone='15607925362' WHERE id='35'";
$affected = $dbh->exec($query); //执行语句返回受影响行数$affected。
//受影响函数同样适用于DELETE 删除语句,但是插入语句insert不好用了。要使用lastInsertId()来获取最后插入id
//插入语句INSERT
$query = "INSERT INTO user(name,phone,email) values('vilin','15607925361','23506583@qq.com')";
$dbh->exec($query);
$dbh->lastInsertID(); //获取最后的插入id
2.使用PDO::query()方法
当执行返回结果集的SELECT查询时,或者所影响的行数无关紧要时,应当使用PDO对象中的query()方法,如果该方法成功执行指定的查询,
则返回一个PDOStatement对象。如果使用了query()方法,并想了解获取数据的总行数,可以使用PDOStatement对象中的rowCount()方法
获取,示例代码如下:
<?php
$dbh = new PDO("mysql:host=localhost;dbname=test;",'root',''); //建议写到try{}catch(){}中
$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); //设置对象错误处理模式
$query = "SELECT name,phone,email FROM user WHERE id='34'"; //准备sql查询语句
try{
$stmt = $dbh->query($query); //执行语句
echo "一共从表中获取到".$stmt->rowCount()."条记录:\n";
foreach($stmt as $row){ //遍历$dbh->query($query);来得到数据
echo $row['name']."\t";
echo $row['phone']."\t";
echo $row['email']."\n";
}
}catch(PDOException $ex){
echo $ex->getMessage();
}
3.使用PDO::quote()方法
可以使用PDO::quote()过滤一些特殊字符,防止一些能引起SQL注入的代码。我们在PDO中使用quote()方法实现,
实例如下:
$query = "SELECT * FROM users WHERE login=".$dbh->quote($_POST['login'])." AND passwd=".$dbh->quote($_POST['pass']);
//安全转义 例如下面这个奇葩的英文名字
$name = "Job's HHH";
//使用此方法转义
$name = $pdo->quote($name);
//通过quote方法转义之后的字符串,会将特殊字符转义,并将两端加上单引号
echo $name.'<br>'; // 'Job\'s HHH'
//我们使用的时候直接使用转义后的变量就可以了,不需要再加上单引号,否则报错
$sql = "insert into shop_user(username,age,money) values($name,19,39000)";
$rows = $pdo->exec($sql);
4.使用PDO::prepare()和PDOStatement::execute()两个方法
当同一个查询需要多次执行时(有时需要迭代传入不同的列值),使用预处理语句的方式来实现效率会很更高。从MySQL4.1开始,
就可以结合MySQL使用PDO对预处理语句的支持。使用预处理语句就需要使用PDO对象中的prepare()方法去准备一个将要执行
的查询,在使用PDOStatement对象中的execute()方法来执行
PDO对预处理语句的支持
使用预处理语句的好处?
1.提高命令的处理效率。
2.可以有效防止SQL注入。
PDOStatement对象的使用
通过执行PDO对象中query()方法返回的PDDOStatement类对象,只代表一个结果集对象。
而通过执行PDO对象中prepare()方法返回的PDOStatement类对象则为一个查询对象,能定义和执行参数化的SQL命令.
PDOStatement类中的全部成员方法如下
实例:
<?php
header('content-type:text/html;charset=utf-8');
// PDO的使用
//准备一个数据源 DSN
$dsn = "mysql:host=localhost;dbname=test";
//实例化PDO对象
try{
$pdo = new PDO($dsn,'root','',array('3'=>'1'));
}catch(PDOException $ex){
echo '数据库连接失败';
}
//设置字符集
$sql = "set names utf8";
$pdo->exec($sql);
//预处理
//会自动使用安全转义 一个值 例如Like后面,占位符要代表一个完整的值
$sql = "select * from user where name like ?";
$stmt = $pdo->prepare($sql);
//绑定参数
$stmt->bindParam(1,$key);
//赋值
$key = "%pan%"; //会安全过滤
//执行
$bool = $stmt->execute();
//设置 setFetchMode()fetch()或fetchAll()取值方式
//PDO::FETCH_ASSOC关联数组 PDO::FETCH_NUM 索引数组 PDO::FETCH_OBJ 对象 PDO::FETCH_BOTH 索引和关联
$stmt->setFetchMode(PDO::FETCH_ASSOC);
//第一种取值方法
/* foreach($stmt as $val){
list($id,$name,$age,$money) = $val;
echo "$id--$name--$age--$money<br>";
} */
//第二种取值方法
//fetch()
/* while($row = $stmt->fetch()){
echo'<pre>';
print_r($row);
echo '</pre>';
$val= array_values($row);
$key = array_keys($row);
list($id,$name,$age,$money) = $val;
echo "--$id--$name--$age---$money----<br>";
}*/
//第三种取值方法
//fetchAll()
/* $rows = $stmt->fetchAll();
echo '<pre>';
print_r($rows);
echo '</pre>';
foreach($rows as $row){
$key = array_keys($row);
$val = array_values($row);
list($id,$name,$age,$money) = $val;
echo "$id--$name--$age--$money<br>";
} */
//第四种方法 取值每次取一行 然后再取一列的某个值 执行一次 指针向下移动一条
/* $one = $stmt->fetchColumn(1);
echo $one.'<br>';
$two = $stmt->fetchColumn(1);
echo $two.'<br>';
$three = $stmt->fetchColumn(1);
echo $three.'<br>'; */
/* while($num = $stmt->fetchColumn(1)){
echo "$num<br>";
} */
//第五种类似于LIST的取值
$stmt->bindColumn(1,$name);
$stmt->bindColumn(2,$age);
$stmt->fetch();
echo $name.'<br>';
echo $age.'<br>';
/* $arr=array(
'ret'=>'0',
'msg'=>'ok',
'url'=>''
);
print_r($arr);
$str= json_encode($arr);
echo $str;
print_r(json_decode($str,true)); */
占位符实例:(:)
<?php
header('content-type:text/html;charset=utf-8');
//PDO的使用
//准备dsn data source name
$dsn = "mysql:host=localhost;dbname=test";
//实例化PDO对象
try{
$pdo = new PDO($dsn,'root','');
}catch(PDOException $ex){
echo $ex->getMessage();
}
//设置字符集
$sql = "set names utf8";
$pdo->exec($sql);
//预处理
//问号占位符号 ?
//冒号占位符号 :
//准备模板 此处冒号不加引号,冒号不能省略
$sql = "insert into user(name,age,money) values(:name,:age,:money)";
$stmt = $pdo->prepare($sql);
//绑定参数 此处冒号可省略,但是一定要加引号
$stmt->bindParam('name',$name);
$stmt->bindParam('age',$age);
$stmt->bindParam('money',$money);
//赋值
$name = 'liangliang';
$age = 23;
$money = 43000;
$stmt->execute();
//赋值
$name = "tietie";
$age = 25;
$money = 45000;
$stmt->execute();
不绑定参数,简写模式
<?php
header('content-type:text/html;charset=utf-8');
//PDO的使用
//准备dsn data source name
$dsn = "mysql:host=localhost;dbname=test";
//实例化PDO对象 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
$arr = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
try{
$pdo = new PDO($dsn,'root','',$arr);
}catch(PDOException $ex){
echo $ex->getMessage();
}
/*
//插入语句操作
//预处理
//占位符号及批量绑定
$sql = "insert into user(name,age,money) values(:name,:age,:money)";
$stmt = $pdo->prepare($sql);
//批量执行
$stmt->execute(array('name'=>'jiajia','age'=>21,'money'=>40000));
*/
/* //删除语句操作
//预处理
//占位符号 及批量绑定
$sql = "delete from user where id=:id";
$stmt = $pdo->prepare($sql);
//批量执行 简化写法 省去绑定参数 和赋值
$stmt->execute(array('id'=>3)); */
//更新语句操作
//预处理
//占位符号及批量绑定
$sql = "update user set name='huahua' where id=:id";
$stmt = $pdo->prepare($sql);
//批量执行 简化写法 省去参数绑定和赋值
$stmt->execute(array('id'=>4));
问号占位符:
<?php
header('content-type:text/html;charset=utf-8');
//PDO的使用
//准备dsn data source name
$dsn = "mysql:host=localhost;dbname=test";
//实例化PDO对象
try{
$pdo = new PDO($dsn,'root','');
}catch(PDOException $ex){
echo $ex->getMessage();
}
//设置字符集
$sql = "set names utf8";
$pdo->exec($sql);
//预处理
//问号占位符号 ?
//冒号占位符号 :
//准备模板
$sql = "insert into user(name,age,money) values(?,?,?)";
$stmt = $pdo->prepare($sql);
//绑定参数 1 2 3按问号顺序进行绑定
$stmt->bindParam(1,$name);
$stmt->bindParam(2,$age);
$stmt->bindParam(3,$money);
//赋值
$name = 'liangliang';
$age = 23;
$money = 43000;
$stmt->execute();
//赋值
$name = "tietie";
$age = 25;
$money = 45000;
$stmt->execute();
PDO的事务处理
事务处理概述
事务是确保数据库一致的机制,是一个或一系列的查询,作为一个单元的一组有序的数据库操作。如果组中的所有SQL语句都操作成功,则认为事务成功,事务则被提交,其修改将作用于所有其他数据库进程。即使在事务的组中只有一个环节操作失败,事务也不成功,则整个事务将被回滚,该事务中所有操作都将被取消。事务功能是企业级数据库的一个重要部分,因为很多业务过程都包括多个步骤。事务处理有4个重要特征:原子性(Atomicity)、一致性(Consistency)、独立性(Isolation)和持久性(Durability)即ACID
实例一
<?php
header('content-type:text/html;charset=utf-8');
//pdo的使用
//准备dsn data source name
$dsn = "mysql:host=localhost;dbname=test";
//实例化一个PDO对象
try{
$pdo = new PDO($dsn,'root','',array(3=>2));
}catch(PDOException $ex){
echo $ex->getMessage();
}
//使用数据设置字符集
$sql = "set names utf8";
$pdo->exec($sql);
//常规操作
//mysql>set autocommit = 0 关闭自动提交后 需要使用commit 确认 使用rollback 回滚
//mysql>set autocommit = 1 开启自动提交 默认是开启的 语句回车后 会直接执行 无法 回滚
//事务操作 表引擎必须是InnoDB
//启动事务 $pdo->beginTransaction();(pdo操作语句) mysql>begin;(操作数据的的语句) 自动提交关闭
$pdo->beginTransaction();
//中间可以做一系列的操作 任何一个环节失败,则整体失败
$money = 1;
$sql = "update shop_user set money = money - $money where id=1";
$rows = $pdo->exec($sql);
$sql = "update shop_user set money = money + $money where id=2";
$rows += $pdo->exec($sql);
if($rows == 2){
$pdo->commit(); //数据库操作语句 mysql>commit;
echo '转账成功';
}else{
$pdo->rollBack(); //数据库操作语句 mysql>rollback;
echo '转账失败';
}
try{
$pdo->beginTransaction();
//中间可以做一系列的操作 任何一个环节失败,则整体失败
$money = 1;
$sql = "update shop_user set money = money - $money where id=1";
$rows = $pdo->exec($sql);
$sql = "update shop_user set money = money + $money where id=2";
$rows = $pdo->exec($sql);
$pdo->commit(); //数据库操作语句 mysql>commit;
echo '转账成功';
}catch(PDOException $ex){
$pdo->rollBack(); //数据库操作语句 mysql>rollback;
echo '转账失败';
}
0 0
- 数据库抽象层--php高级最详细教程
- 命令空间--php高级最详细教程
- PHP数据库抽象层
- smarty模板引擎--php高级最详细教程
- PHP PDO数据库抽象层
- PHP数据库抽象层--PDO
- 数据库基础语法--php基础最详细教程
- PHP面向对象的程序设计封装--php高级最详细教程
- PHP面向对象的程序设计继承--php高级最详细教程
- PHP面向对象的程序设计多态--php高级最详细教程
- PHP面向对象的程序设计关键字--php高级最详细教程
- PHP面向对象的程序设计封装--php高级最详细教程
- PHP数据库抽象层PDO、ADODB、PHPLib
- PHP数据库抽象层PDO、ADODB、PHPLib
- PHP数据库抽象层PDO操作
- 13. php数据库抽象层PDO(一)
- 13. php数据库抽象层PDO(二)
- 14.php数据库抽象层PDO(三)
- ubuntu下安装JDK及环境变量配置
- 欢迎使用CSDN-markdown编辑器
- 16.2.1
- Python 网络数据采集——较好的资源
- 16.2.2
- 数据库抽象层--php高级最详细教程
- CSDN博客暂时停用,移至CNBLOG
- 16.3.1
- Java - main
- OpenSSL+zlib+libssh2编译(windows)
- Cool!
- MySQL Optimization Overview
- 16.3.2
- linux下mysql安装