极致控制下的异常错误处理
2012-11-25 02:27 游乐场123 阅读(297) 评论(0) 编辑 收藏 举报"PHP的try/catch只能捕捉一些异常类型的错误,而一些运行时的错误往往无法获取";
这句话一定要更改. 如果你在try中,
不使用if判断语句来:throw new Exception($error);的话, 你的catch块就是等到2012也不会被触发. 那既然已经if判断了,
我们为何还要用catch来处理异常呢? 自我定义一个统一函数, 如disucz的showmessage()来处理不是更好?
"set_error_handler也捕捉不到函数不存在"
的确set_error_handler无法实现,
但我们可以更深层次思考一下, 总要解决这个问题.
让register_shutdown_function+error_get_last来完成才是王道, 这样已经进入内存中运行的error_get_last()终于能够将错误捕捉了,
并且页面加载已经完成, 它仅仅做的是错误记录, 即不影响速度也不影响用户操作, 一切都在后台默默进行中.
个人建议, 无论如何,
都不要打印出异常信息, 不要试着随意去exit($error); 就算异常已经抛出, 作为一个技术员, 你自己也未必看得到, 比如QQ的网站集群,
页面数量那是相当可观的, 你即不可能去一一检查, 也不会有用户天天告诉你哪个页错误了, 在腾讯这种公司, 错误许可犯, 但自己都不知道错误在何时何地,
是不许可的. 建立一套完善的日志系统及追踪功能对腾讯来说非常重要. 它能够知道哪个页面访问量少了, 哪个页面错误异常, 哪个页面加载过慢.
这些都可以用app_htmlout()完成. 所以, 我建议大家都要布置一套这功能块, 让分散的信息全面集中.
下面看看示例.
- # 首先防止页面崩溃, 先注册个处理函数.
- register_shutdown_function('app_htmlout');
- #....................这儿随意写你的代码, 怎么混乱都行.
- # 不管中止还是结束访问, 此函数都会被调用起来
- function app_htmlout() {
- # 防止多次调用
- static $i = 0;
- empty($i) === false && fun_exit('');
- $i ++;
- # php错误获取
- $s = 0;
- $error = '';
- # 用error_get_last()取得错误信息
- if(is_null($e = error_get_last()) === false){
- if($e['type'] != 8){ // 去掉nitig的提示错误
- $error = 'PHP:';
- foreach($e as $key => $val){
- $error .=" $key: $val /"; // 将数据整合到一条, 这儿如何组合,完全看你自己.
- }
- $s = 1;
- $e = null; // 注销数组.
- $error .="\n";
- }
- }
- # 同时对mysql错误进行有效的获取
- if($e = mysql_error()){
- $error .= 'MYSQL: ';
- $error .= $e;
- $error .=' '.$_SERVER['SCRIPT_NAME'].var_export($_GET,true); // 对执行页php及GET参数进行收集, 以完整表达错误出现的条件是什么.
- $s = 1;
- $error .= "\n";
- }
- # 只有$s为1时, 才代表有错误. 所以写入日志, 注意路径一定要绝对的.
- if($s === 1){
- file_put_contents(ROOT."Data/error.log",$error,FILE_APPEND);
- }
- # 还可以操作一些其它事宜, 比如关闭mysql连接, 比如清空缓存, 也可以生成静态化文件.
- mysql::close();
- }