App.class.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2014 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. namespace Think;
  12. /**
  13. * ThinkPHP 应用程序类 执行应用过程管理
  14. */
  15. class App
  16. {
  17. /**
  18. * 应用程序初始化
  19. * @access public
  20. * @return void
  21. */
  22. public static function init()
  23. {
  24. // 日志目录转换为绝对路径 默认情况下存储到公共模块下面
  25. C('LOG_PATH', realpath(LOG_PATH) . '/Common/');
  26. // 定义当前请求的系统常量
  27. define('NOW_TIME', $_SERVER['REQUEST_TIME']);
  28. define('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']);
  29. define('IS_GET', REQUEST_METHOD == 'GET' ? true : false);
  30. define('IS_POST', REQUEST_METHOD == 'POST' ? true : false);
  31. define('IS_PUT', REQUEST_METHOD == 'PUT' ? true : false);
  32. define('IS_DELETE', REQUEST_METHOD == 'DELETE' ? true : false);
  33. // URL调度
  34. Dispatcher::dispatch();
  35. if (C('REQUEST_VARS_FILTER')) {
  36. // 全局安全过滤
  37. array_walk_recursive($_GET, 'think_filter');
  38. array_walk_recursive($_POST, 'think_filter');
  39. array_walk_recursive($_REQUEST, 'think_filter');
  40. }
  41. define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false);
  42. // TMPL_EXCEPTION_FILE 改为绝对地址
  43. C('TMPL_EXCEPTION_FILE', realpath(C('TMPL_EXCEPTION_FILE')));
  44. return;
  45. }
  46. /**
  47. * 执行应用程序
  48. * @access public
  49. * @return void
  50. */
  51. public static function exec()
  52. {
  53. if (!preg_match('/^[A-Za-z](\/|\w)*$/', CONTROLLER_NAME)) {
  54. // 安全检测
  55. $module = false;
  56. } else {
  57. //创建控制器实例
  58. $module = controller(CONTROLLER_NAME);
  59. }
  60. if (!$module) {
  61. // 是否定义Empty控制器
  62. $module = A('Empty');
  63. if (!$module) {
  64. E(L('_CONTROLLER_NOT_EXIST_') . ':' . CONTROLLER_NAME);
  65. }
  66. }
  67. // 获取当前操作名 支持动态路由
  68. $action = ACTION_NAME . C('ACTION_SUFFIX');
  69. try {
  70. if (!preg_match('/^[A-Za-z](\w)*$/', $action)) {
  71. // 非法操作
  72. throw new \ReflectionException();
  73. }
  74. //执行当前操作
  75. $method = new \ReflectionMethod($module, $action);
  76. if ($method->isPublic() && !$method->isStatic()) {
  77. $class = new \ReflectionClass($module);
  78. // URL参数绑定检测
  79. if ($method->getNumberOfParameters() > 0 && C('URL_PARAMS_BIND')) {
  80. switch ($_SERVER['REQUEST_METHOD']) {
  81. case 'POST':
  82. $vars = array_merge($_GET, $_POST);
  83. break;
  84. case 'PUT':
  85. parse_str(file_get_contents('php://input'), $vars);
  86. break;
  87. default:
  88. $vars = $_GET;
  89. }
  90. $params = $method->getParameters();
  91. $paramsBindType = C('URL_PARAMS_BIND_TYPE');
  92. foreach ($params as $param) {
  93. $name = $param->getName();
  94. if (1 == $paramsBindType && !empty($vars)) {
  95. $args[] = array_shift($vars);
  96. } elseif (0 == $paramsBindType && isset($vars[$name])) {
  97. $args[] = $vars[$name];
  98. } elseif ($param->isDefaultValueAvailable()) {
  99. $args[] = $param->getDefaultValue();
  100. } else {
  101. E(L('_PARAM_ERROR_') . ':' . $name);
  102. }
  103. }
  104. // 开启绑定参数过滤机制
  105. if (C('URL_PARAMS_SAFE')) {
  106. $filters = C('URL_PARAMS_FILTER') ?: C('DEFAULT_FILTER');
  107. if ($filters) {
  108. $filters = explode(',', $filters);
  109. foreach ($filters as $filter) {
  110. $args = array_map_recursive($filter, $args); // 参数过滤
  111. }
  112. }
  113. }
  114. array_walk_recursive($args, 'think_filter');
  115. $method->invokeArgs($module, $args);
  116. } else {
  117. $method->invoke($module);
  118. }
  119. } else {
  120. // 操作方法不是Public 抛出异常
  121. throw new \ReflectionException();
  122. }
  123. } catch (\ReflectionException $e) {
  124. // 方法调用发生异常后 引导到__call方法处理
  125. $method = new \ReflectionMethod($module, '__call');
  126. $method->invokeArgs($module, array($action, ''));
  127. }
  128. return;
  129. }
  130. /**
  131. * 运行应用实例 入口文件使用的快捷方法
  132. * @access public
  133. * @return void
  134. */
  135. public static function run()
  136. {
  137. App::init();
  138. // Session初始化
  139. if (!IS_CLI) {
  140. session(C('SESSION_OPTIONS'));
  141. }
  142. // 记录应用初始化时间
  143. G('initTime');
  144. App::exec();
  145. return;
  146. }
  147. }