PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/ThinkPHP/Lib/Core/Think.class.php

https://github.com/ycj/thinkphp
PHP | 310 lines | 206 code | 22 blank | 82 comment | 40 complexity | 2ee9ac5b73ef55b452d42742e4a00553 MD5 | raw file
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. /**
  12. * ThinkPHP Portal类
  13. * @category Think
  14. * @package Think
  15. * @subpackage Core
  16. * @author liu21st <liu21st@gmail.com>
  17. */
  18. class Think {
  19. private static $_instance = array();
  20. /**
  21. * 应用程序初始化
  22. * @access public
  23. * @return void
  24. */
  25. static public function start() {
  26. // 设定错误和异常处理
  27. register_shutdown_function(array('Think','fatalError'));
  28. set_error_handler(array('Think','appError'));
  29. set_exception_handler(array('Think','appException'));
  30. // 注册AUTOLOAD方法
  31. spl_autoload_register(array('Think', 'autoload'));
  32. //[RUNTIME]
  33. Think::buildApp(); // 预编译项目
  34. //[/RUNTIME]
  35. // 运行应用
  36. App::run();
  37. return ;
  38. }
  39. //[RUNTIME]
  40. /**
  41. * 读取配置信息 编译项目
  42. * @access private
  43. * @return string
  44. */
  45. static private function buildApp() {
  46. // 读取运行模式
  47. if(defined('MODE_NAME')) { // 读取模式的设置
  48. $mode = include MODE_PATH.strtolower(MODE_NAME).'.php';
  49. }else{
  50. $mode = array();
  51. }
  52. // 加载核心惯例配置文件
  53. C(include THINK_PATH.'Conf/convention.php');
  54. if(isset($mode['config'])) {// 加载模式配置文件
  55. C( is_array($mode['config'])?$mode['config']:include $mode['config'] );
  56. }
  57. // 加载项目配置文件
  58. if(is_file(CONF_PATH.'config.php'))
  59. C(include CONF_PATH.'config.php');
  60. // 加载框架底层语言包
  61. L(include THINK_PATH.'Lang/'.strtolower(C('DEFAULT_LANG')).'.php');
  62. // 加载模式系统行为定义
  63. if(C('APP_TAGS_ON')) {
  64. if(isset($mode['extends'])) {
  65. C('extends',is_array($mode['extends'])?$mode['extends']:include $mode['extends']);
  66. }else{ // 默认加载系统行为扩展定义
  67. C('extends', include THINK_PATH.'Conf/tags.php');
  68. }
  69. }
  70. // 加载应用行为定义
  71. if(isset($mode['tags'])) {
  72. C('tags', is_array($mode['tags'])?$mode['tags']:include $mode['tags']);
  73. }elseif(is_file(CONF_PATH.'tags.php')){
  74. // 默认加载项目配置目录的tags文件定义
  75. C('tags', include CONF_PATH.'tags.php');
  76. }
  77. $compile = '';
  78. // 读取核心编译文件列表
  79. if(isset($mode['core'])) {
  80. $list = $mode['core'];
  81. }else{
  82. $list = array(
  83. THINK_PATH.'Common/functions.php', // 标准模式函数库
  84. CORE_PATH.'Core/Log.class.php', // 日志处理类
  85. CORE_PATH.'Core/Dispatcher.class.php', // URL调度类
  86. CORE_PATH.'Core/App.class.php', // 应用程序类
  87. CORE_PATH.'Core/Action.class.php', // 控制器类
  88. CORE_PATH.'Core/View.class.php', // 视图类
  89. );
  90. }
  91. // 项目追加核心编译列表文件
  92. if(is_file(CONF_PATH.'core.php')) {
  93. $list = array_merge($list,include CONF_PATH.'core.php');
  94. }
  95. foreach ($list as $file){
  96. if(is_file($file)) {
  97. require_cache($file);
  98. if(!APP_DEBUG) $compile .= compile($file);
  99. }
  100. }
  101. // 加载项目公共文件
  102. if(is_file(COMMON_PATH.'common.php')) {
  103. include COMMON_PATH.'common.php';
  104. // 编译文件
  105. if(!APP_DEBUG) $compile .= compile(COMMON_PATH.'common.php');
  106. }
  107. // 加载模式别名定义
  108. if(isset($mode['alias'])) {
  109. $alias = is_array($mode['alias'])?$mode['alias']:include $mode['alias'];
  110. alias_import($alias);
  111. if(!APP_DEBUG) $compile .= 'alias_import('.var_export($alias,true).');';
  112. }
  113. // 加载项目别名定义
  114. if(is_file(CONF_PATH.'alias.php')){
  115. $alias = include CONF_PATH.'alias.php';
  116. alias_import($alias);
  117. if(!APP_DEBUG) $compile .= 'alias_import('.var_export($alias,true).');';
  118. }
  119. if(APP_DEBUG) {
  120. // 调试模式加载系统默认的配置文件
  121. C(include THINK_PATH.'Conf/debug.php');
  122. // 读取调试模式的应用状态
  123. $status = C('APP_STATUS');
  124. // 加载对应的项目配置文件
  125. if(is_file(CONF_PATH.$status.'.php'))
  126. // 允许项目增加开发模式配置定义
  127. C(include CONF_PATH.$status.'.php');
  128. }else{
  129. // 部署模式下面生成编译文件
  130. build_runtime_cache($compile);
  131. }
  132. return ;
  133. }
  134. //[/RUNTIME]
  135. /**
  136. * 系统自动加载ThinkPHP类库
  137. * 并且支持配置自动加载路径
  138. * @param string $class 对象类名
  139. * @return void
  140. */
  141. public static function autoload($class) {
  142. // 检查是否存在别名定义
  143. if(alias_import($class)) return ;
  144. $libPath = defined('BASE_LIB_PATH')?BASE_LIB_PATH:LIB_PATH;
  145. $group = defined('GROUP_NAME') && C('APP_GROUP_MODE')==0 ?GROUP_NAME.'/':'';
  146. $file = $class.'.class.php';
  147. if(substr($class,-8)=='Behavior') { // 加载行为
  148. if(require_array(array(
  149. CORE_PATH.'Behavior/'.$file,
  150. EXTEND_PATH.'Behavior/'.$file,
  151. LIB_PATH.'Behavior/'.$file,
  152. $libPath.'Behavior/'.$file),true)
  153. || (defined('MODE_NAME') && require_cache(MODE_PATH.ucwords(MODE_NAME).'/Behavior/'.$file))) {
  154. return ;
  155. }
  156. }elseif(substr($class,-5)=='Model'){ // 加载模型
  157. if(require_array(array(
  158. LIB_PATH.'Model/'.$group.$file,
  159. $libPath.'Model/'.$file,
  160. EXTEND_PATH.'Model/'.$file),true)) {
  161. return ;
  162. }
  163. }elseif(substr($class,-6)=='Action'){ // 加载控制器
  164. if(require_array(array(
  165. LIB_PATH.'Action/'.$group.$file,
  166. $libPath.'Action/'.$file,
  167. EXTEND_PATH.'Action/'.$file),true)) {
  168. return ;
  169. }
  170. }elseif(substr($class,0,5)=='Cache'){ // 加载缓存驱动
  171. if(require_array(array(
  172. EXTEND_PATH.'Driver/Cache/'.$file,
  173. CORE_PATH.'Driver/Cache/'.$file),true)){
  174. return ;
  175. }
  176. }elseif(substr($class,0,2)=='Db'){ // 加载数据库驱动
  177. if(require_array(array(
  178. EXTEND_PATH.'Driver/Db/'.$file,
  179. CORE_PATH.'Driver/Db/'.$file),true)){
  180. return ;
  181. }
  182. }elseif(substr($class,0,8)=='Template'){ // 加载模板引擎驱动
  183. if(require_array(array(
  184. EXTEND_PATH.'Driver/Template/'.$file,
  185. CORE_PATH.'Driver/Template/'.$file),true)){
  186. return ;
  187. }
  188. }elseif(substr($class,0,6)=='TagLib'){ // 加载标签库驱动
  189. if(require_array(array(
  190. EXTEND_PATH.'Driver/TagLib/'.$file,
  191. CORE_PATH.'Driver/TagLib/'.$file),true)) {
  192. return ;
  193. }
  194. }
  195. // 根据自动加载路径设置进行尝试搜索
  196. $paths = explode(',',C('APP_AUTOLOAD_PATH'));
  197. foreach ($paths as $path){
  198. if(import($path.'.'.$class))
  199. // 如果加载类成功则返回
  200. return ;
  201. }
  202. }
  203. /**
  204. * 取得对象实例 支持调用类的静态方法
  205. * @param string $class 对象类名
  206. * @param string $method 类的静态方法名
  207. * @return object
  208. */
  209. static public function instance($class,$method='') {
  210. $identify = $class.$method;
  211. if(!isset(self::$_instance[$identify])) {
  212. if(class_exists($class)){
  213. $o = new $class();
  214. if(!empty($method) && method_exists($o,$method))
  215. self::$_instance[$identify] = call_user_func_array(array(&$o, $method));
  216. else
  217. self::$_instance[$identify] = $o;
  218. }
  219. else
  220. halt(L('_CLASS_NOT_EXIST_').':'.$class);
  221. }
  222. return self::$_instance[$identify];
  223. }
  224. /**
  225. * 自定义异常处理
  226. * @access public
  227. * @param mixed $e 异常对象
  228. */
  229. static public function appException($e) {
  230. $error = array();
  231. $trace = $e->getTrace();
  232. $error['message'] = $e->getMessage();
  233. $error['file'] = $e->getFile();
  234. $error['class'] = isset($trace[0]['class'])?$trace[0]['class']:'';
  235. $error['function'] = isset($trace[0]['function'])?$trace[0]['function']:'';
  236. $error['line'] = $e->getLine();
  237. $error['trace'] = '';
  238. $time = date('y-m-d H:i:m');
  239. foreach ($trace as $t) {
  240. $error['trace'] .= '[' . $time . '] ' . $t['file'] . ' (' . $t['line'] . ') ';
  241. $error['trace'] .= $t['class'] . $t['type'] . $t['function'] . '(';
  242. $error['trace'] .= implode(', ', $t['args']);
  243. $error['trace'] .=')<br/>';
  244. }
  245. halt($error);
  246. }
  247. /**
  248. * 自定义错误处理
  249. * @access public
  250. * @param int $errno 错误类型
  251. * @param string $errstr 错误信息
  252. * @param string $errfile 错误文件
  253. * @param int $errline 错误行数
  254. * @return void
  255. */
  256. static public function appError($errno, $errstr, $errfile, $errline) {
  257. switch ($errno) {
  258. case E_ERROR:
  259. case E_PARSE:
  260. case E_CORE_ERROR:
  261. case E_COMPILE_ERROR:
  262. case E_USER_ERROR:
  263. ob_end_clean();
  264. // 页面压缩输出支持
  265. if(C('OUTPUT_ENCODE')){
  266. $zlib = ini_get('zlib.output_compression');
  267. if(empty($zlib)) ob_start('ob_gzhandler');
  268. }
  269. $errorStr = "$errstr ".$errfile." 第 $errline 行.";
  270. if(C('LOG_RECORD')) Log::write("[$errno] ".$errorStr,Log::ERR);
  271. function_exists('halt')?halt($errorStr):exit('ERROR:'.$errorStr);
  272. break;
  273. case E_STRICT:
  274. case E_USER_WARNING:
  275. case E_USER_NOTICE:
  276. default:
  277. $errorStr = "[$errno] $errstr ".$errfile." 第 $errline 行.";
  278. trace($errorStr,'','NOTIC');
  279. break;
  280. }
  281. }
  282. // 致命错误捕获
  283. static public function fatalError() {
  284. if ($e = error_get_last()) {
  285. Think::appError($e['type'],$e['message'],$e['file'],$e['line']);
  286. }
  287. }
  288. }