PageRenderTime 68ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/core/App.php

https://bitbucket.org/likeping/lkp
PHP | 339 lines | 244 code | 28 blank | 67 comment | 68 complexity | 67de4e883829de66e391c220d19e6467 MD5 | raw file
  1. <?php
  2. /**
  3. * App.php
  4. * 核心类,并初始化系统的基本设置
  5. */
  6. if (!defined('IN_FINECMS')) exit();
  7. error_reporting(E_ALL^E_NOTICE);
  8. /**
  9. * 配置
  10. */
  11. define('SYS_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR); //核心文件所在路径
  12. define('SYS_START_TIME', microtime(true)); //设置程序开始执行时间
  13. define('CONTROLLER_DIR', APP_ROOT . 'controllers' . DIRECTORY_SEPARATOR); //controller目录的路径
  14. define('MODEL_DIR', APP_ROOT . 'models' . DIRECTORY_SEPARATOR); //model目录的路径
  15. define('VIEW_DIR', APP_ROOT . 'views' . DIRECTORY_SEPARATOR); //view目录的路径
  16. define('CONFIG_DIR', APP_ROOT . 'config' . DIRECTORY_SEPARATOR); //config目录的路径
  17. define('EXTENSION_PATH', 'extensions'); //extension目录文件夹
  18. define('EXTENSION_DIR', APP_ROOT . EXTENSION_PATH . DIRECTORY_SEPARATOR); //extension目录的路径
  19. define('PLUGIN_DIR', APP_ROOT . 'plugins' . DIRECTORY_SEPARATOR); //插件目录文件夹
  20. define('SYS_THEME_DIR', $config['SITE_THEME'] . DIRECTORY_SEPARATOR); //模板风格
  21. define('DEFAULT_CONTROLLER', 'Index'); //设置系统默认的controller名称,默认为:Index
  22. define('DEFAULT_ACTION', 'index'); //设置系统默认的action名称,默认为index
  23. define('SYS_LOG', $config['SYS_LOG']); //设置是否开启运行日志
  24. define('SYS_DEBUG', $config['SYS_DEBUG']); //设置是否开启调试模式.开启后,程序运行出现错误时,显示错误信息
  25. define('SYS_DOMAIN', $config['SYS_DOMAIN']); //域名目录,针对虚拟主机用户
  26. define('URL_SEGEMENTATION', '/'); //定义网址路由的分割符
  27. define('ENTRY_SCRIPT_NAME', 'index.php'); //定义入口文件名
  28. define('SITE_MEMBER_COOKIE', $config['SITE_MEMBER_COOKIE']); //会员登录Cookie随机字符码
  29. define('SYS_ATTACK_LOG', isset($config['SYS_ATTACK_LOG']) && $config['SYS_ATTACK_LOG'] ? $config['SYS_ATTACK_LOG'] : false); //系统攻击日志开关
  30. define('SYS_LANGUAGE', isset($config['SYS_LANGUAGE']) && $config['SYS_LANGUAGE'] ? $config['SYS_LANGUAGE'] : 'zh-cn'); //网站语言设置
  31. define('ADMIN_NAMESPACE', isset($config['ADMIN_NAMESPACE']) && $config['ADMIN_NAMESPACE'] ? $config['ADMIN_NAMESPACE'] : 'admin'); //定义后台管理路径的名字
  32. define('SYS_VAR_PREX', isset($config['SYS_VAR_PREX']) && $config['SYS_VAR_PREX'] ? $config['SYS_VAR_PREX'] : 'finecms_'); //SESSION和COOKIE变量前缀
  33. define('TIME_FORMAT', isset($config['SITE_TIME_FORMAT']) && $config['SITE_TIME_FORMAT'] ? $config['SITE_TIME_FORMAT'] : 'Y-m-d H:i:s'); //输出时间格式化
  34. define('SYS_TIME_ZONE', 'Etc/GMT' . ($config['SITE_TIMEZONE'] > 0 ? '-' : '+') . (abs($config['SITE_TIMEZONE']))); //时区
  35. define('LANGUAGE_DIR', EXTENSION_DIR . 'language' . DIRECTORY_SEPARATOR . SYS_LANGUAGE . DIRECTORY_SEPARATOR); //网站语言文件
  36. /**
  37. * 环境参数
  38. */
  39. if (!file_exists(LANGUAGE_DIR)) exit('语言目录不存在:' . LANGUAGE_DIR);
  40. if (function_exists('ini_set')) SYS_DEBUG ? ini_set('display_errors', true) : ini_set('display_errors', false);
  41. if (function_exists('ini_set')) ini_set('memory_limit', '1024M');
  42. date_default_timezone_set(SYS_TIME_ZONE);
  43. if (isset($config['SYS_GZIP']) && $config['SYS_GZIP'] && function_exists('ob_gzhandler')) ob_start('ob_gzhandler');
  44. $language = require LANGUAGE_DIR . 'lang.php';
  45. /**
  46. * 系统核心全局控制类
  47. */
  48. abstract class App {
  49. public static $namespace;
  50. public static $controller;
  51. public static $action;
  52. public static $plugin;
  53. public static $_objects = array();
  54. public static $_inc_files = array();
  55. public static $config = array();
  56. /**
  57. * 分析URL信息
  58. */
  59. private static function parse_request() {
  60. if (SYS_DOMAIN) {
  61. $_SERVER['SCRIPT_NAME'] = str_replace('/' . SYS_DOMAIN, '', $_SERVER['SCRIPT_NAME']);
  62. $_SERVER['REQUEST_URI'] = str_replace('/' . SYS_DOMAIN, '', $_SERVER['REQUEST_URI']);
  63. }
  64. $path_url_string = isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING'] ? $_SERVER['QUERY_STRING'] : $_SERVER['REQUEST_URI'];
  65. $new_url_string = '';
  66. if (!isset($_SERVER['QUERY_STRING']) || empty($_SERVER['QUERY_STRING'])) {
  67. $router_config_file = CONFIG_DIR . 'router.ini.php';
  68. if (is_file($router_config_file)) {
  69. $router_array = require_once $router_config_file;
  70. if (is_array($router_array) && !empty($router_array)) {
  71. $path_url_router = str_replace(str_replace('/' . ENTRY_SCRIPT_NAME, '', $_SERVER['SCRIPT_NAME']), '', $_SERVER['REQUEST_URI']);
  72. $path_url_router = str_replace('/' . ENTRY_SCRIPT_NAME, '', $path_url_router);
  73. if (substr($path_url_router, 0, 1) == '/') $path_url_router = substr($path_url_router, 1);
  74. if ($path_url_router) {
  75. foreach ($router_array as $router_key=>$router_value) {
  76. if (preg_match('#' . $router_key . '#', $path_url_router)) {
  77. $new_url_string = preg_replace('#' . $router_key . '#', $router_value, $path_url_router);
  78. break;
  79. }
  80. }
  81. if (empty($new_url_string)) self::display_404_error(0);
  82. }
  83. }
  84. }
  85. }
  86. $path_url_string = $new_url_string ? $new_url_string : $path_url_string;
  87. parse_str($path_url_string, $url_info_array);
  88. $namespace_name = trim((isset($url_info_array['s']) && $url_info_array['s']) ? $url_info_array['s'] : '');
  89. $controller_name = trim((isset($url_info_array['c']) && $url_info_array['c']) ? $url_info_array['c'] : DEFAULT_CONTROLLER);
  90. $action_name = trim((isset($url_info_array['a']) && $url_info_array['a']) ? $url_info_array['a'] : DEFAULT_ACTION);
  91. if ($namespace_name == 'admin' && ADMIN_NAMESPACE != 'admin') self::display_404_error(5);
  92. $namespace_name = $namespace_name == ADMIN_NAMESPACE ? 'admin' : $namespace_name;
  93. self::$namespace = strtolower($namespace_name);
  94. self::$controller = ucfirst(strtolower($controller_name));
  95. self::$action = strtolower($action_name);
  96. $_GET = array_merge($_GET, $url_info_array);
  97. return true;
  98. }
  99. /**
  100. * 项目运行函数
  101. */
  102. public static function run($config) {
  103. static $_app = array();
  104. self::$config = $config;
  105. self::parse_request();
  106. $app_id = self::$controller . '_' . self::$action;
  107. if (!isset($_app[$app_id]) || $_app[$app_id] == null) {
  108. $namespace = self::$namespace;
  109. $controller = self::$controller . 'Controller';
  110. $action = self::$action . 'Action';
  111. self::load_file(SYS_ROOT . 'Base.php');
  112. self::load_file(SYS_ROOT . 'Controller.php');
  113. self::load_file(CONTROLLER_DIR . 'Common.php');
  114. if ($namespace && is_dir(CONTROLLER_DIR . $namespace)) {
  115. $controller_file = CONTROLLER_DIR . $namespace . DIRECTORY_SEPARATOR . $controller . '.php';
  116. if (!is_file($controller_file)) self::display_404_error(1);
  117. if (is_file(CONTROLLER_DIR . $namespace . DIRECTORY_SEPARATOR . 'Common.php')) self::load_file(CONTROLLER_DIR . $namespace . DIRECTORY_SEPARATOR . 'Common.php');
  118. self::load_file($controller_file);
  119. } elseif ($namespace && is_dir(PLUGIN_DIR . $namespace)) {
  120. $common_file = PLUGIN_DIR . $namespace . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . 'Common.php';
  121. $controller_file = PLUGIN_DIR . $namespace . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . $controller . '.php';
  122. if (is_file($common_file) && is_file($controller_file)) {
  123. self::$plugin = strtolower($namespace);
  124. self::load_file($common_file);
  125. self::load_file($controller_file);
  126. } else {
  127. self::display_404_error(2);
  128. }
  129. } elseif (is_file(CONTROLLER_DIR . $controller . '.php')) {
  130. self::load_file(CONTROLLER_DIR . $controller . '.php');
  131. } else {
  132. self::display_404_error(3);
  133. }
  134. $app_object = new $controller();
  135. if (method_exists($controller, $action)) {
  136. $_app[$app_id] = $app_object->$action();
  137. } else {
  138. self::display_404_error(4);
  139. }
  140. }
  141. return $_app[$app_id];
  142. }
  143. /**
  144. * 显示404错误提示
  145. */
  146. private static function display_404_error($id=0) {
  147. header('HTTP/1.1 404 Not Found');
  148. require SYS_ROOT . 'html/error404.php';
  149. exit();
  150. }
  151. /**
  152. * 显示错误提示
  153. */
  154. public static function display_error($message, $back=0) {
  155. if (!$message) return false;
  156. require SYS_ROOT . 'html/message.php';
  157. exit();
  158. }
  159. /**
  160. * 核心类引导数组
  161. */
  162. public static $core_class_array = array(
  163. 'Model' => 'Model.php',
  164. 'Log' => 'Log.php',
  165. 'View' => 'View.php',
  166. 'mysql' => 'lib/mysql.class.php',
  167. 'html' => 'lib/html.class.php',
  168. 'cache_file' => 'lib/cache_file.class.php',
  169. 'pagelist' => 'lib/pagelist.class.php',
  170. 'cookie' => 'lib/cookie.class.php',
  171. 'session' => 'lib/session.class.php',
  172. 'file_list' => 'lib/file_list.class.php',
  173. 'image_lib' => 'lib/image_lib.class.php',
  174. 'check' => 'lib/check.class.php',
  175. 'file_upload' => 'lib/file_upload.class.php',
  176. 'client' => 'lib/client.class.php',
  177. 'pinyin' => 'lib/pinyin.class.php',
  178. 'tree' => 'lib/tree.class.php',
  179. 'loader' => 'lib/loader.class.php',
  180. 'auth' => 'lib/auth.class.php',
  181. 'mail' => 'lib/mail.class.php',
  182. 'captcha' => 'lib/captcha.class.php',
  183. 'pclzip' => 'lib/pclzip.class.php',
  184. 'linkage_tree' => 'lib/linkage_tree.class.php',
  185. );
  186. /**
  187. * 项目文件的自动加载
  188. */
  189. public static function auto_load($class_name) {
  190. if (isset(self::$core_class_array[$class_name])) {
  191. self::load_file(SYS_ROOT . self::$core_class_array[$class_name]);
  192. } else if (substr($class_name, -5) == 'Model') {
  193. if (is_file(MODEL_DIR . $class_name . '.php')) {
  194. self::load_file(MODEL_DIR . $class_name . '.php');
  195. } elseif ((is_file(PLUGIN_DIR . self::$namespace. DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . $class_name . '.php'))) {
  196. self::load_file(PLUGIN_DIR . self::$namespace. DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . $class_name . '.php');
  197. } else {
  198. Controller::halt('The Model file: ' . $class_name . ' is not exists!');
  199. }
  200. } else {
  201. if (is_file(EXTENSION_DIR . $class_name . '.php')) {
  202. self::load_file(EXTENSION_DIR . $class_name . '.php');
  203. } else {
  204. Controller::halt('The File:' . $class_name . '.php is not exists!');
  205. }
  206. }
  207. }
  208. /**
  209. * 获取当前运行的namespace名称
  210. */
  211. public static function get_namespace_id() {
  212. return strtolower(self::$namespace);
  213. }
  214. /**
  215. * 获取当前运行的controller名称
  216. */
  217. public static function get_controller_id() {
  218. return strtolower(self::$controller);
  219. }
  220. /**
  221. * 获取当前运行的action名称
  222. */
  223. public static function get_action_id() {
  224. return self::$action;
  225. }
  226. /**
  227. * 获取配置信息
  228. */
  229. public static function get_config() {
  230. $data = self::$config;
  231. $data['PLUGIN_DIR'] = basename(PLUGIN_DIR);
  232. return $data;
  233. }
  234. /**
  235. * 获取当前运行的plugin名称
  236. */
  237. public static function get_plugin_id() {
  238. return self::$plugin;
  239. }
  240. /**
  241. * 单例模式
  242. */
  243. public static function singleton($class_name) {
  244. if (!$class_name) return false;
  245. $key = strtolower($class_name);
  246. if (isset(self::$_objects[$key])) return self::$_objects[$key];
  247. return self::$_objects[$key] = new $class_name();
  248. }
  249. /**
  250. * 返回插件模型的唯一实例(单例模式)
  251. */
  252. public static function plugin_model($plugin, $table_name) {
  253. if (!$table_name || !$plugin) return false;
  254. $model_name = ucfirst(strtolower($table_name)) . 'Model';
  255. $model_file = PLUGIN_DIR . $plugin . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . $model_name . '.php';
  256. if (!is_file($model_file)) Controller::halt('The pluginModel(#' . $plugin . ') file:' . $model_name . '.php is not exists!');
  257. $key = strtolower($model_name);
  258. if (isset(self::$_objects[$key])) return self::$_objects[$key];
  259. require $model_file;
  260. return self::$_objects[$key] = new $model_name();
  261. }
  262. /**
  263. * 静态加载文件
  264. */
  265. public static function load_file($file_name) {
  266. if (!$file_name) return false;
  267. if (!isset(self::$_inc_files[$file_name]) || self::$_inc_files[$file_name] == false) {
  268. if (!is_file($file_name)) Controller::halt('The file:' . $file_name . ' not found!');
  269. include_once $file_name;
  270. self::$_inc_files[$file_name] = true;
  271. }
  272. return self::$_inc_files[$file_name];
  273. }
  274. }
  275. /**
  276. * URL函数
  277. */
  278. function url($route, $params = null) {
  279. return Controller::create_url($route, $params);
  280. }
  281. /**
  282. * 插件中的URL函数
  283. */
  284. function purl($route, $params = null) {
  285. $route = App::get_namespace_id() . '/' . $route;
  286. return url($route, $params);
  287. }
  288. /**
  289. * 语言调用函数
  290. */
  291. function lang($name, $data=null) {
  292. global $language;
  293. $string = isset($language[$name]) ? $language[$name] : '未知(#' . $name . ')';
  294. if ($data) {
  295. foreach ($data as $r=>$t) {
  296. $string = str_replace('{' . $r . '}', $t, $string);
  297. }
  298. }
  299. return $string;
  300. }
  301. /**
  302. * 程序执行时间
  303. */
  304. function runtime() {
  305. $temptime = explode(' ', SYS_START_TIME);
  306. $time = $temptime[1] + $temptime[0];
  307. $temptime = explode(' ', microtime());
  308. $now = $temptime[1] + $temptime[0];
  309. return number_format($now - $time, 6);
  310. }
  311. spl_autoload_register(array('App', 'auto_load'));