thinkphp5.0.19 request
一、请求类型
request类中 [F:\phpStudy\WWW\csweb\thinkphp\library\think\Request.php] 获取请求类型的方法分别是:
isGet() 、isPost()、isPut()、isDelete()、isHead()、isPatch()、isOptions()
1 /** 2 * 是否为GET请求 3 * @access public 4 * @return bool 5 */ 6 public function isGet() 7 { 8 return $this->method() == 'GET'; 9 } 10 11 /** 12 * 是否为POST请求 13 * @access public 14 * @return bool 15 */ 16 public function isPost() 17 { 18 return $this->method() == 'POST'; 19 } 20 21 /** 22 * 是否为PUT请求 23 * @access public 24 * @return bool 25 */ 26 public function isPut() 27 { 28 return $this->method() == 'PUT'; 29 } 30 31 /** 32 * 是否为DELTE请求 33 * @access public 34 * @return bool 35 */ 36 public function isDelete() 37 { 38 return $this->method() == 'DELETE'; 39 } 40 41 /** 42 * 是否为HEAD请求 43 * @access public 44 * @return bool 45 */ 46 public function isHead() 47 { 48 return $this->method() == 'HEAD'; 49 } 50 51 /** 52 * 是否为PATCH请求 53 * @access public 54 * @return bool 55 */ 56 public function isPatch() 57 { 58 return $this->method() == 'PATCH'; 59 } 60 61 /** 62 * 是否为OPTIONS请求 63 * @access public 64 * @return bool 65 */ 66 public function isOptions() 67 { 68 return $this->method() == 'OPTIONS'; 69 }
它们都调用了method():
1 /** 2 * 当前的请求类型 3 * @access public 4 * @param bool $method true 获取原始请求类型 5 * @return string 6 */ 7 public function method($method = false) 8 { 9 if (true === $method) { 10 // 获取原始请求类型 11 return IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']); 12 } elseif (!$this->method) { 13 if (isset($_POST[Config::get('var_method')])) { 14 $this->method = strtoupper($_POST[Config::get('var_method')]); 15 $this->{$this->method}($_POST); 16 } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { 17 $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); 18 } else { 19 $this->method = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']); 20 } 21 } 22 return $this->method; 23 }
method(true)是获取原始请求类型。直接读$_SERVER['REQUEST_METHOD']判断。
method()则是先判断 "伪装请求" 类型,其次才是真实的请求类型。
配置文件中的var_method、var_ajax、var_pjax则是伪装请求的配置变量:
下面表单将post伪装为put:
1 <form method="post" action=""> 2 <input type="text" name="name" value="Hello"> 3 <input type="hidden" name="_method" value="PUT" > 4 <input type="submit" value="提交"> 5 </form>
1 public function method($method = false) 2 { 3 if (true === $method) { 4 // 获取原始请求类型 5 return IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']); 6 } elseif (!$this->method) { 7 if (isset($_POST[Config::get('var_method')])) { // post类型表单请求 8 //获取伪装请求内容 9 $this->method = strtoupper($_POST[Config::get('var_method')]); 10 $this->{$this->method}($_POST); //$this->post($_POST)或$this->get($_POST)等处理$_POST数据 11 } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { //request header HTTP_X_HTTP_METHOD_OVERRIDE中定义的表单请求类型 12 $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); 13 } else { // get类型表单请求 14 $this->method = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']); 15 } 16 } 17 return $this->method; 18 }
ajax、pjax的判断:
1 /** 2 * 当前是否Ajax请求 3 * @access public 4 * @param bool $ajax true 获取原始ajax请求 5 * @return bool 6 */ 7 public function isAjax($ajax = false) 8 { 9 //根据header中的HTTP_X_REQUESTED_WITH判断是否为xmlhttprequest 10 $value = $this->server('HTTP_X_REQUESTED_WITH', '', 'strtolower'); 11 $result = ('xmlhttprequest' == $value) ? true : false; 12 if (true === $ajax) { 13 return $result; 14 } else { 15 //如果不是ajax请求则判断是否为模拟的ajax请求 16 return $this->param(Config::get('var_ajax')) ? true : $result; 17 } 18 } 19 20 /** 21 * 当前是否Pjax请求 22 * @access public 23 * @param bool $pjax true 获取原始pjax请求 24 * @return bool 25 */ 26 public function isPjax($pjax = false) 27 { 28 $result = !is_null($this->server('HTTP_X_PJAX')) ? true : false; 29 if (true === $pjax) { 30 return $result; 31 } else { 32 return $this->param(Config::get('var_pjax')) ? true : $result; 33 } 34 }
二、设置或获取header:
1 /** 2 * 设置或者获取当前的Header 3 * @access public 4 * @param string|array $name header名称 5 * @param string $default 默认值 6 * @return string 7 */ 8 public function header($name = '', $default = null) 9 { 10 //$this->header为空则设置 11 if (empty($this->header)) { 12 $header = []; 13 // 使用apache_request_headers()函数获取请求头request header 14 if (function_exists('apache_request_headers') && $result = apache_request_headers()) { 15 $header = $result; 16 } 17 //使用 $_SERVER获取请求头 request header 18 else { 19 $server = $this->server ?: $_SERVER; 20 //针对所有 $_SERVER['HTTP_*'] 元素 21 foreach ($server as $key => $val) { 22 if (0 === strpos($key, 'HTTP_')) { 23 //将HTTP_USER_AGENT形式转化为User-Agent形式(首字母大写) 24 $key = str_replace('_', '-', strtolower(substr($key, 5))); 25 $header[$key] = $val; 26 } 27 } 28 if (isset($server['CONTENT_TYPE'])) { 29 $header['content-type'] = $server['CONTENT_TYPE']; 30 } 31 if (isset($server['CONTENT_LENGTH'])) { 32 $header['content-length'] = $server['CONTENT_LENGTH']; 33 } 34 } 35 //转化为小写 36 $this->header = array_change_key_case($header); 37 } 38 if (is_array($name)) { 39 return $this->header = array_merge($this->header, $name); 40 } 41 //$name为空则返回所有header 42 if ('' === $name) { 43 return $this->header; 44 } 45 //将$name转为小写,并将其中的"_"替换为"-" 46 $name = str_replace('_', '-', strtolower($name)); 47 //查找header并返回 48 return isset($this->header[$name]) ? $this->header[$name] : $default; 49 }
三、获取content-type:
1 public function contentType() 2 { 3 $contentType = $this->server('CONTENT_TYPE'); 4 if ($contentType) { 5 if (strpos($contentType, ';')) { 6 //存在多个只会用第一个 7 list($type) = explode(';', $contentType); 8 } else { 9 $type = $contentType; 10 } 11 return trim($type); 12 } 13 return ''; 14 }
四、获取请求体(php://input):
1 /** 2 * 获取当前请求的php://input 3 * @access public 4 * @return string 5 */ 6 public function getInput() 7 { 8 return $this->input; 9 }
$this->input在构造函数处初始化:
1 protected function __construct($options = []) 2 { 3 foreach ($options as $name => $item) { 4 if (property_exists($this, $name)) { 5 $this->$name = $item; 6 } 7 } 8 if (is_null($this->filter)) { 9 $this->filter = Config::get('default_filter'); 10 } 11 12 // 保存 php://input 13 //1、php://input是个只读流,用于获取请求体(request body) 14 //2、$_POST可获取application/x-www-form-urlencoded 和 multipart/form-data-encoded 两种Content Type的请求体。 15 //3、$_POST不能获取诸如 application/json 等Content Type的请求体数据,php://input可以。 16 //4、content type为multipart/form-data-encoded时,php://input无效。即上传文件时不能使用php://input获取数据,可用$_FILES。 17 //5、相比较于 $HTTP_RAW_POST_DATA , php://input 无需额外地在php.ini中 激活 always-populate-raw-post-data ,而且对于内存的压力也比较小。 18 //reference http://www.digpage.com/web_request.html#id8 19 $this->input = file_get_contents('php://input'); 20 }