CrossPHP
  • Namespace
  • Class
  • Download

Namespaces

  • Cross
    • Auth
    • Cache
      • Driver
      • Request
    • Core
    • DB
      • Connecter
      • Drivers
      • SQLAssembler
    • Exception
    • Http
    • I
    • Lib
      • Document
    • Module
    • MVC
    • Runtime
  • None

Classes

  • Cross\Auth\CookieAuth
  • Cross\Auth\SessionAuth
  • Cross\Cache\Driver\FileCacheDriver
  • Cross\Cache\Driver\MemcacheDriver
  • Cross\Cache\Driver\RedisDriver
  • Cross\Cache\Request\FileCache
  • Cross\Cache\Request\Memcache
  • Cross\Cache\Request\RedisCache
  • Cross\Cache\RequestCache
  • Cross\Core\Annotate
  • Cross\Core\Application
  • Cross\Core\ArrayMap
  • Cross\Core\Config
  • Cross\Core\CrossArray
  • Cross\Core\Delegate
  • Cross\Core\FrameBase
  • Cross\Core\Helper
  • Cross\Core\HttpAuth
  • Cross\Core\Loader
  • Cross\Core\Rest
  • Cross\Core\Router
  • Cross\DB\Connecter\BaseConnecter
  • Cross\DB\Connecter\MySQLConnecter
  • Cross\DB\Connecter\PgSQLConnecter
  • Cross\DB\Connecter\SQLiteConnecter
  • Cross\DB\DBFactory
  • Cross\DB\Drivers\CouchDriver
  • Cross\DB\Drivers\MongoDriver
  • Cross\DB\Drivers\PDOSqlDriver
  • Cross\DB\SQLAssembler\MySQLAssembler
  • Cross\DB\SQLAssembler\PgSQLAssembler
  • Cross\DB\SQLAssembler\SQLAssembler
  • Cross\DB\SQLAssembler\SQLiteAssembler
  • Cross\Http\Request
  • Cross\Http\Response
  • Cross\Lib\Array2XML
  • Cross\Lib\Document\CallTree
  • Cross\Lib\Document\CallTreeToHTML
  • Cross\Lib\Document\HTML
  • Cross\Lib\StringToPHPStream
  • Cross\Module\SQLModule
  • Cross\MVC\Controller
  • Cross\MVC\Module
  • Cross\MVC\View
  • Cross\Runtime\ClosureContainer

Interfaces

  • Cross\I\CacheInterface
  • Cross\I\HttpAuthInterface
  • Cross\I\PDOConnecter
  • Cross\I\RequestCacheInterface
  • Cross\I\RouterInterface
  • Cross\I\SqlInterface

Exceptions

  • Cross\Exception\CacheException
  • Cross\Exception\CoreException
  • Cross\Exception\CrossException
  • Cross\Exception\FrontException

