diff --git a/helper.php b/helper.php index 6fc757ef..8e7908c8 100644 --- a/helper.php +++ b/helper.php @@ -362,14 +362,15 @@ function request() /** * 创建普通 Response 对象实例 - * @param mixed $data 输出数据 - * @param string $code 状态码 - * @param array $header 头信息 + * @param mixed $data 输出数据 + * @param int|string $code 状态码 + * @param array $header 头信息 + * @param string $type * @return Response */ function response($data = [], $code = 200, $header = [], $type = 'html') { - return Response::create($data, $type)->code($code)->header($header); + return Response::create($data, $type, $code, $header); } /** @@ -381,43 +382,46 @@ function response($data = [], $code = 200, $header = [], $type = 'html') */ function view($template = '', $vars = [], $code = 200) { - return Response::create($template, 'view')->vars($vars)->code($code); + return Response::create($template, 'view', $code)->vars($vars); } /** * 获取\think\response\Json对象实例 - * @param mixed $data 返回的数据 + * @param mixed $data 返回的数据 * @param integer $code 状态码 - * @param array $options 参数 + * @param array $header 头部 + * @param array $options 参数 * @return \think\response\Json */ -function json($data = [], $code = 200, $options = []) +function json($data = [], $code = 200, $header = [], $options = []) { - return Response::create($data, 'json', $options)->code($code); + return Response::create($data, 'json', $code, $header, $options); } /** * 获取\think\response\Jsonp对象实例 - * @param mixed $data 返回的数据 - * @param integer $code 状态码 - * @param array $options 参数 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $header 头部 + * @param array $options 参数 * @return \think\response\Jsonp */ -function jsonp($data = [], $code = 200, $options = []) +function jsonp($data = [], $code = 200, $header = [], $options = []) { - return Response::create($data, 'jsonp', $options)->code($code); + return Response::create($data, 'jsonp', $code, $header, $options); } /** * 获取\think\response\Xml对象实例 - * @param mixed $data 返回的数据 - * @param integer $code 状态码 - * @param array $options 参数 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $header 头部 + * @param array $options 参数 * @return \think\response\Xml */ -function xml($data = [], $code = 200, $options = []) +function xml($data = [], $code = 200, $header = [], $options = []) { - return Response::create($data, 'xml', $options)->code($code); + return Response::create($data, 'xml', $code, $header, $options); } /** @@ -433,7 +437,7 @@ function redirect($url = [], $params = [], $code = 302) $code = $params; $params = []; } - return Response::create($url, 'redirect')->code($code)->params($params); + return Response::create($url, 'redirect', $code)->params($params); } /** diff --git a/library/think/App.php b/library/think/App.php index edeac39e..e3724e98 100644 --- a/library/think/App.php +++ b/library/think/App.php @@ -195,7 +195,7 @@ class App /** * 绑定参数 * @access public - * @param \ReflectionMethod $reflect 反射类 + * @param \ReflectionMethod|\ReflectionFunction $reflect 反射类 * @param array $vars 变量 * @return array */ diff --git a/library/think/Controller.php b/library/think/Controller.php index a759ebc7..a34d90fd 100644 --- a/library/think/Controller.php +++ b/library/think/Controller.php @@ -14,9 +14,7 @@ namespace think; \think\Loader::import('controller/Jump', TRAIT_PATH, EXT); use think\Exception; -use think\Exception\ValidateException; -use think\Request; -use think\View; +use think\exception\ValidateException; class Controller { @@ -161,12 +159,13 @@ class Controller /** * 验证数据 * @access protected - * @param array $data 数据 - * @param string|array $validate 验证器名或者验证规则数组 - * @param array $message 提示信息 - * @param bool $batch 是否批量验证 - * @param mixed $callback 回调方法(闭包) - * @return true|string|array + * @param array $data 数据 + * @param string|array $validate 验证器名或者验证规则数组 + * @param array $message 提示信息 + * @param bool $batch 是否批量验证 + * @param mixed $callback 回调方法(闭包) + * @return array|string|true + * @throws ValidateException */ protected function validate($data, $validate, $message = [], $batch = false, $callback = null) { diff --git a/library/think/Request.php b/library/think/Request.php index 04d17d21..6013448e 100644 --- a/library/think/Request.php +++ b/library/think/Request.php @@ -1306,7 +1306,7 @@ class Request * 设置或者获取当前的模块名 * @access public * @param string $module 模块名 - * @return string + * @return string|$this */ public function module($module = null) { @@ -1322,7 +1322,7 @@ class Request * 设置或者获取当前的控制器名 * @access public * @param string $controller 控制器名 - * @return string + * @return string|$this */ public function controller($controller = null) { diff --git a/library/think/Response.php b/library/think/Response.php index 49e492da..0165694f 100644 --- a/library/think/Response.php +++ b/library/think/Response.php @@ -11,80 +11,75 @@ namespace think; -use think\Hook; +use think\response\Json; +use think\response\Jsonp; +use think\response\Redirect; +use think\response\View; +use think\response\Xml; class Response { - // 输出类型的实例化对象 - protected static $instance = []; - // 输出数据的转换方法 - protected $transform; + // 原始数据 protected $data; - // 输出类型 - protected $type; + // 当前的contentType - protected $contentType; - // 可用的输出类型 - protected $contentTypes = [ - 'json' => 'application/json', - 'xml' => 'text/xml', - 'html' => 'text/html', - 'jsonp' => 'application/javascript', - 'script' => 'application/javascript', - 'text' => 'text/plain', - ]; + protected $contentType = 'text/html'; + + // 字符集 + protected $charset = 'utf-8'; + + //状态 + protected $code = 200; // 输出参数 protected $options = []; // header参数 protected $header = []; + protected $content = null; + /** * 架构函数 - * @access public - * @param mixed $data 输出数据 - * @param string $type 输出类型 - * @param array $options 输出参数 + * @access public + * @param mixed $data 输出数据 + * @param int $code + * @param array $header + * @param array $options 输出参数 */ - public function __construct($data = '', $type = '', $options = []) + public function __construct($data = '', $code = 200, array $header = [], $options = []) { - $this->data = $data; - $this->type = empty($type) ? 'null' : strtolower($type); - - if (isset($this->contentTypes[$this->type])) { - $this->contentType($this->contentTypes[$this->type]); - } - + $this->data($data); + $this->header = $header; + $this->code = $code; if (!empty($options)) { $this->options = array_merge($this->options, $options); } - // 方便获取某个类型的实例 - self::$instance[$this->type] = $this; + $this->contentType($this->contentType, $this->charset); } /** * 创建Response对象 * @access public - * @param mixed $data 输出数据 - * @param string $type 输出类型 - * @param array $options 输出参数 - * @return Response + * @param mixed $data 输出数据 + * @param string $type 输出类型 + * @param int $code + * @param array $header + * @param array $options 输出参数 + * @return Response|Json|View|Xml|Redirect|Jsonp */ - public static function create($data = '', $type = '', $options = []) + public static function create($data = '', $type = '', $code = 200, array $header = [], $options = []) { $type = empty($type) ? 'null' : strtolower($type); - if (!isset(self::$instance[$type])) { - $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst($type); - if (class_exists($class)) { - $response = new $class($data, $type, $options); - } else { - $response = new static($data, $type, $options); - } - self::$instance[$type] = $response; + $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst($type); + if (class_exists($class)) { + $response = new $class($data, $code, $header, $options); + } else { + $response = new static($data, $code, $header, $options); } - return self::$instance[$type]; + + return $response; } /** @@ -95,11 +90,6 @@ class Response */ public function send() { - if (isset($this->contentType)) { - $this->contentType($this->contentType); - } - - defined('RESPONSE_TYPE') or define('RESPONSE_TYPE', $this->type); // 处理输出数据 $data = $this->getContent(); @@ -110,26 +100,20 @@ class Response // 发送头部信息 if (!headers_sent() && !empty($this->header)) { // 发送状态码 - if (isset($this->header['status'])) { - http_response_code($this->header['status']); - unset($this->header['status']); - } + http_response_code($this->code); foreach ($this->header as $name => $val) { header($name . ':' . $val); } } - if (is_scalar($data)) { - echo $data; - } elseif (!is_null($data)) { - throw new \InvalidArgumentException('variable type error:' . gettype($data)); - } + + echo $data; if (function_exists('fastcgi_finish_request')) { // 提高页面响应 fastcgi_finish_request(); } - return $data; + } /** @@ -143,18 +127,6 @@ class Response return $data; } - /** - * 转换控制器输出的数据 - * @access public - * @param mixed $callback 调用的转换方法 - * @return $this - */ - public function transform($callback) - { - $this->transform = $callback; - return $this; - } - /** * 输出的参数 * @access public @@ -179,11 +151,12 @@ class Response return $this; } + /** * 设置响应头 * @access public - * @param string|array $name 参数名 - * @param string $value 参数值 + * @param string|array $name 参数名 + * @param string $value 参数值 * @return $this */ public function header($name, $value = null) @@ -196,17 +169,6 @@ class Response return $this; } - /** - * 发送HTTP Location - * @param string $url Location地址 - * @return $this - */ - public function location($url) - { - $this->header['Location'] = $url; - return $this; - } - /** * 发送HTTP状态 * @param integer $code 状态码 @@ -214,7 +176,7 @@ class Response */ public function code($code) { - $this->header['status'] = $code; + $this->code = $code; return $this; } @@ -242,12 +204,12 @@ class Response /** * ETag - * @param string $etag + * @param string $eTag * @return $this */ - public function eTag($etag) + public function eTag($eTag) { - $this->header['etag'] = $etag; + $this->header['ETag'] = $eTag; return $this; } @@ -264,8 +226,8 @@ class Response /** * 页面输出类型 - * @param string $contentType 输出类型 - * @param string $charset 输出编码 + * @param string $contentType 输出类型 + * @param string $charset 输出编码 * @return $this */ public function contentType($contentType, $charset = 'utf-8') @@ -299,22 +261,19 @@ class Response */ public function getContent() { - if (is_callable($this->transform)) { - $data = call_user_func_array($this->transform, [$this->data]); - } else { - $data = $this->data; + $content = $this->output($this->data); + + if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ + $content, + '__toString' + ]) + ) { + throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); } - return $this->output($data); + + return (string)$content; } - /** - * 获取输出类型 - * @return string - */ - public function getType() - { - return $this->type; - } /** * 获取状态码 @@ -322,6 +281,6 @@ class Response */ public function getCode() { - return isset($this->header['status']) ? $this->header['status'] : 200; + return $this->code; } } diff --git a/library/think/response/Json.php b/library/think/response/Json.php index 23b68ea6..f3cfc36f 100644 --- a/library/think/response/Json.php +++ b/library/think/response/Json.php @@ -19,6 +19,7 @@ class Json extends Response protected $options = [ 'json_encode_param' => JSON_UNESCAPED_UNICODE, ]; + protected $contentType = 'application/json'; /** * 处理数据 diff --git a/library/think/response/Jsonp.php b/library/think/response/Jsonp.php index 85445c97..04f0c897 100644 --- a/library/think/response/Jsonp.php +++ b/library/think/response/Jsonp.php @@ -21,6 +21,7 @@ class Jsonp extends Response 'default_jsonp_handler' => 'jsonpReturn', 'json_encode_param' => JSON_UNESCAPED_UNICODE, ]; + protected $contentType = 'application/javascript'; /** diff --git a/library/think/response/Redirect.php b/library/think/response/Redirect.php index f6604039..ae6084c4 100644 --- a/library/think/response/Redirect.php +++ b/library/think/response/Redirect.php @@ -24,6 +24,12 @@ class Redirect extends Response // URL参数 protected $params = []; + public function __construct($data = '', $code = 302, array $header = [], array $options = []) + { + parent::__construct($data, $code, $header, $options); + $this->cacheControl('no-cache,must-revalidate'); + } + /** * 处理数据 * @access protected @@ -32,10 +38,7 @@ class Redirect extends Response */ protected function output($data) { - $url = preg_match('/^(https?:|\/)/', $data) ? $data : Url::build($data, $this->params); - $this->header['Location'] = $url; - $this->header['status'] = isset($this->header['status']) ? $this->header['status'] : 302; - $this->header['Cache-control'] = 'no-cache,must-revalidate'; + $this->header['Location'] = $this->getTargetUrl(); return; } @@ -45,8 +48,7 @@ class Redirect extends Response */ public function getTargetUrl() { - $this->getContent(); - return $this->header['Location']; + return preg_match('/^(https?:|\/)/', $this->data) ? $this->data : Url::build($this->data, $this->params); } public function params($params = [])