码迷,mamicode.com
首页 > Web开发 > 详细

PHP中的异常处理

时间:2015-07-13 12:19:48      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:捕获   异常处理   异常   

1.什么是异常?异常和错误有什么区别?

1.异常:程序运行与预期不太一致,与错误是两个不同的概念!
2.抛出和捕获异常
3.多个catch块的时候基类要往后放,否则基类捕获异常后就不会往下继续捕获了!
3.先出现错误,在出现异常,所以写api的时候一定要把display_errors关掉
4.php的内置异常

error_reporting(-1);
ini_set(‘display_errors‘,‘off‘);

//pdo内置异常类
try {
    $pdo = new PDO(‘mysql:host=localhost;dbname=mysql‘, ‘brave‘, ‘123456‘);
    var_dump($pdo);
    echo ‘<hr/>‘;
    echo ‘continue.......‘;
} catch (Exception $e) {
    echo $e->getMessage();
}
echo ‘this is a test.......‘;

echo ‘<hr/>‘;

//spl文件读写内置异常类
try {
    $splObj = new SplFileObject(‘test.txt‘, ‘r‘);
    echo ‘read file‘;
} catch (RuntimeException $e) {
    echo $e->getMessage();
}
echo ‘continue.......‘;

echo ‘<hr/>‘;

2.异常的基本语法结构

    try {
        //需要进行异常处理的代码
        throw语句抛出
    } catch (PdoException $e) {

        try {
             throw语句抛出
        } catch (Exception $e) {

        }

    } catch (FileException $e) {

    } catch (CustomException $e) {

    }

    //other code

3.如何自定义异常类?

error_reporting(-1);
ini_set(‘display_errors‘,‘off‘);
class MyException extends Exception{

    function __construct($message, $code=0)
    {
        parent::__construct($message, $code);
    }

    public function __toString(){
        $message = "<h2>出现异常了,信息如下</h2>";
        $message .="<p>".__CLASS__." [{$this->code}]:{$this->message}</p>";
        return $message;
    }

    public function test(){
        echo ‘this is a test‘;
    }

    public function stop(){
        exit(‘script end..............<hr/>‘);
    }

    //自定义其他方法
}

try {
    echo ‘出现异常了!‘;
    throw new MyException("测试自定义异常!", 11);
} catch (MyException $e) {
    echo $e->getMessage(); 
    echo ‘<hr/>‘;
    echo $e;
    echo ‘<hr/>‘;
    $e->stop();
    $e->test();
}

4.自定义文件异常类

error_reporting(-1);
ini_set(‘display_errors‘,‘off‘);

class FileException extends Exception
{
    public function getDetails()
    {
        switch ($this->code) {
            case 0:
                return ‘没有提供文件!‘;
                break;

            case 1:
                return ‘文件不存在!‘." trace".$this->getTraceAsString().$this->getLine();
                break;

            case 2:
                return ‘不是一个文件!‘." trace".$this->getTraceAsString().$this->getLine();
                break;

            case 3:
                return ‘文件不可写!‘;
                break;

            case 4:
                return ‘非法文件的操作模式!‘;
                break;

            case 5:
                return ‘数据写入失败!‘;
                break;

            case 6:
                return ‘文件不能被关闭!‘;
                break;

            default:
                return ‘非法!‘;
                break;
        }
    }
}

class WriteData{
    private $_message=‘‘;
    private $_fp=null;

    public function __construct($filename=null, $mode=‘w‘){
        $this->_message="文件:{$filename} 模式:{$mode}";
        if (empty($filename)) {
            throw new FileException($this->_message, 0);
        }
        if (!file_exists($filename)) {
            throw new FileException($this->_message, 1);
        }
        if (!is_file($filename)) {
            throw new FileException($this->_message, 2);
        }
        if (!is_writable($filename)) {
            throw new FileException($this->_message, 3);
        }
        if (!in_array($mode, array(‘w‘, ‘w+‘, ‘a‘, ‘a+‘))) {
            throw new FileException($this->_message, 4);
        }
        $this->_fp=fopen($filename, $mode);
    }

    /**
     * [write 写数据]
     * @param  [type] $data [description]
     * @return [type]       [description]
     */
    public function write($data){
        if (@!fwrite($this->_fp, $data.PHP_EOL)) {
            throw new FileException($this->_message, 5);
        }
    }

