搜索
首页后端开发php教程PHP中的异常处理

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 id="出现异常了-信息如下">出现异常了,信息如下</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 id="出现异常了">出现异常了。。。。。</h1> <p>刷新下试试</p> </body> </html> EOF;        return $message;    }}ini_set('display_errors','off');set_exception_handler(array('ExceptionHandler', 'handle'));//放在try catch中的throwtry {    throw new Exception("this is a test!",20010);} catch (Exception $e) {    echo $e->getMessage();}//没放在try catch中的throwthrow 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

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

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
PHP记录:PHP日志分析的最佳实践PHP记录:PHP日志分析的最佳实践Mar 10, 2025 pm 02:32 PM

PHP日志记录对于监视和调试Web应用程序以及捕获关键事件,错误和运行时行为至关重要。它为系统性能提供了宝贵的见解,有助于识别问题并支持更快的故障排除

在Laravel中使用Flash会话数据在Laravel中使用Flash会话数据Mar 12, 2025 pm 05:08 PM

Laravel使用其直观的闪存方法简化了处理临时会话数据。这非常适合在您的应用程序中显示简短的消息,警报或通知。 默认情况下,数据仅针对后续请求: $请求 -

php中的卷曲:如何在REST API中使用PHP卷曲扩展php中的卷曲:如何在REST API中使用PHP卷曲扩展Mar 14, 2025 am 11:42 AM

PHP客户端URL(curl)扩展是开发人员的强大工具,可以与远程服务器和REST API无缝交互。通过利用Libcurl(备受尊敬的多协议文件传输库),PHP curl促进了有效的执行

简化的HTTP响应在Laravel测试中模拟了简化的HTTP响应在Laravel测试中模拟了Mar 12, 2025 pm 05:09 PM

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显着减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

在Codecanyon上的12个最佳PHP聊天脚本在Codecanyon上的12个最佳PHP聊天脚本Mar 13, 2025 pm 12:08 PM

您是否想为客户最紧迫的问题提供实时的即时解决方案? 实时聊天使您可以与客户进行实时对话,并立即解决他们的问题。它允许您为您的自定义提供更快的服务

解释PHP中晚期静态结合的概念。解释PHP中晚期静态结合的概念。Mar 21, 2025 pm 01:33 PM

文章讨论了PHP 5.3中引入的PHP中的晚期静态结合(LSB),从而允许静态方法的运行时分辨率调用以获得更灵活的继承。 LSB的实用应用和潜在的触摸

自定义/扩展框架:如何添加自定义功能。自定义/扩展框架:如何添加自定义功能。Mar 28, 2025 pm 05:12 PM

本文讨论了将自定义功能添加到框架上,专注于理解体系结构,识别扩展点以及集成和调试的最佳实践。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。