Response.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. namespace Qii\Base;
  3. class Response
  4. {
  5. /**
  6. * Default body name
  7. */
  8. const DEFAULT_BODY = 'html';
  9. const FORMAT_JSON = 'json';
  10. const FORMAT_HTML = 'html';
  11. /**
  12. * Body content
  13. * @var array
  14. */
  15. protected $body = array();
  16. /**
  17. * data
  18. * @param array $data
  19. */
  20. protected $data = array();
  21. /**
  22. * Array of headers. Each header is an array with keys 'name' and 'value'
  23. * @var array
  24. */
  25. protected $headers = array();
  26. /**
  27. * Determine to send the headers or not
  28. * @var unknown_type
  29. */
  30. protected $_sendHeader = false;
  31. public function __construct($data = array())
  32. {
  33. $this->data = $data;
  34. }
  35. /**
  36. * Append content to the body content
  37. *
  38. * @param string $content
  39. * @param string $key
  40. * @return Qii_Response_Abstract
  41. */
  42. public function appendBody($body, $key = NULL)
  43. {
  44. if (!strlen($key)) {
  45. $key = self::DEFAULT_BODY;
  46. }
  47. if (!isset($this->body[$key])) {
  48. $this->body[$key] = '';
  49. }
  50. $this->body[$key] .= (string) $body;
  51. return $this;
  52. }
  53. /**
  54. * Clear the entire body
  55. *
  56. * @param string $key
  57. * @return boolean
  58. */
  59. public function clearBody($key = NULL)
  60. {
  61. if (strlen($key)) {
  62. if (array_key_exists($key, $this->body)) {
  63. unset($this->body[$key]);
  64. }
  65. } else {
  66. $this->body = array();
  67. }
  68. return true;
  69. }
  70. /**
  71. * Clear headers
  72. *
  73. * @return Qii\Response\Abstract
  74. */
  75. public function clearHeaders()
  76. {
  77. $this->headers = array();
  78. return $this;
  79. }
  80. /**
  81. * Return the body content
  82. *
  83. * @param string $key
  84. * @return string
  85. */
  86. public function getBody($key = NULL)
  87. {
  88. if (!strlen($key)) {
  89. $key = self::DEFAULT_BODY;
  90. }
  91. return array_key_exists($key, $this->body) ? $this->body[$key] : null;
  92. }
  93. /**
  94. * Return array of headers; see {@link $headers} for format
  95. *
  96. * @return array
  97. */
  98. public function getHeader()
  99. {
  100. return $this->headers;
  101. }
  102. /**
  103. * Prepend content the body
  104. *
  105. * @param string $body
  106. * @param string $key
  107. * @return Qii_Response_Abstract
  108. */
  109. public function prependBody($body, $key = null)
  110. {
  111. if (!strlen($key)) {
  112. $key = self::DEFAULT_BODY;
  113. }
  114. if (!isset($this->body[$key])) {
  115. $this->body[$key] = '';
  116. }
  117. $this->body[$key] = $body . $this->body[$key];
  118. return $this;
  119. }
  120. /**
  121. * Send the response, including all headers
  122. *
  123. * @return void
  124. */
  125. public function response()
  126. {
  127. if($this->data && isset($this->data['body']))
  128. {
  129. switch($this->data['format'])
  130. {
  131. case self::FORMAT_JSON:
  132. $this->setHeader('Content-Type', 'text/json');
  133. $this->sendHeaders();
  134. echo json_encode($this->data['body'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
  135. break;
  136. default:
  137. echo $this->body;
  138. break;
  139. }
  140. return;
  141. }
  142. if ($this->_sendHeader == true) {
  143. $this->sendHeaders();
  144. }
  145. foreach ($this->body as $key => $body) {
  146. echo $body;
  147. }
  148. }
  149. public function setAllHeaders()
  150. {
  151. return false;
  152. }
  153. /**
  154. * Set body content
  155. *
  156. * @param string $body
  157. * @param string $key
  158. * @return Qii_Response_Abstract
  159. */
  160. public function setBody($body, $key = NULL)
  161. {
  162. if (!strlen($key)) {
  163. $key = self::DEFAULT_BODY;
  164. }
  165. $this->body[$key] = (string) $body;
  166. return $this;
  167. }
  168. /**
  169. * Set a header
  170. *
  171. * If $replace is true, replaces any headers already defined with that
  172. * $name.
  173. *
  174. * @param string $name
  175. * @param string $value
  176. * @param boolean $replace
  177. * @return Qii_Response_Abstract
  178. */
  179. public function setHeader($name, $value, $replace = false)
  180. {
  181. $name = $this->_normalizeHeader($name);
  182. $value = (string) $value;
  183. if ($replace) {
  184. foreach ($this->headers as $key => $header) {
  185. if ($name == $header['name']) {
  186. unset($this->headers[$key]);
  187. }
  188. }
  189. }
  190. $this->headers[] = array(
  191. 'name' => $name,
  192. 'value' => $value,
  193. 'replace' => $replace
  194. );
  195. return $this;
  196. }
  197. /**
  198. * Set redirect URL
  199. *
  200. * Sets Location header. Forces replacement of any prior redirects.
  201. *
  202. * @param string $url
  203. * @return Qii_Response_Abstract
  204. */
  205. public function setRedirect($url)
  206. {
  207. $this->setHeader('Location', $url, true);
  208. return $this;
  209. }
  210. /**
  211. * Magic __toString functionality
  212. *
  213. * Returns response value as string
  214. * using output buffering.
  215. *
  216. * @return string
  217. */
  218. public function __toString()
  219. {
  220. ob_start();
  221. $this->response();
  222. return ob_get_clean();
  223. }
  224. /**
  225. * Normalize a header name
  226. *
  227. * Normalizes a header name to X-Capitalized-Names
  228. *
  229. * @param string $name
  230. * @return string
  231. */
  232. protected function _normalizeHeader($name)
  233. {
  234. $filtered = str_replace(array('-', '_'), ' ', (string) $name);
  235. $filtered = ucwords(strtolower($filtered));
  236. $filtered = str_replace(' ', '-', $filtered);
  237. return $filtered;
  238. }
  239. /**
  240. * Send all headers
  241. *
  242. * Sends any headers specified.
  243. * If an {@link setHttpResponseCode() HTTP response code}
  244. * has been specified, it is sent with the first header.
  245. *
  246. * @return Qii_Response_Abstract
  247. */
  248. protected function sendHeaders()
  249. {
  250. foreach ($this->headers as $header) {
  251. header(
  252. $header['name'] . ': ' . $header['value'],
  253. $header['replace']
  254. );
  255. }
  256. return $this;
  257. }
  258. }