    /**
     * [close 关闭文件句柄]
     * @return [type] [description]
     */
    public function close(){
        if ($this->_fp) {
            if (@!fclose($this->_fp)) {
                throw new FileException($this->_message, 6);
                $this->_fp=null;
            }
        }
    }

    public function __destruct(){
        $this->close();
    }
}

try {
    $fp = new WriteData(‘test.txt‘, ‘w‘);
    $fp->write(‘this is a test‘);
    $fp->close();
    echo ‘数据写入成功!‘;
} catch (FileException $e) {
    echo ‘出问题了:‘.$e->getMessage().‘ 详细信息如下:‘.$e->getDetails();
}

5.使用观察者模式处理异常

  1. 定义观察(异常)的类, 可以在代码中动态的添加观察者
    /**
     * 观察(异常)的类, 可以在代码中动态的添加观察者
     */
    class Observable_Exception extends Exception
    {
        public static $_observers=array();
        public static function attach(Exception_Observer $observer){
            self::$_observers[]=$observer;
        }

        public function __construct($message=null, $code=0){
            parent::__construct($message, $code);
            $this->notify();
        }

        public function notify(){
            foreach (self::$_observers as $observer) {
                $observer->update($this);
            }
        }

    }

2.定义异常观察者基类用于规范每一个观察者

    /**
     * 观察者基类,用于规范每一个观察者
     */
    interface Exception_Observer{
        //强制指定必须是我们规定的观察类
        public function update(Observable_Exception $e);

    }

3.定义日志观察者

    /**
     * 定义日志观察者
     */
    class Logging_Exception_Observer implements Exception_Observer{
        public $_filename=‘./log_exception.log‘;

        public function __construct($filename=null){
            if ($filename!==null && is_string($filename)) {
                $this->_filename=$filename;
            }
        }

        public function update(Observable_Exception $e){
            $message="时间:".date(‘Y-m-d H:i:s‘).PHP_EOL;
            $message.="信息:".$e->getMessage().PHP_EOL;
            $message.="追踪信息:".$e->getTraceAsString().PHP_EOL;
            $message.="文件:".$e->getFile().PHP_EOL;
            $message.=‘行号:‘.$e->getLine().PHP_EOL;
            error_log($message, 3, $this->_filename);
        }
    }

4.定义邮件观察者

    /**
     * 定义邮件观察者
     */
    class Email_Exception_Observer implements Exception_Observer{
        public $_email=‘732578448@qq.com‘;

        public function __construct($email=null){
            if ($email!==null && filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $this->_email=$email;
            }
        }

        public function update(Observable_Exception $e){
            $message="时间:".date(‘Y-m-d H:i:s‘).PHP_EOL;
            $message.="信息:".$e->getMessage().PHP_EOL;
            $message.="追踪信息:".$e->getTraceAsString().PHP_EOL;
            $message.="文件:".$e->getFile().PHP_EOL;
            $message.=‘行号:‘.$e->getLine().PHP_EOL;
            error_log($message, 1, $this->_email);
        }
    }

5.执行测试

error_reporting(-1);
ini_set(‘display_errors‘,‘off‘);
//引入观察异常的类
require ‘Observable_Exception.php‘;
//引入观察者基类
require ‘Exception_Observer.php‘;
//引入日志观察者
require ‘Logging_Exception_Observer.php‘;
//引入邮件观察者
require ‘Email_Exception_Observer.php‘;

Observable_Exception::attach(new Logging_Exception_Observer());
//自定义地址记录错误异常
Observable_Exception::attach(new Logging_Exception_Observer(‘/tmp/test11.log‘));
Observable_Exception::attach(new Email_Exception_Observer());
//自定义邮件接收人记录错误异常
Observable_Exception::attach(new Email_Exception_Observer(‘123456@qq.com‘));
class MyException extends Observable_Exception{
    public function test(){
        echo ‘this is a test!‘;
    }

    public function test1(){
        echo ‘我是 自定义的方法处理这个异常!‘;
    }
}

try {
    throw new MyException("出现异常了,记录一下下!");

} catch (MyException $e) {
    echo $e->getMessage();
    echo ‘<hr/>‘;
    $e->test();
    echo ‘<hr/>‘;
    $e->test1();
}

6.自定义异常处理器(set_exception_handler)?

1.目的1处理所有未捕获的异常
2.目的2处理所有我们为放到try catch中的异常

3.自定义异常处理函数

ini_set(‘display_errors‘,‘off‘);
function exceptionHandler_1($e){
  echo ‘自定义异常处理器1‘.__FUNCTION__;
  echo ‘异常信息:‘.$e->getMessage();
}

