www.gusucode.com > iWebshop开源PHP商城系统 v2.8源码程序 > iwebshop/lib/core/util/exception_class.php
<?php /** * @copyright (c) 2011 jooyea.cn * @file exception_class.php * @brief 异常处理 * @author walu * @date 2011-07-22 * @version 0.1 */ if( !class_exists('Exception') ) { /** * 在php5.1之前,通过php代码中模拟Exception类 */ class Exception { /** * 异常信息 * @var mixed */ protected $message = 'Unknown exception'; /** * 用户自定义的异常代码 * @var mixed */ protected $code = 0; /** * 发生异常的文件名 * @var string */ protected $file; /** * 发生异常的代码行号 * @var int */ protected $line; private $backtrace; /** * 返回异常信息 * @return mixed * @final */ final function getMessage() { return $this->message; } /** * 返回异常代码 * @return mixed * @final */ final function getCode() { return $this->code; } /** * 返回发生异常的文件名 * @return string * @final */ final function getFile() { return $this->file; } /** * 返回发生异常的代码行号 * 如果php version小于5.1,则只能返回抛出异常的行号 * @return int * @final */ final function getLine() { return $this->line; } /** * 返回完整的debug_backtrace数组 * @return array * @final */ final function getTrace() { return $this->backtrace; } /** * 返回已经格式化为html字符串的debug_backtrace信息 * @return string * @final */ final function getTraceAsString() {} } } class IException extends Exception { private static $logPath = false; private static $debugMode = false; /** * 构造函数 * @param string $message * @param mixed $code */ public function __construct($message = null, $code = 0) { $bt = debug_backtrace(); //抛弃这一层,用上一层的 foreach($bt as $key=>$value) { //unset($bt[$key]); break; } $info = reset($bt); if($info !== false) { $this->message = $message; $this->code = $code; $this->file = $info['file']; $this->line = $info['line']; } $this->backtrace = $bt; } /** * 直接输出异常信息,不用catch */ public static function phpException($e) { if( !($e instanceof IException) && $e instanceof Exception ) { if( self::$debugMode ) { echo $e->getMessage(); } self::logError($e->getMessage()); return; } $e->show(); } public static function phpError($errno , $errstr,$errfile=false ,$errline=false,$errcontext=false ) { $errfile = self::pathFilter($errfile); $re = "<ERROR_INFO>\n"; $re .= "errID:{$errno}\n"; $re .= "errStr:{$errstr}\n"; $re .= "errFile:{$errfile}\n"; $re .= "errLine:{$errline}\n"; $re .= "errTime:".date("y-m-d H:i:s")."\n"; if(is_array($errcontext)) { $re .= "##出错时变量的值:##\n"; $re .= var_export($errcontext,true)."\n"; } $re .= "<\ERROR_INFO>\n"; self::logError($re); if( self::$debugMode ) { echo $re; exit; } } public static function pathFilter($path) { $iweb_path = IWEB_PATH; $iapp_path = IWeb::$app->getBasePath(); $count = 1; if( strpos($path,$iweb_path) ===0 ) { $path = str_replace(IWEB_PATH , "IWEB_PATH/",$path , $count); } elseif( strpos($path,$iapp_path) === 0 ) { $path = str_replace($iapp_path , "IAPP_PATH/" , $path ,$count ); } return $path; } public function show() { $bt = $this->getTrace(); $re = "<ERROR_INFO>\n"; $re .= sprintf("Mess: %s\n",$this->getMessage()); $re .= sprintf("Line: %s\n",$this->getLine()); $re .= sprintf("File: %s\n",self::pathFilter( $this->getFile() ) ); $re .= sprintf("##Debug_backtrace:##\n"); foreach($bt as $value) { $value['file'] = self::pathFilter($value['file']); $re .= sprintf("\tFunc:%-15s\tClass:%-15s\tType:%-5s\tLine:%-5s\tFile:%s\n" , isset($value['function'])?$value['function']: "" , isset($value['class'])?$value['class']:"", isset($value['type'])?$value['type']:"", isset($value['line'])?$value['line']:"", $value['file'] ); } $re .= "</ERROR_INFO>\n"; if( ! $this instanceof IHttpException ) self::logError($re); if( self::$debugMode ) { echo $re; exit; } } public static function setLogPath($path) { self::$logPath = $path; } public static function setDebugMode($mode) { self::$debugMode = $mode; } public static function logError($str) { if( self::$logPath) { $dir = dirname( self::$logPath ); if( !file_exists(self::$logPath) && !file_exists( $dir ) ) { $b = mkdir($dir,0777,true); if(!$b) { return; } } $fp = fopen(self::$logPath,"ab"); if($fp !== false) { fwrite($fp,$str); } } } } class IHttpException extends IException { /** * @brief 获取控制器 * @return object 控制器对象 */ public function getController() { return IWeb::$app->controller; } /** * @brief 报错 [适合在逻辑(非视图)中使用,此方法支持数据渲染] * @param string $httpNum HTTP错误代码 * @param array $errorData 错误数据 */ public function show() { $httpNum = $this->getCode(); $errorData = $this->getMessage(); $controller = $this->getController(); //初始化页面数据 $showData = array( 'title' => null, 'heading' => null, 'message' => null, ); if(is_array($errorData)) { $showData['title'] = isset($errorData['title']) ? $errorData['title'] : null; $showData['heading'] = isset($errorData['heading']) ? $errorData['heading'] : null; $showData['message'] = isset($errorData['message']) ? urlencode($errorData['message']) : null; } else { $showData['message'] = urlencode($errorData); } //检查用户是否定义了error处理类 $config = isset( IWeb::$app->config['exception_handler'] ) ? IWeb::$app->config['exception_handler'] : 'Error' ; $flag = class_exists($config); if( $flag && method_exists($config,"error{$httpNum}") ) { $errorObj = new $config(IWeb::$app,'error'); call_user_func(array($errorObj,'error'.$httpNum),$errorData); } //是系统内置的错误机制 else if(file_exists(IWEB_PATH.'web/view/'.'error'.$httpNum.$controller->extend)) { $controller->render(IWEB_PATH.'web/view/'.'error'.$httpNum,$showData); } //输出错误信息 else { $controller->renderText($showData['message']); } exit; } }