From 8e1cd9c51f5e051284f4904ec7d277f7b6008e66 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 11 May 2016 07:51:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9BResponse=E7=B1=BB=20=E6=94=B9?= =?UTF-8?q?=E8=BF=9Btraits\controller\Jump=20=E6=B7=BB=E5=8A=A0response?= =?UTF-8?q?=E5=8A=A9=E6=89=8B=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helper.php | 12 + library/think/App.php | 10 +- library/think/Response.php | 253 +++++++----------- library/traits/controller/Jump.php | 74 +++-- tests/thinkphp/library/think/responseTest.php | 106 -------- 5 files changed, 166 insertions(+), 289 deletions(-) diff --git a/helper.php b/helper.php index 56558928..7db8de1d 100644 --- a/helper.php +++ b/helper.php @@ -23,6 +23,7 @@ use think\Lang; use think\Loader; use think\Log; use think\Request; +use think\Response; use think\Route; use think\Session; use think\Url; @@ -370,3 +371,14 @@ function request($name, $param = '') { return Request::instance()->$name($param); } + +/** + * 设置Response输出 + * @param string $name 方法 + * @param mixed $param 参数 + * @return mixed + */ +function response($name, $param = '') +{ + return Response::$name($param); +} diff --git a/library/think/App.php b/library/think/App.php index 9d5db618..b340ca05 100644 --- a/library/think/App.php +++ b/library/think/App.php @@ -11,6 +11,8 @@ namespace think; +use think\Response; + /** * App 应用管理 * @author liu21st @@ -100,12 +102,12 @@ class App default: throw new Exception('dispatch type not support', 10008); } - // 监听app_end - APP_HOOK && Hook::listen('app_end', $data); // 输出数据到客户端 - if (isset($data)) { + if (isset($data) && !is_null($data)) { + // 监听app_end + APP_HOOK && Hook::listen('app_end', $data); // 自动响应输出 - return Response::send($data, Response::type(), Config::get('response_return')); + return Response::send($data, '', Config::get('response_return')); } } diff --git a/library/think/Response.php b/library/think/Response.php index 0eca0c68..4643e56e 100644 --- a/library/think/Response.php +++ b/library/think/Response.php @@ -13,45 +13,98 @@ namespace think; use think\Config; use think\Url; -use think\View; class Response { // 输出数据的转换方法 protected static $transform = null; - // 输出数据的类型 - protected static $type = ''; + // 输出数据 protected static $data = ''; // 是否exit protected static $isExit = false; + // 输出类型 + protected static $type = ''; + // contentType + protected static $contentType = [ + 'json' => 'application/json', + 'xml' => 'text/xml', + 'html' => 'text/html', + 'jsonp' => 'application/javascript', + 'script' => 'application/javascript', + 'text' => 'text/plain', + ]; + // HTTP status + protected static $code = [ + // Informational 1xx + 100 => 'Continue', + 101 => 'Switching Protocols', + // Success 2xx + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + // Redirection 3xx + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Moved Temporarily ', // 1.1 + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + // 306 is deprecated but reserved + 307 => 'Temporary Redirect', + // Client Error 4xx + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + // Server Error 5xx + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 509 => 'Bandwidth Limit Exceeded', + ]; /** * 发送数据到客户端 - * @access protected - * @param mixed $data 要返回的数据 - * @param String $type 返回数据格式 + * @access public + * @param mixed $data 数据 + * @param string $type 返回类型 * @param bool $return 是否返回数据 * @return mixed */ - public static function send($data = '', $type = '', $return = false) + public static function send($data = [], $type = '', $return = false) { - $type = strtolower($type ?: self::$type); - - $headers = [ - 'json' => 'application/json', - 'xml' => 'text/xml', - 'html' => 'text/html', - 'jsonp' => 'application/javascript', - 'script' => 'application/javascript', - 'text' => 'text/plain', - ]; - - if (!headers_sent() && isset($headers[$type])) { - header('Content-Type:' . $headers[$type] . '; charset=utf-8'); + if ('' == $type) { + $type = self::$type ?: (IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type')); } $data = $data ?: self::$data; + + if (!headers_sent() && isset(self::$contentType[$type])) { + header('Content-Type:' . self::$contentType[$type] . '; charset=utf-8'); + } + if (is_callable(self::$transform)) { $data = call_user_func_array(self::$transform, [$data]); } else { @@ -82,38 +135,35 @@ class Response * 转换控制器输出的数据 * @access public * @param mixed $callback 调用的转换方法 - * @return void + * @return $this */ public static function transform($callback) { self::$transform = $callback; } + /** + * 输出数据设置 + * @access public + * @param mixed $data 输出数据 + * @return $this + */ + public static function data($data) + { + self::$data = $data; + } + /** * 输出类型设置 * @access public * @param string $type 输出内容的格式类型 * @return mixed */ - public static function type($type = null) + public static function type($type) { - if (is_null($type)) { - return self::$type ?: (IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type')); - } self::$type = $type; } - /** - * 输出数据设置 - * @access public - * @param mixed $data 输出数据 - * @return void - */ - public static function data($data) - { - self::$data = $data; - } - /** * 输出是否exit设置 * @access public @@ -134,7 +184,6 @@ class Response * @param mixed $data 要返回的数据 * @param integer $code 返回的code * @param string $msg 提示信息 - * @param string $type 返回数据格式 * @return mixed */ public static function result($data, $code = 0, $msg = '', $type = '') @@ -145,78 +194,7 @@ class Response 'time' => NOW_TIME, 'data' => $data, ]; - if ($type) { - self::type($type); - } - - return $result; - } - - /** - * 操作成功跳转的快捷方法 - * @access public - * @param mixed $msg 提示信息 - * @param mixed $data 返回的数据 - * @param string $url 跳转的URL地址 - * @param integer $wait 跳转等待时间 - * @return mixed - */ - public static function success($msg = '', $data = '', $url = null, $wait = 3) - { - $code = 1; - if (is_numeric($msg)) { - $code = $msg; - $msg = ''; - } - $result = [ - 'code' => $code, - 'msg' => $msg, - 'data' => $data, - 'url' => is_null($url) && isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $url, - 'wait' => $wait, - ]; - - $type = IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type'); - - if ('html' == $type) { - $result = View::instance(Config::get('template'), Config::get('view_replace_str')) - ->fetch(Config::get('dispatch_success_tmpl'), $result); - } - self::type($type); - return $result; - } - - /** - * 操作错误跳转的快捷方法 - * @access public - * @param mixed $msg 提示信息 - * @param mixed $data 返回的数据 - * @param string $url 跳转的URL地址 - * @param integer $wait 跳转等待时间 - * @return mixed - */ - public static function error($msg = '', $data = '', $url = null, $wait = 3) - { - $code = 0; - if (is_numeric($msg)) { - $code = $msg; - $msg = ''; - } - $result = [ - 'code' => $code, - 'msg' => $msg, - 'data' => $data, - 'url' => is_null($url) ? 'javascript:history.back(-1);' : $url, - 'wait' => $wait, - ]; - - $type = IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type'); - - if ('html' == $type) { - $result = View::instance(Config::get('template'), Config::get('view_replace_str')) - ->fetch(Config::get('dispatch_error_tmpl'), $result); - } - self::type($type); + self::$type = $type; return $result; } @@ -255,61 +233,12 @@ class Response * @param integer $code 状态码 * @return void */ - public static function sendHttpStatus($code) + public static function code($code) { - static $_status = [ - // Informational 1xx - 100 => 'Continue', - 101 => 'Switching Protocols', - // Success 2xx - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - // Redirection 3xx - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Moved Temporarily ', // 1.1 - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - // 306 is deprecated but reserved - 307 => 'Temporary Redirect', - // Client Error 4xx - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - // Server Error 5xx - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - 509 => 'Bandwidth Limit Exceeded', - ]; - if (isset($_status[$code])) { - header('HTTP/1.1 ' . $code . ' ' . $_status[$code]); + if (isset(self::$statusCode[$code])) { + header('HTTP/1.1 ' . $code . ' ' . self::$statusCode[$code]); // 确保FastCGI模式下正常 - header('Status:' . $code . ' ' . $_status[$code]); + header('Status:' . $code . ' ' . self::$statusCode[$code]); } } } diff --git a/library/traits/controller/Jump.php b/library/traits/controller/Jump.php index 5e83493e..c6a3a243 100644 --- a/library/traits/controller/Jump.php +++ b/library/traits/controller/Jump.php @@ -14,36 +14,76 @@ */ namespace traits\controller; +use think\Config; use think\Response; +use think\View; trait Jump { - /** - * 操作错误跳转的快捷方法 - * @access public - * @param mixed $msg 提示信息 - * @param string $url 跳转的URL地址 - * @param mixed $data 返回的数据 - * @param integer $wait 跳转等待时间 - * @return mixed - */ - public function error($msg = '', $url = null, $data = '', $wait = 3) - { - return Response::error($msg, $data, $url, $wait); - } - /** * 操作成功跳转的快捷方法 * @access public * @param mixed $msg 提示信息 - * @param string $url 跳转的URL地址 * @param mixed $data 返回的数据 + * @param string $url 跳转的URL地址 * @param integer $wait 跳转等待时间 * @return mixed */ - public function success($msg = '', $url = null, $data = '', $wait = 3) + public static function success($msg = '', $data = '', $url = null, $wait = 3) { - return Response::success($msg, $data, $url, $wait); + $code = 1; + if (is_numeric($msg)) { + $code = $msg; + $msg = ''; + } + $result = [ + 'code' => $code, + 'msg' => $msg, + 'data' => $data, + 'url' => is_null($url) && isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $url, + 'wait' => $wait, + ]; + + $type = IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type'); + + if ('html' == $type) { + $result = View::instance(Config::get('template'), Config::get('view_replace_str')) + ->fetch(Config::get('dispatch_success_tmpl'), $result); + } + Response::send($result, $type); + } + + /** + * 操作错误跳转的快捷方法 + * @access public + * @param mixed $msg 提示信息 + * @param mixed $data 返回的数据 + * @param string $url 跳转的URL地址 + * @param integer $wait 跳转等待时间 + * @return mixed + */ + public static function error($msg = '', $data = '', $url = null, $wait = 3) + { + $code = 0; + if (is_numeric($msg)) { + $code = $msg; + $msg = ''; + } + $result = [ + 'code' => $code, + 'msg' => $msg, + 'data' => $data, + 'url' => is_null($url) ? 'javascript:history.back(-1);' : $url, + 'wait' => $wait, + ]; + + $type = IS_AJAX ? Config::get('default_ajax_return') : Config::get('default_return_type'); + + if ('html' == $type) { + $result = View::instance(Config::get('template'), Config::get('view_replace_str')) + ->fetch(Config::get('dispatch_error_tmpl'), $result); + } + Response::send($result, $type); } /** diff --git a/tests/thinkphp/library/think/responseTest.php b/tests/thinkphp/library/think/responseTest.php index 55702e02..f2b5d6a6 100644 --- a/tests/thinkphp/library/think/responseTest.php +++ b/tests/thinkphp/library/think/responseTest.php @@ -129,10 +129,6 @@ class responseTest extends \PHPUnit_Framework_TestCase { $type = "json"; Response::type($type); - - $result = Response::type(); - $this->assertEquals($type, $result); - Response::type($type); } /** @@ -176,108 +172,6 @@ class responseTest extends \PHPUnit_Framework_TestCase $this->assertEquals($msg, $result["msg"]); $this->assertEquals($data, $result["data"]); $this->assertEquals($_SERVER['REQUEST_TIME'], $result["time"]); - $this->assertEquals($type, Response::type()); - } - - /** - * @covers think\Response::success - * @todo Implement testSuccess(). - */ - public function testSuccess() - { - // round 1 - $msg = 1001; - $data = "data"; - - $url = "www.HTTP_REFERER.com"; - if (isset($_SERVER["HTTP_REFERER"])) { - $HTTP_REFERER = $_SERVER["HTTP_REFERER"]; - } - $_SERVER["HTTP_REFERER"] = $url; - Config::set('default_return_type', "json"); - - $result = Response::success($msg, $data); - - $this->assertEquals($msg, $result["code"]); - - $this->assertEquals($data, $result["data"]); - $this->assertEquals($url, $result["url"]); - $this->assertEquals("json", Response::type()); - $this->assertEquals(3, $result["wait"]); - - // round 2 - $msg = "the msg"; - $url = "www.thinkphptestsucess.com"; - - $result = Response::success($msg, $data, $url); - - $this->assertEquals($msg, $result["msg"]); - $this->assertEquals($url, $result["url"]); - - // round 3 异常在travis-ci中未能重现 - // $this->setExpectedException('\think\Exception'); - // FIXME 静态方法mock - // $oMockView = $this->getMockBuilder('\think\View')->setMethods(array( - // 'fetch' - // ))->getMock(); - - // $oMockView->expects($this->any())->method('fetch')->will($this->returnValue('content')); - - // Config::set('default_return_type', "html"); - // $result = Response::success($msg, $data, $url); - - // FIXME 静态方法mock - // $this->assertEquals('content', $result); - if (isset($HTTP_REFERER)) { - $_SERVER["HTTP_REFERER"] = $HTTP_REFERER; - } - - } - - /** - * @covers think\Response::error - * @todo Implement testError(). - */ - public function testError() - { - // round 1 - $msg = 1001; - $data = "data"; - - Config::set('default_return_type', "json"); - - $result = Response::error($msg, $data); - - $this->assertEquals($msg, $result["code"]); - $this->assertEquals($data, $result["data"]); - $this->assertEquals('javascript:history.back(-1);', $result["url"]); - $this->assertEquals("json", Response::type()); - $this->assertEquals(3, $result["wait"]); - - // round 2 - $msg = "the msg"; - $url = "www.thinkphptesterror.com"; - - $result = Response::error($msg, $data, $url); - - $this->assertEquals($msg, $result["msg"]); - $this->assertEquals($url, $result["url"]); - - // round 3 异常在travis-ci中未能重现 - // $this->setExpectedException('\think\Exception'); - // FIXME 静态方法mock - // $oMockView = $this->getMockBuilder('\think\View')->setMethods(array( - // 'fetch' - // ))->getMock(); - - // $oMockView->expects($this->any())->method('fetch')->will($this->returnValue('content')); - - // Config::set('default_return_type', "html"); - - // $result = Response::error($msg, $data, $url); - - // FIXME 静态方法mock - // $this->assertEquals('content', $result); } /**