From 199825ec32e221343c92d6653711d3d869acf917 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 16 May 2016 14:18:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9BResponse=E7=B1=BB=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=89=A9=E5=B1=95=E4=B8=8D=E5=90=8C=E7=9A=84=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E7=B1=BB=E5=9E=8B=20=E6=94=B9=E8=BF=9BModel=E7=B1=BB?= =?UTF-8?q?=20=E4=B8=8D=E5=90=8C=E7=9A=84=E6=A8=A1=E5=9E=8B=E9=87=87?= =?UTF-8?q?=E7=94=A8=E4=B8=8D=E5=90=8C=E7=9A=84=E6=9F=A5=E8=AF=A2=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E5=AE=9E=E4=BE=8B=20=E4=BF=AE=E6=AD=A3Request?= =?UTF-8?q?=E7=B1=BB=E4=B8=80=E5=A4=84=E9=94=99=E8=AF=AF=20=E5=8A=A9?= =?UTF-8?q?=E6=89=8B=E5=87=BD=E6=95=B0view=E6=94=B9=E8=BF=9B=20=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E8=BF=94=E5=9B=9EResponse=E7=B1=BB=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helper.php | 27 ++- library/think/App.php | 5 +- library/think/Model.php | 53 ++-- library/think/Request.php | 3 +- library/think/Response.php | 227 ++++++++++++------ library/think/Validate.php | 2 +- library/think/controller/Rest.php | 2 +- library/think/db/Connection.php | 23 +- library/think/db/Query.php | 92 ++++--- library/think/exception/Handle.php | 15 +- library/think/response/Json.php | 36 +++ library/think/response/Jsonp.php | 39 +++ library/think/response/Redirect.php | 40 +++ library/traits/controller/Jump.php | 8 +- tests/thinkphp/library/think/responseTest.php | 60 +---- 15 files changed, 420 insertions(+), 212 deletions(-) create mode 100644 library/think/response/Json.php create mode 100644 library/think/response/Jsonp.php create mode 100644 library/think/response/Redirect.php diff --git a/helper.php b/helper.php index ed0cd711..8fe6851f 100644 --- a/helper.php +++ b/helper.php @@ -340,11 +340,14 @@ function trace($log = '[think]', $level = 'log') * 渲染模板输出 * @param string $template 模板文件 * @param array $vars 模板变量 - * @return string + * @param string $type 输出类型 + * @return \think\Response */ -function view($template = '', $vars = []) +function view($template = '', $vars = [], $type = 'html') { - return View::instance(Config::get('template'), Config::get('view_replace_str'))->fetch($template, $vars); + $data = View::instance(Config::get('template'), Config::get('view_replace_str'))->fetch($template, $vars); + $response = Response::create($type); + return $response->data($data); } /** @@ -371,10 +374,22 @@ function request() } /** - * 获取当前的Response对象实例 + * 创建Response对象实例 + * @param string $type 输出类型 + * @param array $options 参数 * @return \think\Response */ -function response() +function response($type = '', $options = []) { - return Response::instance(); + return Response::create($type, $options); +} + +/** + * 获取\think\response\Json对象实例 + * @param array $options 参数 + * @return \think\response\Json + */ +function json($options = []) +{ + return new \think\response\Json($options); } diff --git a/library/think/App.php b/library/think/App.php index e37d3f2b..965951e9 100644 --- a/library/think/App.php +++ b/library/think/App.php @@ -106,7 +106,7 @@ class App default: throw new Exception('dispatch type not support', 10008); } - } catch (HttpResponseException $exception){ + } catch (HttpResponseException $exception) { $data = $exception->getResponse(); } // 输出数据到客户端 @@ -116,8 +116,9 @@ class App } else { // 监听app_end APP_HOOK && Hook::listen('app_end', $data); + $type = IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type'); // 自动响应输出 - return Response::instance()->send($data, '', Config::get('response_return')); + return Response::create($type)->send($data); } } } diff --git a/library/think/Model.php b/library/think/Model.php index 05c33cf6..af278982 100644 --- a/library/think/Model.php +++ b/library/think/Model.php @@ -28,8 +28,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess // 数据库对象池 private static $links = []; - // 对象实例 - private static $instance = []; // 数据库配置 protected $connection = []; // 当前模型名称 @@ -90,9 +88,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * 架构函数 * @access public * @param array|object $data 数据 - * @param bool $init 是否初始化 */ - public function __construct($data = [], $init = true) + public function __construct($data = []) { if (is_object($data)) { $this->data = get_object_vars($data); @@ -103,12 +100,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $this->name = basename(str_replace('\\', '/', get_class($this))); } - if ($init) { - // 获取字段类型信息并缓存 - $this->fieldType = self::db('info')->getTableInfo('', 'type'); - $this->initialize(); - } - + $this->initialize(); } /** @@ -238,7 +230,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess public function getPk($table = '') { if (empty($this->pk)) { - $this->pk = self::db('info')->getTableInfo($table, 'pk'); + $this->pk = self::db()->getTableInfo($table, 'pk'); } return $this->pk; } @@ -866,32 +858,27 @@ abstract class Model implements \JsonSerializable, \ArrayAccess /** * 初始化数据库对象 * @access public - * @param bool $new 是否采用新的数据库连接 - * @return \think\db\Driver + * @return \think\db\Query */ - public static function db($new = false) + public static function db() { $model = get_called_class(); + if (!isset(self::$links[$model])) { + $class = new static(); - if ($new || !isset(self::$links[$model])) { - $class = new static([], false); - self::$links[$model] = Db::connect($class->connection, $new); - self::$instance[$model] = $class; - } else { - $class = self::$instance[$model]; + // 设置当前模型 确保查询返回模型对象 + self::$links[$model] = Db::connect($class->connection)->model($model); + + // 设置当前数据表和模型名 + if (!empty($class->table)) { + self::$links[$model]->table($class->table); + } else { + $name = !empty($class->name) ? $class->name : basename(str_replace('\\', '/', $model)); + self::$links[$model]->name($name); + } } - // 设置当前数据表和模型名 - if (!empty($class->table)) { - self::$links[$model]->table($class->table); - } else { - $name = !empty($class->name) ? $class->name : basename(str_replace('\\', '/', $model)); - self::$links[$model]->name($name); - } - - // 设置当前模型 确保查询返回模型对象 - self::$links[$model]->model($model); - // 返回当前数据库对象 + // 返回当前模型的数据库查询对象 return self::$links[$model]; } @@ -923,6 +910,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public function __set($name, $value) { + if (is_null($this->fieldType)) { + // 获取字段类型信息并缓存 + $this->fieldType = self::db()->getTableInfo('', 'type'); + } if (is_null($value) && in_array($name, $this->autoTimeField)) { // 自动写入的时间戳字段 if (isset($this->type[$name])) { diff --git a/library/think/Request.php b/library/think/Request.php index 5a4f9da0..7d0b2290 100644 --- a/library/think/Request.php +++ b/library/think/Request.php @@ -63,10 +63,11 @@ class Request protected $file = []; protected $cookie = []; protected $server = []; + /** * @var array 资源类型 */ - protected $mime = [ + protected $mimeType = [ 'html' => 'text/html,application/xhtml+xml,*/*', 'xml' => 'application/xml,text/xml,application/x-xml', 'json' => 'application/json,text/x-json,application/jsonrequest,text/json', diff --git a/library/think/Response.php b/library/think/Response.php index e0943711..aa1dbbd5 100644 --- a/library/think/Response.php +++ b/library/think/Response.php @@ -11,21 +11,16 @@ namespace think; -use think\Config; -use think\Url; - class Response { - protected static $instance; + // 输出类型的实例化对象 + protected static $instance = []; // 输出数据的转换方法 - protected $transform = null; - + protected $transform; // 输出数据 - protected $data = ''; + protected $data; // 是否exit protected $isExit = false; - // 输出类型 - protected $type = ''; // contentType protected $contentType = [ 'json' => 'application/json', @@ -36,74 +31,83 @@ class Response 'text' => 'text/plain', ]; + // 输出参数 + protected $options = []; + // header参数 + protected $header = []; + /** * 架构函数 * @access public * @param array $options 参数 */ - public function __construct($type = '') + public function __construct($options = []) { - $this->type = $type; + $this->options = array_merge($this->options, $options); } /** - * 初始化 + * 创建一个response对象 * @access public * @param string $type 输出类型 + * @param array $options 参数 * @return \think\Response */ - public static function instance($type = '') + public static function create($type = '', $options = []) { - if (is_null(self::$instance)) { - self::$instance = new static($type); + $type = strtolower($type ?: (IS_AJAX ? 'json' : 'html')); + if (!isset(self::$instance[$type])) { + self::$instance[$type] = new static($options); + self::$instance[$type]->type($type, $options); } - return self::$instance; + return self::$instance[$type]; } /** * 发送数据到客户端 * @access public * @param mixed $data 数据 - * @param string $type 返回类型 - * @param bool $return 是否返回数据 * @return mixed */ - public function send($data = [], $type = '', $return = false) + public function send($data = []) { - if ('' == $type) { - $type = $this->type ?: (IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type')); - } - $type = strtolower($type); $data = $data ?: $this->data; - if (!headers_sent() && isset($this->contentType[$type])) { - header('Content-Type:' . $this->contentType[$type] . '; charset=utf-8'); - } - if (is_callable($this->transform)) { $data = call_user_func_array($this->transform, [$data]); - } else { - switch ($type) { - case 'json': - // 返回JSON数据格式到客户端 包含状态信息 - $data = json_encode($data, JSON_UNESCAPED_UNICODE); - break; - case 'jsonp': - // 返回JSON数据格式到客户端 包含状态信息 - $handler = !empty($_GET[Config::get('var_jsonp_handler')]) ? $_GET[Config::get('var_jsonp_handler')] : Config::get('default_jsonp_handler'); - $data = $handler . '(' . json_encode($data, JSON_UNESCAPED_UNICODE) . ');'; - break; + } + + // 处理输出数据 + $data = $this->output($data); + // 发送头部信息 + if (!headers_sent() && !empty($this->header)) { + // 发送状态码 + if (isset($this->header['status'])) { + http_response_code($this->header['status']); + unset($this->header['status']); + } + + foreach ($this->header as $name => $val) { + header($name . ':' . $val); } } - - APP_HOOK && Hook::listen('return_data', $data); - - if ($return) { + echo $data; + if ($this->isExit) { + exit; + } else { return $data; } + } - echo $data; - $this->isExit() && exit(); + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + return $data; } /** @@ -118,6 +122,18 @@ class Response return $this; } + /** + * 输出的参数 + * @access public + * @param mixed $options 输出参数 + * @return $this + */ + public function options($options = []) + { + $this->options = array_merge($this->options, $options); + return $this; + } + /** * 输出数据设置 * @access public @@ -134,12 +150,20 @@ class Response * 输出类型设置 * @access public * @param string $type 输出内容的格式类型 + * @param array $options 参数 * @return $this */ - public function type($type) + public function type($type, $options = []) { - $this->type = $type; - return $this; + $type = strtolower($type); + if (!isset(self::$instance[$type])) { + $class = '\\think\\response\\' . ucfirst($type); + self::$instance[$type] = class_exists($class) ? new $class($options) : $this; + } + if (isset($this->contentType[$type])) { + self::$instance[$type]->contentType($this->contentType[$type]); + } + return self::$instance[$type]; } /** @@ -148,11 +172,8 @@ class Response * @param bool $exit 是否退出 * @return $this */ - public function isExit($exit = null) + public function isExit($exit) { - if (is_null($exit)) { - return $this->isExit; - } $this->isExit = (boolean) $exit; return $this; } @@ -165,7 +186,7 @@ class Response * @param string $msg 提示信息 * @return mixed */ - public function result($data, $code = 0, $msg = '', $type = '') + public function result($data, $code = 0, $msg = '') { $result = [ 'code' => $code, @@ -173,26 +194,7 @@ class Response 'time' => NOW_TIME, 'data' => $data, ]; - $this->type = $type; - return $result; - } - - /** - * URL重定向 - * @access public - * @param string $url 跳转的URL表达式 - * @param array|int $params 其它URL参数或http code - * @return void - */ - public function redirect($url, $params = []) - { - $http_response_code = 301; - if (is_int($params) && in_array($params, [301, 302])) { - $http_response_code = $params; - $params = []; - } - $url = preg_match('/^(https?:|\/)/', $url) ? $url : Url::build($url, $params); - header('Location: ' . $url, true, $http_response_code); + return $this->data($result); } /** @@ -204,7 +206,18 @@ class Response */ public function header($name, $value) { - header($name . ':' . $value); + $this->header[$name] = $value; + return $this; + } + + /** + * 发送HTTP Location + * @param string $url Location地址 + * @return $this + */ + public function location($url) + { + $this->header['Location'] = $url; return $this; } @@ -215,7 +228,73 @@ class Response */ public function code($code) { - http_response_code($code); + $this->header['status'] = $code; return $this; } + + /** + * LastModified + * @param string $time + * @return $this + */ + public function lastModified($time) + { + $this->header['Last-Modified'] = $time; + return $this; + } + + /** + * Expires + * @param string $time + * @return $this + */ + public function expires($time) + { + $this->header['Expires'] = $time; + return $this; + } + + /** + * ETag + * @param string $etag + * @return $this + */ + public function eTag($etag) + { + $this->header['etag'] = $etag; + return $this; + } + + /** + * 页面缓存控制 + * @param string $cache 状态码 + * @return $this + */ + public function cacheControl($cache) + { + $this->header['Cache-control'] = $cache; + return $this; + } + + /** + * 页面输出类型 + * @param string $contentType 输出类型 + * @param string $charset 输出编码 + * @return $this + */ + public function contentType($contentType, $charset = 'utf-8') + { + $this->header['Content-Type'] = $contentType . '; charset=' . $charset; + return $this; + } + + /** + * 获取头部信息 + * @param string $name 头部名称 + * @return mixed + */ + public function getHeader($name = '') + { + return !empty($name) ? $this->header[$name] : $this->header; + } } diff --git a/library/think/Validate.php b/library/think/Validate.php index 5ff0929d..69b1778d 100644 --- a/library/think/Validate.php +++ b/library/think/Validate.php @@ -335,7 +335,7 @@ class Validate } // 如果不是require 有数据才会行验证 - if (0 === strpos($info, 'require') || !empty($value)) { + if (0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) { // 验证类型 $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type]; // 验证数据 diff --git a/library/think/controller/Rest.php b/library/think/controller/Rest.php index 1608ff94..c7be9b07 100644 --- a/library/think/controller/Rest.php +++ b/library/think/controller/Rest.php @@ -92,7 +92,7 @@ abstract class Rest */ protected function response($data, $type = '', $code = 200) { - return Response::instance()->data($data)->type($type)->code($code); + return Response::create($type)->data($data)->code($code); } /** diff --git a/library/think/db/Connection.php b/library/think/db/Connection.php index 14ce32bc..71d84f3a 100644 --- a/library/think/db/Connection.php +++ b/library/think/db/Connection.php @@ -61,7 +61,8 @@ abstract class Connection protected $attrCase = PDO::CASE_LOWER; // 监听回调 protected static $event = []; - + // 查询对象 + protected $query = []; // 数据库连接参数配置 protected $config = [ // 数据库类型 @@ -119,7 +120,20 @@ abstract class Connection if (!empty($config)) { $this->config = array_merge($this->config, $config); } - $this->query = new Query($this); + } + + /** + * 创建指定模型的查询对象 + * @access public + * @param string $model 模型类名称 + * @return \think\Query + */ + public function model($model) + { + if (!isset($this->query[$model])) { + $this->query[$model] = new Query($this, $model); + } + return $this->query[$model]; } /** @@ -131,7 +145,10 @@ abstract class Connection */ public function __call($method, $args) { - return call_user_func_array([$this->query, $method], $args); + if (!isset($this->query['database'])) { + $this->query['database'] = new Query($this); + } + return call_user_func_array([$this->query['database'], $method], $args); } /** diff --git a/library/think/db/Query.php b/library/think/db/Query.php index 7218cbdc..c23b242c 100644 --- a/library/think/db/Query.php +++ b/library/think/db/Query.php @@ -29,7 +29,12 @@ class Query protected $connection; // 数据库驱动类型 protected $driver; - + // 当前模型类名称 + protected $model; + // 当前数据表名称(含前缀) + protected $table; + // 当前数据表名称(不含前缀) + protected $name; // 查询参数 protected $options = []; // 参数绑定 @@ -41,10 +46,11 @@ class Query * @param object|string $connection 数据库对象实例 * @throws Exception */ - public function __construct($connection = '') + public function __construct($connection = '', $model = '') { $this->connection = $connection ?: Db::connect([], true); $this->driver = $this->connection->getDriverName(); + $this->model = $model; } /** @@ -73,6 +79,39 @@ class Query } } + /** + * 执行查询 返回数据集 + * @access public + * @param string $sql sql指令 + * @param array $bind 参数绑定 + * @param boolean $fetch 不执行只是获取SQL + * @param boolean $master 是否在主服务器读操作 + * @param bool|string $class 指定返回的数据集对象 + * @return mixed + * @throws DbBindParamException + * @throws PDOException + */ + public function query($sql, $bind = [], $fetch = false, $master = false, $class = false) + { + return $this->connection->query($sql, $bind, $fetch, $master, $class); + } + + /** + * 执行语句 + * @access public + * @param string $sql sql指令 + * @param array $bind 参数绑定 + * @param boolean $fetch 不执行只是获取SQL + * @param boolean $getLastInsID 是否获取自增ID + * @return int + * @throws DbBindParamException + * @throws PDOException + */ + public function execute($sql, $bind = [], $fetch = false, $getLastInsID = false) + { + return $this->connection->execute($sql, $bind, $fetch, $getLastInsID); + } + /** * 获取当前的builder实例对象 * @access protected @@ -677,7 +716,7 @@ class Query */ public function table($table) { - $this->options['table'] = $table; + $this->table = $table; return $this; } @@ -898,18 +937,6 @@ class Query return $this; } - /** - * 指定当前模型 - * @access public - * @param string $model 模型类名称 - * @return $this - */ - public function model($model) - { - $this->options['model'] = $model; - return $this; - } - /** * 设置当前name * @access public @@ -918,7 +945,7 @@ class Query */ public function name($name) { - $this->options['name'] = $name; + $this->name = $name; return $this; } @@ -929,13 +956,13 @@ class Query */ public function getTable() { - if (empty($this->options['table'])) { + if (empty($this->table)) { $tableName = $this->connection->getConfig('prefix'); - if (isset($this->options['name'])) { - $tableName .= Loader::parseName($this->options['name']); + if (isset($this->name)) { + $tableName .= Loader::parseName($this->name); } } else { - $tableName = $this->options['table']; + $tableName = $this->table; } return $tableName; } @@ -1059,7 +1086,7 @@ class Query } $i = 0; - $currentModel = $this->options['model']; + $currentModel = $this->model; /** @var Model $class */ $class = new $currentModel; @@ -1181,7 +1208,7 @@ class Query // 生成SQL语句 $sql = $this->builder()->insert($data, $options, $replace); // 执行操作 - return $this->connection->execute($sql, $this->getBind(), $options['fetch_sql'], $getLastInsID); + return $this->execute($sql, $this->getBind(), $options['fetch_sql'], $getLastInsID); } /** @@ -1212,7 +1239,7 @@ class Query // 生成SQL语句 $sql = $this->builder()->insertAll($dataSet, $options); // 执行操作 - return $this->connection->execute($sql, $this->getBind(), $options['fetch_sql']); + return $this->execute($sql, $this->getBind(), $options['fetch_sql']); } /** @@ -1230,7 +1257,7 @@ class Query // 生成SQL语句 $sql = $this->builder()->selectInsert($fields, $table, $options); // 执行操作 - return $this->connection->execute($sql, $this->getBind(), $options['fetch_sql']); + return $this->execute($sql, $this->getBind(), $options['fetch_sql']); } /** @@ -1275,7 +1302,7 @@ class Query return 0; } // 执行操作 - return $this->connection->execute($sql, $this->getBind(), $options['fetch_sql']); + return $this->execute($sql, $this->getBind(), $options['fetch_sql']); } /** @@ -1316,7 +1343,7 @@ class Query // 生成查询SQL $sql = $this->builder()->select($options); // 执行查询操作 - $resultSet = $this->connection->query($sql, $this->getBind(), $options['fetch_sql'], $options['master'], $options['fetch_class']); + $resultSet = $this->query($sql, $this->getBind(), $options['fetch_sql'], $options['master'], $options['fetch_class']); if (is_string($resultSet)) { // 返回SQL @@ -1337,9 +1364,9 @@ class Query if ($resultSet) { // 数据列表读取后的处理 - if (!empty($options['model'])) { + if (!empty($this->model)) { // 生成模型对象 - $model = $options['model']; + $model = $this->model; foreach ($resultSet as $key => $result) { /** @var Model $result */ $result = new $model($result); @@ -1397,7 +1424,7 @@ class Query // 生成查询SQL $sql = $this->builder()->select($options); // 执行查询 - $result = $this->connection->query($sql, $this->getBind(), $options['fetch_sql'], $options['master'], $options['fetch_class']); + $result = $this->query($sql, $this->getBind(), $options['fetch_sql'], $options['master'], $options['fetch_class']); if (is_string($result)) { // 返回SQL @@ -1418,9 +1445,10 @@ class Query // 数据处理 if (!empty($result[0])) { $data = $result[0]; - if (!empty($options['model'])) { + if (!empty($this->model)) { // 返回模型对象 - $data = new $options['model']($data); + $model = $this->model; + $data = new $model($data); $data->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null); // 关联查询 if (!empty($options['relation'])) { @@ -1517,7 +1545,7 @@ class Query // 生成删除SQL语句 $sql = $this->builder()->delete($options); // 执行操作 - return $this->connection->execute($sql, $this->getBind(), $options['fetch_sql']); + return $this->execute($sql, $this->getBind(), $options['fetch_sql']); } /** diff --git a/library/think/exception/Handle.php b/library/think/exception/Handle.php index a43122b1..a319f9c8 100644 --- a/library/think/exception/Handle.php +++ b/library/think/exception/Handle.php @@ -22,7 +22,7 @@ class Handle { protected $ignoreReport = [ - '\\think\\exception\\HttpException' + '\\think\\exception\\HttpException', ]; /** @@ -40,15 +40,15 @@ class Handle 'file' => $exception->getFile(), 'line' => $exception->getLine(), 'message' => $exception->getMessage(), - 'code' => $this->getCode($exception) + 'code' => $this->getCode($exception), ]; - $log = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]"; + $log = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]"; } else { $data = [ 'code' => $exception->getCode(), 'message' => $exception->getMessage(), ]; - $log = "[{$data['code']}]{$data['message']}"; + $log = "[{$data['code']}]{$data['message']}"; } Log::record($log, 'error'); @@ -130,7 +130,7 @@ class Handle 'Server/Request Data' => $_SERVER, 'Environment Variables' => $_ENV, 'ThinkPHP Constants' => $this->getConst(), - ] + ], ]; } else { // 部署模式仅显示 Code 和 Message @@ -151,7 +151,7 @@ class Handle // 获取并清空缓存 $content = ob_get_clean(); - $response = Response::instance()->data($content); + $response = Response::create('html')->data($content); if ($exception instanceof HttpException) { $statusCode = $exception->getStatusCode(); @@ -205,7 +205,6 @@ class Handle return $source; } - /** * 获取异常扩展信息 * 用于非调试模式html返回类型显示 @@ -229,4 +228,4 @@ class Handle { return get_defined_constants(true)['user']; } -} \ No newline at end of file +} diff --git a/library/think/response/Json.php b/library/think/response/Json.php new file mode 100644 index 00000000..963221bc --- /dev/null +++ b/library/think/response/Json.php @@ -0,0 +1,36 @@ + +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Response; + +class Json extends Response +{ + // 输出参数 + protected $options = [ + 'json_encode_param' => JSON_UNESCAPED_UNICODE, + ]; + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + // 返回JSON数据格式到客户端 包含状态信息 + $data = json_encode($data, $this->options['json_encode_param']); + return $data; + } + +} diff --git a/library/think/response/Jsonp.php b/library/think/response/Jsonp.php new file mode 100644 index 00000000..8bfc8907 --- /dev/null +++ b/library/think/response/Jsonp.php @@ -0,0 +1,39 @@ + +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Response; + +class Jsonp extends Response +{ + // 输出参数 + protected $options = [ + 'var_jsonp_handler' => 'callback', + 'default_jsonp_handler' => 'jsonpReturn', + 'json_encode_param' => JSON_UNESCAPED_UNICODE, + ]; + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + // 返回JSON数据格式到客户端 包含状态信息 + $handler = !empty($_GET[$this->options['var_jsonp_handler']]) ? $_GET[$this->options['var_jsonp_handler']] : $this->options['default_jsonp_handler']; + $data = $handler . '(' . json_encode($data, $this->options['json_encode_param']) . ');'; + return $data; + } + +} diff --git a/library/think/response/Redirect.php b/library/think/response/Redirect.php new file mode 100644 index 00000000..2cb90745 --- /dev/null +++ b/library/think/response/Redirect.php @@ -0,0 +1,40 @@ + +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Response; +use think\Url; + +class Redirect extends Response +{ + + protected $options = [ + 'http_response_code' => 301, + 'http_url_params' => [], + ]; + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + $this->isExit = true; + $url = preg_match('/^(https?:|\/)/', $data) ? $data : Url::build($data, $this->options['http_url_params']); + $this->header['Location'] = $url; + $this->header['status'] = $this->options['http_response_code']; + return; + } + +} diff --git a/library/traits/controller/Jump.php b/library/traits/controller/Jump.php index 8c2e4b38..d7c3b83f 100644 --- a/library/traits/controller/Jump.php +++ b/library/traits/controller/Jump.php @@ -50,7 +50,7 @@ trait Jump $result = View::instance(Config::get('template'), Config::get('view_replace_str')) ->fetch(Config::get('dispatch_success_tmpl'), $result); } - Response::instance()->send($result, $type); + return Response::create($type)->data($result); } /** @@ -83,7 +83,7 @@ trait Jump $result = View::instance(Config::get('template'), Config::get('view_replace_str')) ->fetch(Config::get('dispatch_error_tmpl'), $result); } - Response::instance()->send($result, $type); + return Response::create($type)->data($result); } /** @@ -97,7 +97,7 @@ trait Jump */ public function result($data, $code = 0, $msg = '', $type = '') { - return Response::instance()->result($data, $code, $msg, $type); + return Response::create($type)->result($data, $code, $msg); } /** @@ -109,7 +109,7 @@ trait Jump */ public function redirect($url, $params = []) { - Response::instance()->redirect($url, $params); + Response::create()->isExit(true)->redirect($url, $params); } } diff --git a/tests/thinkphp/library/think/responseTest.php b/tests/thinkphp/library/think/responseTest.php index 2bba1845..6aaee446 100644 --- a/tests/thinkphp/library/think/responseTest.php +++ b/tests/thinkphp/library/think/responseTest.php @@ -70,7 +70,7 @@ class responseTest extends \PHPUnit_Framework_TestCase { Config::set('default_ajax_return', $this->default_ajax_return); Config::set('default_return_type', $this->default_return_type); - Response::instance()->type(Config::get('default_return_type')); // 会影响其他测试 + Response::create(Config::get('default_return_type')); // 会影响其他测试 } /** @@ -83,16 +83,11 @@ class responseTest extends \PHPUnit_Framework_TestCase $dataArr["key"] = "value"; //$dataArr->key = "val"; - $response = Response::instance(); - $result = $response->send($dataArr, "", true); - $this->assertArrayHasKey("key", $result); - - $result = $response->send($dataArr, "json", true); + $response = Response::create(); + $result = $response->type('json')->send($dataArr); $this->assertEquals('{"key":"value"}', $result); - - $handler = "callback"; - $_GET[Config::get('var_jsonp_handler')] = $handler; - $result = $response->send($dataArr, "jsonp", true); + $_GET['callback'] = 'callback'; + $result = $response->type('jsonp', ['var_jsonp_handler' => 'callback'])->send($dataArr); $this->assertEquals('callback({"key":"value"});', $result); $response->transform(function () { @@ -100,7 +95,7 @@ class responseTest extends \PHPUnit_Framework_TestCase return "callbackreturndata"; }); - $result = $response->send($dataArr, "", true); + $result = $response->send($dataArr); $this->assertEquals("callbackreturndata", $result); $_GET[Config::get('var_jsonp_handler')] = ""; } @@ -111,13 +106,13 @@ class responseTest extends \PHPUnit_Framework_TestCase */ public function testtransform() { - $response = Response::instance(); + $response = Response::create(); $response->transform(function () { return "callbackreturndata"; }); $dataArr = []; - $result = $response->send($dataArr, "", true); + $result = $response->send($dataArr); $this->assertEquals("callbackreturndata", $result); $response->transform(null); @@ -130,7 +125,7 @@ class responseTest extends \PHPUnit_Framework_TestCase public function testType() { $type = "json"; - Response::instance()->type($type); + Response::create($type); } /** @@ -139,45 +134,12 @@ class responseTest extends \PHPUnit_Framework_TestCase */ public function testData() { - $data = "data"; - $response = Response::instance(); + $data = "data"; + $response = Response::create(); $response->data($data); $response->data(null); } - /** - * @covers think\Response::isExit - * @todo Implement testIsExit(). - */ - public function testIsExit() - { - $isExit = true; - $response = Response::instance(); - $response->isExit($isExit); - - $result = $response->isExit(); - $this->assertTrue($isExit, $result); - $response->isExit(false); - } - - /** - * @covers think\Response::result - * @todo Implement testResult(). - */ - public function testResult() - { - $data = "data"; - $code = "1001"; - $msg = "the msg"; - $type = "json"; - $result = Response::instance()->result($data, $code, $msg, $type); - - $this->assertEquals($code, $result["code"]); - $this->assertEquals($msg, $result["msg"]); - $this->assertEquals($data, $result["data"]); - $this->assertEquals($_SERVER['REQUEST_TIME'], $result["time"]); - } - /** * @#runInSeparateProcess * @covers think\Response::redirect