基于你的这个问题来说,你需要有一定的抽象能力,要有封装的概念,其实我更喜欢称之为分层,也就是我们要建立类似下列概念:
上层角色 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
楼主应该没有理解好 异常的执行机制,先读读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的一些特点:
echo 'CCC'
)会继续执行。结合以上的特点,那么贴主提出来的疑问,就比较容易解决了。
问题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 自由度会比较大,用异常或许不太方便。
上面就是自己的愚见吧,有不对的地方,希望指出,共同进步吧!下班了,走人。。。
如果你希望全局捕获错误,或者异常,请看
http://cn2.php.net/manual/zh/function.set-error-handler.php
http://cn2.php.net/manual/zh/function.set-exception-handler.php
都允许用一个callable对象捕获错误或者异常
PHP调用exit退出脚本执行不会导致PHP服务退出,这个跟其他语言有本质区别,所以其他语言只好用try/catch捕获异常或判断返回值来进一步处理,对PHP则不是必须的。
看了这个帖子:http://bbs.phpchina.com/thread-212378-1-1.html,我的问题里可能没有理解异常,像数据库连不上或者配置文件丢失这种或许 halt 更安全直接虽然有点粗暴。