function exceptionHandler_2($e){
  echo ‘自定义异常处理器2‘.__FUNCTION__;
  echo ‘异常信息:‘.$e->getMessage();
}
set_exception_handler(‘exceptionHandler_1‘);
set_exception_handler(‘exceptionHandler_2‘);
//恢复到上一次定义过的异常处理函数
restore_exception_handler();
throw new Exception(‘测试‘);
echo ‘continue........‘;
echo ‘<hr/>‘;

4.自定义异常处理类

/**
 * 自定义错误异常类
 */
class ExceptionHandler{
    protected $_exception;
    protected $_logFile=‘./testExceptionHandler.log‘;

    function __construct(Exception $e){
        //保存异常对象
        $this->_exception = $e;
    }

    public static function handle(Exception $e){
        $self = new self($e);
        $self->log();
        echo $self;
    }

    public function log(){
        $msg=<<<EOF
        出现了通知错误,如下
产生通知的文件:{$this->_exception->getFile()}<br>
产生通知的信息:{$this->_exception->getTraceAsString()}
产生通知的行号:{$this->_exception->getLine()}
产生通知的错误号:{$this->_exception->getCode()}
产生通知的时间:{$datetime}
\n
EOF;
        echo $msg;
        error_log($msg, 3, $this->_logFile);
    }

    public function __toString(){
        $message = <<<EOF
        <!DOCTYPE html>
        <html>
        <head>
            <title></title>
        </head>
        <body>
            <h1>出现异常了。。。。。</h1>
            <p>刷新下试试</p>
        </body>
        </html>
EOF;
        return $message;
    }
}



ini_set(‘display_errors‘,‘off‘);
set_exception_handler(array(‘ExceptionHandler‘, ‘handle‘));

//放在try catch中的throw
try {
    throw new Exception("this is a test!",20010);
} catch (Exception $e) {
    echo $e->getMessage();
}

//没放在try catch中的throw
throw new Exception("测试未捕获的自定义的异常处理器hello world!",2008);

7.如何像处理异常一样处理PHP的错误?

1.通过ErrorException

function exception_error_handler($errno, $errstr, $errfile, $errline){
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

set_error_handler(‘exception_error_handler‘);
try {
    echo gettype();
} catch (Exception $e) {
    echo $e->getMessage();
}

2.自定义异常类

class ErrorToException extends Exception{

    public static function handle($errno, $errstr)
    {
        throw new self($errstr, $errno);
    }
}

ini_set(‘display_errors‘, ‘off‘);
set_error_handler(array(‘ErrorToException‘, ‘handle‘));
set_error_handler(array(‘ErrorToException‘, ‘handle‘),E_USER_WARNING|E_WARNING);

try {
    echo $test;
    gettype();
    trigger_error(‘test‘,E_USER_WARNING);
} catch (Exception $e) {
    echo $e->getMessage();
}

8.在发生错误的时候将用户重定向到另一个页面

class ExceptionRedirectHandler{
    protected $_exception;
    protected $_logFile=‘./redirectLog.log‘;
    protected $_redirect=‘404.html‘;

    public function __construct(Exception $e){
        $this->_exception=$e;
    }

    public static function handle(Exception $e){
        $self = new self($e);
        $self->log();
        while (@ob_end_clean());
        header(‘HTTP/1.1 307 Temporary Redirect‘);
        header(‘Cache-Control:no-cache,must-revalidate‘);
        header(‘Expires: Wed, 01 Jul 2015 07:40:45 GMT‘);
        header(‘Location:‘.$self->_redirect);
        exit(1);
    }

    public function log($value=‘‘){
        error_log($this->_exception->getMessage().PHP_EOL, 3, $this->_logFile);
    }
}

ini_set(‘display_errors‘,‘off‘);
set_exception_handler(array(‘ExceptionRedirectHandler‘, ‘handle‘));
$link = mysql_connect(‘localhost‘, ‘brave‘, ‘123456123‘);
if (!$link) {
    throw new Exception("数据库受到攻击了,赶快去看看吧!");

}

9.设置自定义错误和异常需要传递的参数

异常传递:$msg, $code
错误传递:$errno, $errmsg, $errfile, $errline 可看MyErrorHandler.php

版权声明:本文为博主原创文章,未经博主允许不得转载。

PHP中的异常处理

标签:捕获   异常处理   异常   

原文地址:http://blog.csdn.net/wjc19911118/article/details/46859339

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!