| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 | <?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK ]// +----------------------------------------------------------------------// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: liu21st <liu21st@gmail.com>// +----------------------------------------------------------------------namespace think;use think\response\Redirect as RedirectResponse;class Response{    /**     * 原始数据     * @var mixed     */    protected $data;    /**     * 应用对象实例     * @var App     */    protected $app;    /**     * 当前contentType     * @var string     */    protected $contentType = 'text/html';    /**     * 字符集     * @var string     */    protected $charset = 'utf-8';    /**     * 状态码     * @var integer     */    protected $code = 200;    /**     * 是否允许请求缓存     * @var bool     */    protected $allowCache = true;    /**     * 输出参数     * @var array     */    protected $options = [];    /**     * header参数     * @var array     */    protected $header = [];    /**     * 输出内容     * @var string     */    protected $content = null;    /**     * 架构函数     * @access public     * @param  mixed $data    输出数据     * @param  int   $code     * @param  array $header     * @param  array $options 输出参数     */    public function __construct($data = '', $code = 200, array $header = [], $options = [])    {        $this->data($data);        if (!empty($options)) {            $this->options = array_merge($this->options, $options);        }        $this->contentType($this->contentType, $this->charset);        $this->code   = $code;        $this->app    = Container::get('app');        $this->header = array_merge($this->header, $header);    }    /**     * 创建Response对象     * @access public     * @param  mixed  $data    输出数据     * @param  string $type    输出类型     * @param  int    $code     * @param  array  $header     * @param  array  $options 输出参数     * @return Response     */    public static function create($data = '', $type = '', $code = 200, array $header = [], $options = [])    {        $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type));        if (class_exists($class)) {            return new $class($data, $code, $header, $options);        }        return new static($data, $code, $header, $options);    }    /**     * 发送数据到客户端     * @access public     * @return void     * @throws \InvalidArgumentException     */    public function send()    {        // 监听response_send        $this->app['hook']->listen('response_send', $this);        // 处理输出数据        $data = $this->getContent();        // Trace调试注入        if ('cli' != PHP_SAPI && $this->app['env']->get('app_trace', $this->app->config('app.app_trace'))) {            $this->app['debug']->inject($this, $data);        }        if (200 == $this->code && $this->allowCache) {            $cache = $this->app['request']->getCache();            if ($cache) {                $this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate';                $this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';                $this->header['Expires']       = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT';                $this->app['cache']->tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]);            }        }        if (!headers_sent() && !empty($this->header)) {            // 发送状态码            http_response_code($this->code);            // 发送头部信息            foreach ($this->header as $name => $val) {                header($name . (!is_null($val) ? ':' . $val : ''));            }        }        $this->sendData($data);        if (function_exists('fastcgi_finish_request')) {            // 提高页面响应            fastcgi_finish_request();        }        // 监听response_end        $this->app['hook']->listen('response_end', $this);        // 清空当次请求有效的数据        if (!($this instanceof RedirectResponse)) {            $this->app['session']->flush();        }    }    /**     * 处理数据     * @access protected     * @param  mixed $data 要处理的数据     * @return mixed     */    protected function output($data)    {        return $data;    }    /**     * 输出数据     * @access protected     * @param string $data 要处理的数据     * @return void     */    protected function sendData($data)    {        echo $data;    }    /**     * 输出的参数     * @access public     * @param  mixed $options 输出参数     * @return $this     */    public function options($options = [])    {        $this->options = array_merge($this->options, $options);        return $this;    }    /**     * 输出数据设置     * @access public     * @param  mixed $data 输出数据     * @return $this     */    public function data($data)    {        $this->data = $data;        return $this;    }    /**     * 是否允许请求缓存     * @access public     * @param  bool $cache 允许请求缓存     * @return $this     */    public function allowCache($cache)    {        $this->allowCache = $cache;        return $this;    }    /**     * 设置响应头     * @access public     * @param  string|array $name  参数名     * @param  string       $value 参数值     * @return $this     */    public function header($name, $value = null)    {        if (is_array($name)) {            $this->header = array_merge($this->header, $name);        } else {            $this->header[$name] = $value;        }        return $this;    }    /**     * 设置页面输出内容     * @access public     * @param  mixed $content     * @return $this     */    public function content($content)    {        if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([            $content,            '__toString',        ])        ) {            throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content)));        }        $this->content = (string) $content;        return $this;    }    /**     * 发送HTTP状态     * @access public     * @param  integer $code 状态码     * @return $this     */    public function code($code)    {        $this->code = $code;        return $this;    }    /**     * LastModified     * @access public     * @param  string $time     * @return $this     */    public function lastModified($time)    {        $this->header['Last-Modified'] = $time;        return $this;    }    /**     * Expires     * @access public     * @param  string $time     * @return $this     */    public function expires($time)    {        $this->header['Expires'] = $time;        return $this;    }    /**     * ETag     * @access public     * @param  string $eTag     * @return $this     */    public function eTag($eTag)    {        $this->header['ETag'] = $eTag;        return $this;    }    /**     * 页面缓存控制     * @access public     * @param  string $cache 缓存设置     * @return $this     */    public function cacheControl($cache)    {        $this->header['Cache-control'] = $cache;        return $this;    }    /**     * 设置页面不做任何缓存     * @access public     * @return $this     */    public function noCache()    {        $this->header['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0';        $this->header['Pragma']        = 'no-cache';        return $this;    }    /**     * 页面输出类型     * @access public     * @param  string $contentType 输出类型     * @param  string $charset     输出编码     * @return $this     */    public function contentType($contentType, $charset = 'utf-8')    {        $this->header['Content-Type'] = $contentType . '; charset=' . $charset;        return $this;    }    /**     * 获取头部信息     * @access public     * @param  string $name 头部名称     * @return mixed     */    public function getHeader($name = '')    {        if (!empty($name)) {            return isset($this->header[$name]) ? $this->header[$name] : null;        }        return $this->header;    }    /**     * 获取原始数据     * @access public     * @return mixed     */    public function getData()    {        return $this->data;    }    /**     * 获取输出数据     * @access public     * @return mixed     */    public function getContent()    {        if (null == $this->content) {            $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)));            }            $this->content = (string) $content;        }        return $this->content;    }    /**     * 获取状态码     * @access public     * @return integer     */    public function getCode()    {        return $this->code;    }    public function __debugInfo()    {        $data = get_object_vars($this);        unset($data['app']);        return $data;    }}
 |