php5和php7的异常处理机制有区别吗

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销毁的是指定的存储地址上的内容;

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

原创文章,作者:ADGLU,如若转载,请注明出处:https://www.wangzhanshi.com/n/6968.html

(0)
ADGLU的头像ADGLU
上一篇 2025年1月1日 16:38:01
下一篇 2025年1月1日 16:38:03

相关推荐

  • PHP7中怎么操作MySQL数据库

    连接到 MySQL服务器 mysqli_connect(host, username, password [,dbname] [,port]); – 参数: host:…

    php 2025年1月1日
  • php5流程结构的详细介绍

    php5的流程结构有几种?分别是哪些?相信很多人都不太了解,为了让大家更加了解php5的流程结构,所以给大家总结了以下内容,一起往下看吧。 从执行方式上看,语句的控制结构分为以下三…

    php 2025年1月2日
  • PHP如何实现给页面设置独立访问密码

    PHP网页如果需要查看信息必须输入密码,验证后才可显示出内容的代码如何实现? 对某些php页面设置单独的访问密码,如果密码不正确则无法查看内容,相当于对页面进行了一个加密。 效果截…

    2024年12月17日
  • centos6与centos7安装php7的方法

    centos 7/6都可以 下载链接(当前最新版本是7.4.5) php官网 wget https://www.php.net/distributions/php-7.4…

    2025年1月1日
  • php7怎么安装mysql扩展

    php7安装mysql扩展的方法:首先在php网站上下载mysql扩展;然后解压并使用phpize工具初始化;接着把mysql.so拷贝到php.ini当前所在目录中;最后在php…

    2025年1月1日
  • linux中安装php5的方法

    linux安装php5的方法:首先下载“php-5.6.2.tar.gz”包;然后进行解压;接着通过“make install”进行编译安装;最后修改配置php.ini等相关文件即…

    2025年1月2日
  • centos yum如何安装php7

    centos yum安装php7的方法:首先安装PHP7相应的yum源;然后通过命令“yum install php70w”安装PHP7;最后通过“php -v”命令测试是否安装成…

    2025年1月1日
  • 安装php7并与php5共存的方法

    今天小编给大家分享的是 安装php7并与php5共存的方法,很多人都不太了解,今天小编为了让大家更加了解 安装php7并与php5共存的方法,所以给大家总结了以…

    php 2025年1月1日
  • PHP中比较两个对象的几种方式小结

    引言 在PHP中,比较两个对象并不是一件直接明了的事情,因为对象之间的比较通常依赖于它们的属性和状态,而这些属性和状态可能非常复杂且多样化。PHP提供了几种方式来比较对象,但每种方…

    php 2024年12月17日
  • php中闭包(Closure)的bindTo函数用法详解

    介绍 Closure::bindTo 是 PHP 中的一个方法,用于改变闭包(Closure)内部的 $this 上下文以及其静态范围。这意味着你可以将一个闭包从一个对象或类绑定到…

    php 2024年12月17日

发表回复

登录后才能评论