Response.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2021 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace think;
  13. /**
  14. * 响应输出基础类
  15. * @package think
  16. */
  17. abstract class Response
  18. {
  19. /**
  20. * 原始数据
  21. * @var mixed
  22. */
  23. protected $data;
  24. /**
  25. * 当前contentType
  26. * @var string
  27. */
  28. protected $contentType = 'text/html';
  29. /**
  30. * 字符集
  31. * @var string
  32. */
  33. protected $charset = 'utf-8';
  34. /**
  35. * 状态码
  36. * @var integer
  37. */
  38. protected $code = 200;
  39. /**
  40. * 是否允许请求缓存
  41. * @var bool
  42. */
  43. protected $allowCache = true;
  44. /**
  45. * 输出参数
  46. * @var array
  47. */
  48. protected $options = [];
  49. /**
  50. * header参数
  51. * @var array
  52. */
  53. protected $header = [];
  54. /**
  55. * 输出内容
  56. * @var string
  57. */
  58. protected $content = null;
  59. /**
  60. * Cookie对象
  61. * @var Cookie
  62. */
  63. protected $cookie;
  64. /**
  65. * Session对象
  66. * @var Session
  67. */
  68. protected $session;
  69. /**
  70. * 初始化
  71. * @access protected
  72. * @param mixed $data 输出数据
  73. * @param int $code 状态码
  74. */
  75. protected function init($data = '', int $code = 200)
  76. {
  77. $this->data($data);
  78. $this->code = $code;
  79. $this->contentType($this->contentType, $this->charset);
  80. }
  81. /**
  82. * 创建Response对象
  83. * @access public
  84. * @param mixed $data 输出数据
  85. * @param string $type 输出类型
  86. * @param int $code 状态码
  87. * @return Response
  88. */
  89. public static function create($data = '', string $type = 'html', int $code = 200): Response
  90. {
  91. $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type));
  92. return Container::getInstance()->invokeClass($class, [$data, $code]);
  93. }
  94. /**
  95. * 设置Session对象
  96. * @access public
  97. * @param Session $session Session对象
  98. * @return $this
  99. */
  100. public function setSession(Session $session)
  101. {
  102. $this->session = $session;
  103. return $this;
  104. }
  105. /**
  106. * 发送数据到客户端
  107. * @access public
  108. * @return void
  109. * @throws \InvalidArgumentException
  110. */
  111. public function send(): void
  112. {
  113. // 处理输出数据
  114. $data = $this->getContent();
  115. if (!headers_sent() && !empty($this->header)) {
  116. // 发送状态码
  117. http_response_code($this->code);
  118. // 发送头部信息
  119. foreach ($this->header as $name => $val) {
  120. header($name . (!is_null($val) ? ':' . $val : ''));
  121. }
  122. }
  123. if ($this->cookie) {
  124. $this->cookie->save();
  125. }
  126. $this->sendData($data);
  127. if (function_exists('fastcgi_finish_request')) {
  128. // 提高页面响应
  129. fastcgi_finish_request();
  130. }
  131. }
  132. /**
  133. * 处理数据
  134. * @access protected
  135. * @param mixed $data 要处理的数据
  136. * @return mixed
  137. */
  138. protected function output($data)
  139. {
  140. return $data;
  141. }
  142. /**
  143. * 输出数据
  144. * @access protected
  145. * @param string $data 要处理的数据
  146. * @return void
  147. */
  148. protected function sendData(string $data): void
  149. {
  150. echo $data;
  151. }
  152. /**
  153. * 输出的参数
  154. * @access public
  155. * @param mixed $options 输出参数
  156. * @return $this
  157. */
  158. public function options(array $options = [])
  159. {
  160. $this->options = array_merge($this->options, $options);
  161. return $this;
  162. }
  163. /**
  164. * 输出数据设置
  165. * @access public
  166. * @param mixed $data 输出数据
  167. * @return $this
  168. */
  169. public function data($data)
  170. {
  171. $this->data = $data;
  172. return $this;
  173. }
  174. /**
  175. * 是否允许请求缓存
  176. * @access public
  177. * @param bool $cache 允许请求缓存
  178. * @return $this
  179. */
  180. public function allowCache(bool $cache)
  181. {
  182. $this->allowCache = $cache;
  183. return $this;
  184. }
  185. /**
  186. * 是否允许请求缓存
  187. * @access public
  188. * @return $this
  189. */
  190. public function isAllowCache()
  191. {
  192. return $this->allowCache;
  193. }
  194. /**
  195. * 设置Cookie
  196. * @access public
  197. * @param string $name cookie名称
  198. * @param string $value cookie值
  199. * @param mixed $option 可选参数
  200. * @return $this
  201. */
  202. public function cookie(string $name, string $value, $option = null)
  203. {
  204. $this->cookie->set($name, $value, $option);
  205. return $this;
  206. }
  207. /**
  208. * 设置响应头
  209. * @access public
  210. * @param array $header 参数
  211. * @return $this
  212. */
  213. public function header(array $header = [])
  214. {
  215. $this->header = array_merge($this->header, $header);
  216. return $this;
  217. }
  218. /**
  219. * 设置页面输出内容
  220. * @access public
  221. * @param mixed $content
  222. * @return $this
  223. */
  224. public function content($content)
  225. {
  226. if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([
  227. $content,
  228. '__toString',
  229. ])
  230. ) {
  231. throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content)));
  232. }
  233. $this->content = (string) $content;
  234. return $this;
  235. }
  236. /**
  237. * 发送HTTP状态
  238. * @access public
  239. * @param integer $code 状态码
  240. * @return $this
  241. */
  242. public function code(int $code)
  243. {
  244. $this->code = $code;
  245. return $this;
  246. }
  247. /**
  248. * LastModified
  249. * @access public
  250. * @param string $time
  251. * @return $this
  252. */
  253. public function lastModified(string $time)
  254. {
  255. $this->header['Last-Modified'] = $time;
  256. return $this;
  257. }
  258. /**
  259. * Expires
  260. * @access public
  261. * @param string $time
  262. * @return $this
  263. */
  264. public function expires(string $time)
  265. {
  266. $this->header['Expires'] = $time;
  267. return $this;
  268. }
  269. /**
  270. * ETag
  271. * @access public
  272. * @param string $eTag
  273. * @return $this
  274. */
  275. public function eTag(string $eTag)
  276. {
  277. $this->header['ETag'] = $eTag;
  278. return $this;
  279. }
  280. /**
  281. * 页面缓存控制
  282. * @access public
  283. * @param string $cache 状态码
  284. * @return $this
  285. */
  286. public function cacheControl(string $cache)
  287. {
  288. $this->header['Cache-control'] = $cache;
  289. return $this;
  290. }
  291. /**
  292. * 页面输出类型
  293. * @access public
  294. * @param string $contentType 输出类型
  295. * @param string $charset 输出编码
  296. * @return $this
  297. */
  298. public function contentType(string $contentType, string $charset = 'utf-8')
  299. {
  300. $this->header['Content-Type'] = $contentType . '; charset=' . $charset;
  301. return $this;
  302. }
  303. /**
  304. * 获取头部信息
  305. * @access public
  306. * @param string $name 头部名称
  307. * @return mixed
  308. */
  309. public function getHeader(string $name = '')
  310. {
  311. if (!empty($name)) {
  312. return $this->header[$name] ?? null;
  313. }
  314. return $this->header;
  315. }
  316. /**
  317. * 获取原始数据
  318. * @access public
  319. * @return mixed
  320. */
  321. public function getData()
  322. {
  323. return $this->data;
  324. }
  325. /**
  326. * 获取输出数据
  327. * @access public
  328. * @return string
  329. */
  330. public function getContent(): string
  331. {
  332. if (null == $this->content) {
  333. $content = $this->output($this->data);
  334. if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([
  335. $content,
  336. '__toString',
  337. ])
  338. ) {
  339. throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content)));
  340. }
  341. $this->content = (string) $content;
  342. }
  343. return $this->content;
  344. }
  345. /**
  346. * 获取状态码
  347. * @access public
  348. * @return integer
  349. */
  350. public function getCode(): int
  351. {
  352. return $this->code;
  353. }
  354. }