Request.Class.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <?php
  2. namespace Mall\Framework\Core;
  3. class Request
  4. {
  5. /**
  6. *
  7. * 存放当前请求的参数
  8. * @var array
  9. */
  10. protected $params;
  11. static protected $instance;
  12. private function __construct()
  13. {
  14. }
  15. static public function getInstance()
  16. {
  17. if (is_null(self::$instance)) {
  18. self::$instance = new self();
  19. }
  20. return self::$instance;
  21. }
  22. /**
  23. * 获取请求的参数集。
  24. * 支持http访问的参数 以及 命令行下访问的参数
  25. * demo1:php test.php -p3 -t=abc --opt=valopt --opt2 valopt2
  26. * demo2 http://test.kimiss.com/index.php?c=xxx&a=ddd
  27. *
  28. * @param boolean $returnRawJson 是否将json参数作为独立key(rawjson)返回
  29. * @throws
  30. * @return array
  31. */
  32. public static function params($returnRawJson = false)
  33. {
  34. if (self::isCLI()) {
  35. return self::cliParams();
  36. } else if( strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== FALSE || strpos($_SERVER['CONTENT_TYPE'], 'text/plain') !== FALSE || strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== FALSE){
  37. $request_body = file_get_contents("php://input");
  38. if(!empty($request_body)){
  39. $request_body = json_decode($request_body, true);
  40. if(!$request_body){
  41. throw new \Exception("参数格式异常");
  42. }
  43. if($returnRawJson){
  44. return array_merge($_REQUEST, ['rawjson'=> $request_body]);
  45. }
  46. return array_merge($_REQUEST, $request_body);
  47. }
  48. return $_REQUEST;
  49. } else{
  50. return $_REQUEST;
  51. }
  52. }
  53. /**
  54. *
  55. * 获取命令行下传递进来的参数
  56. * 只支持以 - 或 -- 开头的参数
  57. * demo:php test.php -p3 -t=abc --opt=valopt --opt2 valopt2
  58. * @return array
  59. */
  60. private static function cliParams()
  61. {
  62. $result = array();
  63. $params = $GLOBALS['argv'];
  64. array_shift($params);
  65. do {
  66. $tmpEachResult = array_shift($params);
  67. if (!$tmpEachResult) {
  68. break;
  69. }
  70. $p = $tmpEachResult;
  71. if ($p[0] == '-') {
  72. $pname = substr($p, 1);
  73. $value = false;
  74. if ($pname[0] == '-') {// 长选项 (--<param>)
  75. $pname = substr($pname, 1);
  76. if (strpos($p, '=') !== false) {
  77. // value specified inline (--<param>=<value>)
  78. list($pname, $value) = explode('=', substr($p, 2), 2);
  79. }
  80. } else {// 短选项
  81. if (strpos($p, '=') !== false) {
  82. // value specified inline (-<param>=<value>)
  83. list($pname, $value) = explode('=', substr($p, 1), 2);
  84. } else if (strlen($p) > 1) {
  85. $pname = substr($p, 1, 1);
  86. $value = substr($p, 2);
  87. }
  88. }
  89. # 如果上面没有取到值,并且下一个不是以-开头的,则下一个值为当前参数的值
  90. $nextparm = current($params);
  91. if ($value === false
  92. && $nextparm !== false
  93. && $nextparm[0] != '-'
  94. ) {
  95. $value = array_shift($params);
  96. }
  97. $result[$pname] = (string)$value;// 将 false转为空串,以便与http访问时对参数的处理一致
  98. } else {
  99. # 不是以-指定开始的参数,一律丢弃
  100. //$result[] = $p;
  101. }
  102. } while (true);
  103. return $result;
  104. }
  105. /**
  106. * 分发请求,调用Controller以及对应的action
  107. *
  108. * @param boolean $enableNginxRwite 是否启用nginx rewrite功能支持pathinfo访问方式
  109. * @param boolean $enableModule 是否启用控制器分模块方式
  110. * @throws
  111. * @return object
  112. */
  113. public function dispatch($enableNginxRwite = true, $enableModule = false)
  114. {
  115. // 如果未启用nginx rewrite,通过此处简单路由功能匹配
  116. if( !$enableNginxRwite && !self::isCLI()){
  117. $requestUrl = $_SERVER['REQUEST_URI'];
  118. if(strpos($requestUrl, '?') !== false){
  119. $requestUrl = substr($requestUrl, 0, strpos($requestUrl, '?'));
  120. }
  121. if(!empty($requestUrl)){
  122. $requestUrl = explode('/', $requestUrl);
  123. if(!empty($requestUrl)){
  124. if($enableModule){
  125. $_REQUEST['m'] = $requestUrl[1];
  126. $_REQUEST['c'] = $requestUrl[2];
  127. $_REQUEST['a'] = $requestUrl[3];
  128. if(isset($requestUrl[4])){
  129. $_REQUEST['request_id'] = intval($requestUrl[4]);
  130. }
  131. }else{
  132. $_REQUEST['c'] = $requestUrl[1];
  133. $_REQUEST['a'] = $requestUrl[2];
  134. if(isset($requestUrl[3])){
  135. $_REQUEST['request_id'] = intval($requestUrl[3]);
  136. }
  137. }
  138. }
  139. }
  140. }
  141. self::$instance->params = self::params();
  142. $controllerName = self::getController($enableModule);
  143. if (!class_exists($controllerName)) {
  144. throw new \Exception("controller: {$controllerName} not exists!");
  145. }
  146. $action = self::getAction();
  147. $controller = new $controllerName();
  148. $controller->$action();
  149. //
  150. // if (method_exists($controller, 'display')) {
  151. // $controller->display();
  152. // }
  153. }
  154. public function getModule()
  155. {
  156. $m = self::param('m') ?: DEFAULT_CLASS_MODULE_NAME;
  157. return ucfirst(trim($m, '_'));
  158. }
  159. public function getModuleType()
  160. {
  161. $t = self::param('t') ?: '';
  162. if ($t) {
  163. return ucfirst(trim($t, '_'));
  164. }
  165. }
  166. public function getController($enableModule)
  167. {
  168. $c = self::param('c');
  169. $c = trim($c, '_');
  170. //默认给一个控制器名
  171. if (!$c) {
  172. $c = DEFAULT_CLASS_CONTROLLER_NAME;
  173. }
  174. $arr_class_path = array_map(function ($tmpV) {
  175. return ucfirst($tmpV);
  176. }, explode('_', $c));
  177. $c = join('\\', $arr_class_path);
  178. $NS = Config::getInstance()->get('app_name');
  179. $controller = "{$NS}\\Controller\\";
  180. if ($t = self::getModuleType()) {
  181. $controller .= $t . "\\";
  182. }
  183. if (($m = self::getModule()) && $enableModule) {
  184. $controller .= $m . "\\";
  185. }
  186. $controller .= "{$c}";
  187. return $controller;
  188. }
  189. public function getAction()
  190. {
  191. $action = self::param('a');
  192. //默认给一个方法名
  193. if (!$action) {
  194. $action = DEFAULT_CLASS_ACTION_NAME;
  195. }
  196. return $action;
  197. }
  198. /**
  199. * 获取指定的参数值
  200. * @param $name
  201. * @return array|bool|string
  202. */
  203. public function param($name)
  204. {
  205. if(empty($this->params)){
  206. $this->params = self::params();
  207. }
  208. if (isset($this->params[$name])) {
  209. return self::paramFilter($this->params[$name]);
  210. }
  211. return false;
  212. }
  213. /**
  214. * 获取raw中json格式参数值
  215. */
  216. public function getRawJson()
  217. {
  218. if(empty($this->params['rawjson'])){
  219. $this->params = self::params(true);
  220. }
  221. if (isset($this->params['rawjson'])) {
  222. return self::paramFilter($this->params['rawjson']);
  223. }
  224. return false;
  225. }
  226. /**
  227. * 是否POST请求
  228. *
  229. * @return boolean
  230. */
  231. static public function isPost()
  232. {
  233. return $_SERVER['REQUEST_METHOD'] == 'POST' ? true : false;
  234. }
  235. /**
  236. * 是否GET请求
  237. *
  238. * @return boolean
  239. */
  240. static public function isGet()
  241. {
  242. return $_SERVER['REQUEST_METHOD'] == 'GET' ? true : false;
  243. }
  244. /**
  245. * 是否处于命令行下
  246. *
  247. * @return Boolean
  248. */
  249. static public function isCLI()
  250. {
  251. if (php_sapi_name() == "cli" || empty($_SERVER['PHP_SELF'])) {
  252. return true;
  253. } else {
  254. return false;
  255. }
  256. }
  257. /**
  258. * 获取客户端真实Ip
  259. * @return string
  260. */
  261. static public function get_onlineip()
  262. {
  263. $onlineip = '';
  264. if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
  265. $onlineip = getenv('HTTP_CLIENT_IP');
  266. } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
  267. $onlineip = getenv('HTTP_X_FORWARDED_FOR');
  268. } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
  269. $onlineip = getenv('REMOTE_ADDR');
  270. } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
  271. $onlineip = $_SERVER['REMOTE_ADDR'];
  272. }
  273. return $onlineip;
  274. }
  275. /**
  276. * 获取$_SERVER下面的方法
  277. */
  278. function getServerParam($param)
  279. {
  280. if (isset($_SERVER[$param])) {
  281. return self::paramFilter($_SERVER[$param]);
  282. }
  283. return '';
  284. }
  285. /**
  286. * 全局的接收参数过滤
  287. */
  288. private function paramFilter($param)
  289. {
  290. if (is_array($param)) {
  291. foreach ($param as $key => $value) {
  292. if(is_array($value)){
  293. self::paramFilter($value);
  294. continue;
  295. }
  296. if(!is_numeric($value)){
  297. $param[$key] = htmlspecialchars(trim($value), ENT_QUOTES, 'UTF-8');
  298. }
  299. }
  300. } else if (!empty($param) && !is_numeric($param)) {
  301. $param = htmlspecialchars(trim($param), ENT_QUOTES, 'UTF-8');
  302. }
  303. return $param;
  304. }
  305. /**
  306. * 获取上传的文件信息
  307. *
  308. * @access public
  309. * @param string|array $name 名称
  310. *
  311. * @return null|array| \Mall\Framework\Core\File
  312. */
  313. public function file($name = '')
  314. {
  315. $files = isset($_FILES) ? $_FILES : [];
  316. if (is_array($name)) {
  317. return $files = array_merge($files, $name);
  318. }
  319. if (!empty($files)) {
  320. // 处理上传文件
  321. $array = [];
  322. foreach ($files as $key => $file) {
  323. if (is_array($file['name'])) {
  324. $item = [];
  325. $keys = array_keys($file);
  326. $count = count($file['name']);
  327. for ($i = 0; $i < $count; $i++) {
  328. if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) {
  329. continue;
  330. }
  331. $temp['key'] = $key;
  332. foreach ($keys as $_key) {
  333. $temp[$_key] = $file[$_key][$i];
  334. }
  335. $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp);
  336. }
  337. $array[$key] = $item;
  338. } else {
  339. if ($file instanceof File) {
  340. $array[$key] = $file;
  341. } else {
  342. if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) {
  343. continue;
  344. }
  345. $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file);
  346. }
  347. }
  348. }
  349. if (strpos($name, '.')) {
  350. list($name, $sub) = explode('.', $name);
  351. }
  352. if ('' === $name) {
  353. // 获取全部文件
  354. return $array;
  355. } elseif (isset($sub) && isset($array[$name][$sub])) {
  356. return $array[$name][$sub];
  357. } elseif (isset($array[$name])) {
  358. return $array[$name];
  359. }
  360. }
  361. return;
  362. }
  363. }