Functions

  • ascLogo
  • line
  • tBody
  • th
  • tHead
  1 <?php
  2 /**
  3  * Cross - a micro PHP 5 framework
  4  *
  5  * @link        http://www.crossphp.com
  6  * @license     MIT License
  7  */
  8 
  9 namespace Cross\Exception;
 10 
 11 use Cross\Http\Response;
 12 use ReflectionMethod;
 13 use ReflectionClass;
 14 use SplFileObject;
 15 use Exception;
 16 
 17 /**
 18  * @author wonli <wonli@live.com>
 19  * Class CrossException
 20  * @package Cross\Exception
 21  */
 22 abstract class CrossException extends Exception
 23 {
 24     /**
 25      * CrossException constructor.
 26      *
 27      * @param string $message
 28      * @param null|int $code
 29      * @param Exception|null $previous
 30      */
 31     function __construct($message = 'CrossPHP Exception', $code = null, Exception $previous = null)
 32     {
 33         parent::__construct($message, $code, $previous);
 34         if (PHP_SAPI === 'cli') {
 35             set_exception_handler(array($this, 'cliErrorHandler'));
 36         } else {
 37             set_exception_handler(array($this, 'errorHandler'));
 38         }
 39     }
 40 
 41     /**
 42      * 根据trace信息分析源码,生成异常处理详细数据
 43      *
 44      * @param Exception $e
 45      * @return array
 46      */
 47     function cpExceptionSource(Exception $e)
 48     {
 49         $file = $e->getFile();
 50         $exception_line = $e->getLine();
 51 
 52         $exception_file_source = array();
 53         $exception_file_info = new SplFileObject($file);
 54         foreach ($exception_file_info as $line => $code) {
 55             $line += 1;
 56             if ($line <= $exception_line + 6 && $line >= $exception_line - 6) {
 57                 $exception_file_source[$line] = self::highlightCode($code);
 58             }
 59         }
 60 
 61         $result['main'] = array(
 62             'file' => $file,
 63             'line' => $exception_line,
 64             'message' => $this->hiddenFileRealPath($e->getMessage()),
 65             'show_file' => $this->hiddenFileRealPath($file),
 66             'source' => $exception_file_source,
 67         );
 68 
 69         $trace = $e->getTrace();
 70         $this->getTraceInfo($trace, $result['trace']);
 71         if ($e->getPrevious()) {
 72             $this->getTraceInfo($e->getPrevious()->getTrace(), $result['previous_trace']);
 73         }
 74 
 75         return $result;
 76     }
 77 
 78     /**
 79      * cli模式下的异常处理
 80      *
 81      * @param Exception $e
 82      */
 83     function cliErrorHandler(Exception $e)
 84     {
 85         $trace_table = array();
 86         $trace = $e->getTrace();
 87         $this->getCliTraceInfo($trace, $trace_table);
 88 
 89         $previous_trace = array();
 90         if ($e->getPrevious()) {
 91             $previous_trace = $e->getPrevious()->getTrace();
 92             $this->getCliTraceInfo($previous_trace, $trace_table);
 93         }
 94 
 95         $result['line'] = $e->getLine();
 96         $result['file'] = $e->getFile();
 97         $result['message'] = $e->getMessage();
 98 
 99         $result['trace'] = $trace;
100         $result['trace_table'] = $trace_table;
101         $result['previous_trace'] = $previous_trace;
102 
103         Response::getInstance()->display($result, __DIR__ . '/tpl/cli_error.tpl.php');
104     }
105 
106     /**
107      * trace
108      *
109      * @param array $trace
110      * @param $content
111      */
112     protected function getTraceInfo(array $trace, &$content)
113     {
114         if (!empty($trace)) {
115             $this->alignmentTraceData($trace);
116             foreach ($trace as $tn => &$t) {
117                 if (!isset($t['file'])) {
118                     continue;
119                 }
120 
121                 $i = 0;
122                 $trace_file_info = new SplFileObject($t['file']);
123                 foreach ($trace_file_info as $line => $code) {
124                     $line += 1;
125                     if (($line <= $t['end_line'] && $line >= $t['start_line']) && $i < 16) {
126                         $t['source'][$line] = self::highlightCode($code);
127                         $i++;
128                     }
129                 }
130 
131                 $content[] = $t;
132             }
133         }
134     }
135 
136     /**
137      * CLI trace
138      *
139      * @param array $trace
140      * @param $trace_table
141      */
142     protected function getCliTraceInfo(&$trace, &$trace_table)
143     {
144         if (!empty($trace)) {
145             $this->alignmentTraceData($trace);
146             foreach ($trace as &$t) {
147                 foreach ($t as $type_name => &$trace_content) {
148                     switch ($type_name) {
149                         case 'file':
150                         case 'line':
151                         case 'function':
152                             $line_max_width = max(strlen($type_name), strlen($trace_content));
153                             if (($line_max_width % 2) != 0) {
154                                 $line_max_width += 5;
155                             } else {
156                                 $line_max_width += 4;
157                             }
158 
159                             if (!isset($trace_table[$type_name]) || $line_max_width > $trace_table[$type_name]) {
160                                 $trace_table[$type_name] = $line_max_width;
161                             }
162                             break;
163                         default:
164                             unset($t[$type_name]);
165                     }
166                 }
167             }
168         }
169     }
170 
171     /**
172      * 隐藏异常中的真实文件路径
173      *
174      * @param $path
175      * @return mixed
176      */
177     protected function hiddenFileRealPath($path)
178     {
179         return str_replace(array(PROJECT_REAL_PATH, CP_PATH, str_replace('/', DIRECTORY_SEPARATOR, $_SERVER['DOCUMENT_ROOT'])),
180             array('Project->', 'Cross->', 'Index->'), $path);
181     }
182 
183     /**
184      * 高亮代码
185      *
186      * @param string $code
187      * @return mixed
188      */
189     private static function highlightCode($code)
190     {
191         $code = rtrim($code);
192         if (0 === strcasecmp(substr($code, 0, 5), '<?php ')) {
193             return highlight_string($code, true);
194         }
195 
196         $highlight_code_fragment = highlight_string("<?php {$code}", true);
197         return str_replace('&lt;?php', '', $highlight_code_fragment);
198     }
199 
200     /**
201      * 整理trace数据
202      *
203      * @param array $trace
204      */
205     private function alignmentTraceData(array &$trace = array())
206     {
207         foreach ($trace as &$t) {
208             if (isset($t['file'])) {
209                 $t['show_file'] = $this->hiddenFileRealPath($t['file']);
210                 $t['start_line'] = max(1, $t['line'] - 6);
211                 $t['end_line'] = $t['line'] + 6;
212             } elseif (isset($t['function']) && isset($t['class'])) {
213                 try {
214                     $rc = new ReflectionClass($t['class']);
215                     $t['file'] = $rc->getFileName();
216                     $t['show_file'] = $this->hiddenFileRealPath($rc->getFileName());
217 
218                     $rf = new ReflectionMethod($t['class'], $t['function']);
219                     $t['start_line'] = $rf->getStartLine();
220                     $t['end_line'] = $rf->getEndLine();
221                     $t['line'] = sprintf("%s ~ %s", $t['start_line'], $t['end_line']);
222                 } catch (Exception $e) {
223                     continue;
224                 }
225             } else {
226                 continue;
227             }
228         }
229     }
230 
231     /**
232      * 异常处理抽象方法
233      *
234      * @param Exception $e
235      * @return mixed
236      */
237     abstract protected function errorHandler(Exception $e);
238 }
239 
CrossPHP API documentation generated by ApiGen