Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 691|回复: 0

php5和php7的异常处理机制 ----thinkphp5 异常处理的分析

[复制链接]
  • TA的每日心情
    奋斗
    7 天前
  • 签到天数: 803 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726482
    发表于 2021-4-25 12:30:38 | 显示全部楼层 |阅读模式

    1.php异常和错误

    在其他语言中,异常和错误是有区别的,但是PHP,遇见自身错误时,会触发一个错误,而不是跑出异常。并且,php大部分情况,都会触发错误,终止程序执行,在php5中,try catch是没有办法处理错误的。

    php7是可以捕获错误的;

    1.1 php5 错误异常

    // 1.异常处理
    try
    {   throw new Exception("Error Processing Request", 1); }catch ( Exception $e){   echo $e->getCode().'<br/>';   echo $e->getMessage().'<br/>';   echo $e->getLine().'<br/>';   echo $e->getFile().'<br/>'; } 返回: 1 Error Processing Request 158 E:\phpwebenv\PHPTutorial\WWW\test\index.php // 2.结果php错误处理机制 function MyErrorHandler($error,$errstr,$errfile,$errline){ echo '<b> Custom error:</b>'.$error.':'.$errstr.'<br/>'; echo "Error on line $errline in ".$errfile; } set_error_handler('MyErrorHandler',E_ALL|E_STRICT); try{ // throw new Exception("Error Processing Request", 4);   trigger_error('error_msg'); }catch ( Exception $e){   echo $e->getCode().'<br/>';   echo $e->getMessage().'<br/>';   echo $e->getLine().'<br/>';   echo $e->getFile().'<br/>'; } 结果: Custom error:1024:error_msg Error on line 164 in E:\phpwebenv\PHPTutorial\WWW\test\index.php //3. 处理致命错误:脚本结束后执行 function shutdown_function(){   $e = error_get_last();   echo '<pre/>';   var_dump($e); } register_shutdown_function('shutdown_function'); try{ // throw new Exception("Error Processing Request", 4); // trigger_error('error_msg');   fun(); }catch ( Exception $e){   echo $e->getCode().'<br/>';   echo $e->getMessage().'<br/>';   echo $e->getLine().'<br/>';   echo $e->getFile().'<br/>'; } 结果: Fatal error: Uncaught Error: Call to undefined function fun() in E:\phpwebenv\PHPTutorial\WWW\ test\index.php:172 Stack trace: #0 {main} thrown in E:\phpwebenv\PHPTutorial\WWW\test\index.php on line 172 array(4) { ["type"]=> int(1) ["message"]=> string(131) "Uncaught Error: Call to undefined function fun() in E:\phpwebenv\PHPTutorial\WWW\test\index.php:172 Stack trace: #0 {main} thrown" ["file"]=> string(43) "E:\phpwebenv\PHPTutorial\WWW\test\index.php" ["line"]=> int(172) } 以上方法可以看出,php没有捕获到异常,只能依赖set_error_handler()和register_shutdown_function();来处理,set_error_handler只能接受 异常和非致命的错误。register_shutdown_function():主要针对die()或致命错误,即程序终结后执行;所以php5没有很好的异常处理机制。

     1.2 php7的异常处理

    // 处理致命错误:脚本结束后执行
    function shutdown_function(){
        $e = error_get_last();
        echo '<pre>';
        var_dump($e);
    }
    register_shutdown_function('shutdown_function');
    // 结果php错误处理机制
    function MyErrorHandler($error,$errstr,$errfile,$errline){
        echo '<b> Custom error:</b>'.$error.':'.$errstr.'<br/>';
        echo "Error on line $errline in ".$errfile;
    }
    set_error_handler('MyErrorHandler',E_ALL|E_STRICT);
    try{
        // throw new Exception("Error Processing Request", 4);
        // trigger_error('error_msg');
        fun();
    }catch ( Error $e){
        echo $e->getCode().'<br/>';
        echo $e->getMessage().'<br/>';
        echo $e->getLine().'<br/>';
        echo $e->getFile().'<br/>';
    }
    结果:
    0
    Call to undefined function fun()
    172
    E:\phpwebenv\PHPTutorial\WWW\test\index.php
    NULL  
    register_shutdown_function();没有捕获到异常

     

    // 2. 如果不用try catch 捕获
    
    function exception_handler( Throwable $e){
    
        echo 'catch Error:'.$e->getCode().':'.$e->getMessage().'<br/>';
    
    
    }
    
    set_exception_handler('exception_handler');
    
    fun();

     总结: Throwable 是Error 和 Exception 的基类,在php7中,如果既想捕获异常有需要捕获错误

    try{
        fun();
    }catch ( Throwable $e){
        echo $e->getCode().'<br/>';
        echo $e->getMessage().'<br/>';
        echo $e->getLine().'<br/>';
        echo $e->getFile().'<br/>';
    }

     

     3. thinkphp5框架的错误处理:

    在异常错误处理类:Error有这个处理  
    // 注册错误和异常处理机制
    \think\Error::register();
     /**
         * 注册异常处理
         * @return void
         */
        public static function register()
        {
            error_reporting(E_ALL);
            set_error_handler([__CLASS__, 'appError']);
            set_exception_handler([__CLASS__, 'appException']);
            register_shutdown_function([__CLASS__, 'appShutdown']);
        }
    当程序出现错误时,会执行这些异常、错误的函数;

    链接数据库后,处理异常的是:

    /**
         * 连接数据库方法
         * @access public
         * @param array         $config 连接参数
         * @param integer       $linkNum 连接序号
         * @param array|bool    $autoConnection 是否自动连接主数据库(用于分布式)
         * @return PDO
         * @throws Exception
         */
        public function connect(array $config = [], $linkNum = 0, $autoConnection = false)
        {
            if (!isset($this->links[$linkNum])) {
                if (!$config) {
                    $config = $this->config;
                } else {
                    $config = array_merge($this->config, $config);
                }
                // 连接参数
                if (isset($config['params']) && is_array($config['params'])) {
                    $params = $config['params'] + $this->params;
                } else {
                    $params = $this->params;
                }
                // 记录当前字段属性大小写设置
                $this->attrCase = $params[PDO::ATTR_CASE];
    
                // 数据返回类型
                if (isset($config['result_type'])) {
                    $this->fetchType = $config['result_type'];
                }
                try {
                    if (empty($config['dsn'])) {
                        $config['dsn'] = $this->parseDsn($config);
                    }
                    if ($config['debug']) {
                        $startTime = microtime(true);
                    }
                    $this->links[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $params);
                    if ($config['debug']) {
                        // 记录数据库连接信息
                        Log::record('[ DB ] CONNECT:[ UseTime:' . number_format(microtime(true) - $startTime, 6) . 's ] ' . $config['dsn'], 'sql');
                    }
                } catch (\PDOException $e) {
                    if ($autoConnection) {
                        Log::record($e->getMessage(), 'error');
                        return $this->connect($autoConnection, $linkNum);
                    } else {
                        throw $e;
                    }
                }
            }
            return $this->links[$linkNum];
        }

    当数据库链接失败后,可以重新链接或者直接抛出异常;

        /**
         * 析构方法
         * @access public
         */
        public function __destruct()
        {
            // 释放查询
            if ($this->PDOStatement) {
                $this->free();
            }
            // 关闭连接
            $this->close();
        }
     
     

    当执行sql失败后,调用析构方法,关闭数据库链接;

     

     4. php发生错误时,资源释放

    php是解释性脚本,每个php页面都是一个独立的执行程序,不管用什么方式只要执行完了(包括die(),exit(),致命错误终止程序),都会把结果返回给服务器,都会关闭。程序都关闭了,资源当然会被释放;

    unset();当多个变量名或者对象名指向一块存储地址时,unset()函数的作用仅仅是销毁变量名和存储地址的指向而已,当仅有一个变量名或者对象名,unset销毁的是指定的存储地址上的内容;

    析构方法:当实例化的对象,没有其他变量或对象名指向时,就会执行此方法;或者是在脚本结束后,释放对象资源时,执行此方法;

    参考资料:http://blog.csdn.net/zhang197093/article/details/75094816

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-24 14:43 , Processed in 0.566988 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表