思考:在MySql中,有一种事务功能,能够帮助实现哪些需要多个步骤操作,然后一次性完成的,那么PDO中是如何实现的呢?
引入:其实,事务操作本质上是一种SQL操作,也就是说利用前面所说的写操作(事务都是写操作),就可以实现,而在PDO中,当然也提供
了一定的封装来实现这个功能,从而避免了一些简单的固定SQL执行的操作
PDO事务功能【了解】
定义:PDO事务功能,并非PDO额外多出了一项功能,而是将原来MySql所支持的事务操作进行了一定的封装实现。注意:事务执行是否成功是由MySql对应的存储引擎是否支持决定的
1.事务功能回顾:事务是指改变默认的一次操作一次写入数据表的机制,而是通过事务日志记录操作,在最后通过一次性操作写入到数据表。事务过程如下
- 开始事务:start transaction,写操作停止直接写入数据表,而是记录事务日志
- 事务操作:具体的写操作,通常多个步骤多条指令
- 提交事务:即事务操作结束
- 成功提交:commit,所有事务日志内容同步到数据表,并清空当前事务日志
- 失败提交 rollback ,直接清空当前事务日志
2.PDO类中提供一套方案来实现事务操作
- PDO::beginTransction()开启事务
- PDO::exec()执行事务-----写操作
- PDO::rollBack()回滚所有事务
- PDO::commit()成功提交事务
<?php //实例化PDO函数 封装 function PDO_ini($dsn){ $obj=@new PDO($dsn,'root','root'); if(!$obj){ exit('数据库连接失败'); }else{ return $obj; } } $dsn='mysql:host=localhost;port=3306;dbname=senven;charset=utf8'; $obj=PDO_ini($dsn); //开启事务 $obj->beginTransction() or die("事务开启失败"); //执行事务 $obj->exec('insert into hylist (hyid,hyname,hysex,hyphone) values ('','','','','')'); //省略下面步骤,使用事务必须是多条指令,一条没由意义 //终止事务 $obj->commit(); //成功提交事务 $obj->rollBack(); //失败回滚 ?>
3.在事务中,由一种回滚点机制,在PDO中没有实现,如果有必要,可以通过SQL指令设置实现
//我们在MySql中操作事务的时候,可以通过下面代码设置会给你点 start transction; #回滚点 savepoint sp1; rollback to sp1; //那么php中如何回滚点设置呢 $PDO->exec('savepoint sp1');
$PDO->exec('rollback to sp1');
总结:
事务的本质是由既定SL指令完成,二事务具体操作内容一定是外部指定的SQL(写操作)来处理
PDO提供了事务固定内容的封装,包括开启事务(PDO::beginTransction) 执行事务(PDO::exec()) 终止事务(PDO::commit()成功提交事务
PDO::rollBack()失败回滚事务);
回滚点可以通过PDO::exec();方法来设定
如果不采用PDO的事务机制,也可以完全利用PDO::exec()来实现
异常【掌握】
思考:目前我们所碰到的错误基本上是所见既所得。就是一旦出错,系统自动就给出错误信息,不过很多错误都是值,这样的话用户体验非常不好
有没有好的办法来解决呢?
引入:PHP因为是从面向过程发展而来,系统基本承担了所有编译层以及执行层出现的问题,即使现在到面向对象,系统也是直接报错(当然,生产环境会通过错误设置或者PHP.ini配置拟制错误)
而开发的时候,我们希望我们能抓住某些错误,而且通过合适的方式保存或者提示用户,此时就需要用到异常处理。
1.异常机制【掌握】
定义:异常机制Exception,是面向对象中一种错误捕捉机制。它允许开发人员将可能出现的错误被对象(Exception类)捕捉,然后在特定位置通过该对象来进行处理如:
$connt=4/0;
上述带代码在编译不存在时,但是在运行的时候因为被除数为0,所以会出现错误,而这个时候默认的,就是系统无法正确执行,立马给出错误(php默认规则),这种错误直接给出的方式不属于异常
不捕捉,异常捕获需要用到异常类Exception类及逆行捕捉:使用throw 抛出抓出。
<?php $a=10; $b=0; if($b==0){ //抛出一个异常类对象 throw new Exception('被除数不能为0'); } $count=$a/$b;
很明显,使用面向对象方式会额外增加代码来实现错误处理,但是在面向对象中,异常机制通常很成熟,并不需要写额外很多的代码,而且绝大部分时间里,我们不会处理
"不可能"出现问题的代码。
2.面向对象异常处理机制:如果可能出现未知错误(通常时因为外部数据的不确定),我们可以将代码块放到一个会自动捕捉的代码块中来实现异常处理。异常处理捕捉语法:
<?php //正常不会出错代码 echo 'hello word'; $a=10; $b=0; //可能出现异常代码;使用try进行包裹捕捉 try { //代码的执行具有未知性,但是代码没有语法错误 $count=$a/$b; } catch (Exception $e) { //捕捉后的处理代码;如果try中没有问题,不会进入到catch内部 //$e中保存了$conut =$a /$b;会出现的错误 die('出错了。。。'); //w未捕捉到错误 }
3.以上代码在php中运行即便出错也不会执行,原因时系统默认使用的警告模式,既有任何问题都是直接报错。如果想要实现异常处理,必须借助于系统提供的
set_error_handler(回调函数)来告知系统我们向采用的处理模式
//第一种方式 //匿名函数作为回调函数的 set_error_handler(function (){ throw new Exception('错误'); }); //第二种方式 function func(){ throw new Exception('出错'); } set_error_handler('func');
4.有了上述代码在错误处理之前,那么系统碰到错误,就会调用我们定义的function来进行错误处理,处理也两种模式:由try和没有try
5.异常对象$e到目前为止没有产生任何作用,其实Exception类中由很多的方法和属性,可以帮助我们获取错误信息的。
请参考手册
6.由的时候代码如果走到了一个“死胡同"即代码执行没有任何问题,但是不符合我们的逻辑,以前我们时跳转提示,现在可以抛出异常,交给异常来处理 throw new Exception();
<?php set_error_handler(function (){ throw new Exception('错误'); }); $n=0; try { if($n!=0){ $res=10/$n; }else{ //业务逻辑没法发展了,直接抛出个异常 throw new Exception('被除数不能为0!'); } } catch (Exception $e) { echo '错误的文件'.$e->getFile().'<br>'; echo '错误的行号'.$e->getLine().'<br>'; echo '错误的信息'.$e->getMessage().'<br>'; die(); }
总结:
1.异常时面向对象中处理错误的一种方式,能够让整体用一种同意的方式对外处理错误
2.异常机制时利用try()和chatch(Exception $e){}来进行捕捉处理的,Exception 类提供了很多方法可以方便获取各种错误相关信息
3.PHP默认是警告模式,即直接系统给出错误,如果想使用异常处理,那么就需要设置错误异常模式set_error_handle(异常回调函数)来实现
4.异常模式中,必须使用try catch才会捕捉异常,否则只会系统提示(如果因为异常处理代码太麻烦,可以将异常处理代码封装成函数或者类来实现简化)
PDO错误机制【了解】
思考:其实异常就是给了一种灵活的错误处理模式,而不是直接让系统把错误提示给用户,那PDO中也由自己的异常类,为什么就出现了错误依然还是直接提示呢?
引入:PDO有自己的一套异常机制,但是为了结合PHP本身的特性,并没有直接使用,在PDO中,错误模式是多种的,需要我们去先择才会生效。
定义:PDO错误机制,是指PDO在使用过程中出现了错误(大多是SQL指令执行错误)的时候,PDO处理错误的方式
1.PDO中提供了三种错误机制:是通过PDO的常量PDO::ATTR_ERRMODE来选择的
PDO::ERRMODE_SILENT:静默模式,出错了不处理(默认的);
PDO::ERRMODE_WANGNING:警告模式,出错了立马给出错误提示
PDO::ERROMODE_EXCEPTION:异常模式,出错了将错误交给异常PDOException对象
#PDO::ERRMODE_SILENT
<?php $link=new PDO('mysql:host=localhost;port=3306;dbname=senven;charset=utf8','root','root'); $link->exec('insert into hylist values ()'); //错误,但是不会报错 默认静默模式 ?>
#PDO::ERRMODE_WARNING
<?php $link=new PDO('mysql:host=localhost;port=3306;dbname=senven;charset=utf8','root','root'); //设置警告模式 $link->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING); $link->exec('insert into hylist values'); //报错,因为使用了警告模式 ?>
#PDO::EXCEPTION
<?php $link=new PDO('mysql:host=localhost;port=3306;dbname=senven;charset=utf8','root','root'); //设置警告模式 $link->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); try { $link->exec('delete fron hylist'); //报错,因为使用了警告模式 } catch (PDOException $e) { echo 'SQL语句错误'; echo '错误行号'.$e->getline(); //因为PDOException 继承了Exception echo '错误信息'.$e->getMessage(); exit; } ?>
总结:
1.PDO提供提供了多种错误处理机制,静默模式,警告模式,异常模式,其中静默模式为默认的
2.PDO可以通过PDO::setAttribute()方法来设定错误处理模式
3.PDO异常模式是通过PDOException来捕获异常的