发布于 1970-01-01 08:00
  • 5 个回答
    • 基于你的这个问题来说,你需要有一定的抽象能力,要有封装的概念,其实我更喜欢称之为分层,也就是我们要建立类似下列概念:

      上层角色 Upper Role
      ------------------层分界线------------
      当前层角色 Current Role
      ------------------层分界线------------
      下层角色 Lower Role
      

      基于上述概念来说,无论exit/die还是Exception可以分为2种情况:

       a. Upper Role作为接受方,Current Role作为行为方
       b. Current Role作为接受方,Lower Role作为行为方
      

      对于a来说,你要考虑的做出的行为的接受方Upper Role是谁?如果Upper Role是Top Role(顶层角色,一般基于我们的应用来说,顶层角色指的是使用浏览器的人),那么就应该用exit/die,这个是要Top Role做出处理的,也就是除了Top Role以外的所有Upper Role无权干涉,而当Upper Role非Top Role,那么就应该用Exception,这样除了Top Role以外的所有Upper Role才有权利去进行一些额外处理。

      基于a来说mysql_connect连接的事情,(按照我的设计)在使用mysql_connect时,Current Role指的是DB处理连接mysql相关逻辑,而Upper Role是调用DB的未知逻辑(想想这里我为什么要用“未知”这个概念),Current Role仅仅知道mysql_connect连接失败了,而并不知道Upper Role是否还有其他DB或额外选择,那么Current Role为了让Upper Role有一定选择权,这里(我)选择使用Exception,让Upper Role决定是交给Top Role处理还是更上层的Upper Role处理。

      对于b的情况来说,Current Role要判断Lower Role是不是会有一些非Current Role期望的情况出现(即:Exception),则有以下选择

      是否有非Current Role期望的情况
      如果没有,Current Role不需要try/catch,
      如果有,Current Role需要处理么?
          Current Role需要处理,try/catch
             Current Role可以处理?
                 可以处理,处理
                 Upper Role需要处理Current Role的非期望,throw          
          Current Role不需要处理,无视         
      

      基于b来说mysql_connect连接的事情,Current Role指的是需要用到DB的相关逻辑,而Lower Role是DB处理连接mysql相关逻辑,在Current Role使用的时候,Current Role期望mysql可以正常连接,但是额外情形也会出现,那么Current Role就要考虑自身的情况来选择,比如说Current Role是一个select操作,那么Current Role就是可以返回为空,那么对于msyql连接失败或者数据表真的为空,性质一样,Current Role就可以将非期望舍弃掉(捕获不处理)返回为空,而对于一个update来说,可以选择处理或者不处理都可以,而对于一个可以选择n个mysql 连接的逻辑来说,就必须处理,等等

      总之,啰嗦了一堆,就是说你要用好异常,那么你要有上下层的概念,并且在上下层逻辑处理中,要分清Current Role是可以终止程序执行(exit)还是交由Upper Role处理(throw Excepton)

      最后,throw是Current Role反馈给Upper Role,try/catch是Current Role处理Lower Role反馈,希望你能更好的使用Exception

      2022-12-01 17:10 回答
    • 楼主应该没有理解好 异常的执行机制,先读读PHP官方手册对异常的描述 点这里

      先不说异常该怎样使用,我们先看看 Exception 执行过程

      try {
      
          throw new Exception('This is first exception.');
      
          echo 'AAA';
      
      } catch (Exception $e) {
      
          echo 'BBB';
      
      }
      
      //这里会输出
      echo 'CCC';
      
      throw new Exception('This is second exception.');
      
      

      你觉得上面的输出结果是什么呢? 下面是答案

      BBBCCC
      
      Fatal error: Uncaught exception 'Exception' with message 'This is second exception.' ...
      

      从以上的执行结果,我们可以看出Exception的一些特点:

      1. try 与 catch 一定是成对出现的,try{ } 中包含可能会抛出异常的代码。
      2. try { } 中的代码一旦发生异常,那么异常后面的代码将停止执行。(这里特指try{ }里面的代码)
      3. 使用 catch(){ } 捕捉并处理完异常后,try{ }和catch(){} 后面的代码(比如这里的 echo 'CCC')会继续执行
      4. 如果异常没有被捕捉,那么将抛出一个致命错误 Fatal error。

      结合以上的特点,那么贴主提出来的疑问,就比较容易解决了。


      问题1:是不是每个有异常的地方都要try catch 一下?

      我的答案:这样做太麻烦了,而且一般没必要,你可以在所有可能抛出异常的地方,用一个 try catch 包含即可。catch 到异常后,对谁处理,怎么样处理都可以。这个也满足单一入口,单一出口的开发理念


      问题2:遇到错误,是抛 Exception 还是使用 die()/exit()

      我的答案:异常你可以随便抛,但最终你必须有个地方处理。处理完后(比如记录日志等等),最终你要把错误告诉前端用户,告诉这个过程就是输出。一旦发生错误时,我推荐使用异常 Exception,因为它符合单一出口开发理念,这样你可以监控所有页面输出。 如果到处使用 die()/exit()来直接输出,那就无法控制输出了

      再者,Exception 实际上本来就包含更丰富的信息,比如行数line、错误代码code、错误堆栈信息trace等等。所以不是更好吗?


      问题3:应用场景问题,该什么时候用?

      我的答案:异常在任何情况下用都可以,关键你想Exception起到什么作用了。比如自己在写API服务程序时,任何错误(包括程序异常、业务逻辑错误、字段类型错误等等),一律抛异常,一律由一个地方处理。实际上,我感觉这种开发体验是非常棒的,因为第一次写的时候,我不是使用Exception的,囧~。但这里有一个疑问:API 它是没有界面的,它只负责返回一些数据,而且返回的数据格式要求一般是统一的规范的

      如果你在写一个前端程序,我一边写一边想,可不可以这样使用 Exception任何程序错误抛异常,任何业务上的验证出错时使用比如 return/echo/die 返回这样子。 因为毕竟异常能表达的东西自然是有限的,如果有些错误(一般业务错误)返回非常复杂,而且前端应用非API 自由度会比较大,用异常或许不太方便。

      上面就是自己的愚见吧,有不对的地方,希望指出,共同进步吧!下班了,走人。。。

      2022-12-01 17:10 回答
    • 如果你希望全局捕获错误,或者异常,请看
      http://cn2.php.net/manual/zh/function.set-error-handler.php
      http://cn2.php.net/manual/zh/function.set-exception-handler.php

      都允许用一个callable对象捕获错误或者异常

      2022-12-01 17:10 回答
    • PHP调用exit退出脚本执行不会导致PHP服务退出,这个跟其他语言有本质区别,所以其他语言只好用try/catch捕获异常或判断返回值来进一步处理,对PHP则不是必须的。

      2022-12-01 17:10 回答
    • 看了这个帖子:http://bbs.phpchina.com/thread-212378-1-1.html,我的问题里可能没有理解异常,像数据库连不上或者配置文件丢失这种或许 halt 更安全直接虽然有点粗暴。

      2022-12-01 17:10 回答
    撰写答案
    今天,你开发时遇到什么问题呢?
    立即提问
    PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有