PageRenderTime 66ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/README.md

https://gitlab.com/payam/ext-request
Markdown | 454 lines | 332 code | 122 blank | 0 comment | 0 complexity | 815d7830863e7bfc0118dddb4ec0a46b MD5 | raw file
  1. # ext/request
  2. This extension provides server-side request and response objects for PHP.
  3. These are *not* HTTP message objects proper. They are more like wrappers
  4. for existing global PHP variables and functions, with some limited
  5. additional convenience functionality.
  6. This extension defines two classes in the global namespace:
  7. - ServerRequest, composed of read-only copies of PHP superglobals and some
  8. other commonly-used values, with methods for adding application-specific
  9. request information in immutable fashion.
  10. - ServerResponse, essentially a wrapper around (and buffer for) response-
  11. related PHP functions, with some additional convenience methods, and self-
  12. sending capability.
  13. ## ServerRequest
  14. An object representing the PHP request received by the server; use it in place
  15. of the `$_GET`, `$_POST`, etc. superglobals. It provides:
  16. - non-session superglobals as read-only properties;
  17. - other read-only properties calculated from the superglobals (`$method`,
  18. `$headers`, `$content`, `$accept`, `$uploads`, etc.);
  19. - immutable retention of application-specific information, such as parsed body
  20. input and routing parameters;
  21. - extensibility.
  22. ### Instantiation
  23. Instantiation of _ServerRequest_ is straightforward:
  24. ```php
  25. <?php
  26. $request = new ServerRequest();
  27. ?>
  28. ```
  29. The _ServerRequest_ object builds itself from the PHP superglobals. If you want
  30. to provide custom values in place of the superglobals, pass an array that mimics
  31. `$GLOBALS` to the constructor:
  32. ```php
  33. <?php
  34. $request = new ServerRequest([
  35. '_SERVER' => [
  36. 'foo' => 'bar',
  37. ],
  38. ]);
  39. ?>
  40. ```
  41. If a superglobal is represented in the array of custom values, it will be used
  42. instead of the real superglobal. If it is not represented in the array,
  43. _ServerRequest_ will use the real superglobal.
  44. ### Properties
  45. _ServerRequest_ has these public properties.
  46. #### Superglobal-related
  47. These properties are read-only and cannot be modified.
  48. - `$env`: A copy of `$_ENV`.
  49. - `$files`: A copy of `$_FILES`.
  50. - `$get`: A copy of `$_GET`.
  51. - `$cookie`: A copy of `$_COOKIE`.
  52. - `$post`: A copy of `$_POST`.
  53. - `$server`: A copy of `$_SERVER`.
  54. - `$uploads`: A copy of `$_FILES`, restructured to look more like `$_POST`.
  55. #### HTTP-related
  56. These properties are read-only and cannot be modified.
  57. - `$accept`: An array computed from `$_SERVER['HTTP_ACCEPT']`.
  58. - `$acceptCharset`: An array computed from `$_SERVER['HTTP_ACCEPT_CHARSET']`.
  59. - `$acceptEncoding`: An array computed from `$_SERVER['HTTP_ACCEPT_ENCODING']`.
  60. - `$acceptLanguage`: An array computed from `$_SERVER['HTTP_ACCEPT_LANGUAGE']`.
  61. - `$headers`: An array of all `HTTP_*` header keys from `$_SERVER`, plus RFC
  62. 3875 headers not prefixed with `HTTP_`.
  63. - `$method`: The `$_SERVER['REQUEST_METHOD']` value, or the
  64. `$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']` when appropriate.
  65. - `$xhr`: A boolean indicating if this is an XmlHttpRequest.
  66. Each element of the `$accept*` arrays has these sub-array keys:
  67. ```
  68. 'value' => The "main" value of the accept specifier
  69. 'quality' => The 'q=' parameter value
  70. 'params' => A key-value array of all other parameters
  71. ```
  72. In addition, each `$acceptLanguage` array element has two additional sub-array
  73. keys: `'type'` and `'subtype'`.
  74. The `$accept*` array elements are sorted by highest `q` value to lowest.
  75. #### Content-related
  76. These properties are read-only and cannot be modified.
  77. - `$content`: The value of `file_get_contents('php://input')`.
  78. - `$contentCharset`: The `charset` parameter value of `$_SERVER['CONTENT_TYPE']`.
  79. - `$contentLength`: The value of `$_SERVER['CONTENT_LENGTH']`.
  80. - `$contentMd5`: The value of `$_SERVER['HTTP_CONTENT_MD5']`.
  81. - `$contentType`: The value of `$_SERVER['CONTENT_TYPE']`, minus any parameters.
  82. #### Authentication-related
  83. These properties are read-only and cannot be modified.
  84. - `$authDigest`: An array of digest values computed from
  85. `$_SERVER['PHP_AUTH_DIGEST']`.
  86. - `$authPw`: The value of `$_SERVER['PHP_AUTH_PW']`.
  87. - `$authType`: The value of `$_SERVER['PHP_AUTH_TYPE']`.
  88. - `$authUser`: The value of `$_SERVER['PHP_AUTH_USER']`.
  89. #### Application-related
  90. These property values are "immutable" rather than read-only. That is, they can
  91. changed using the methods below, but the changed values are available only on a
  92. new instance of the _ServerRequest_ as returned by the method.
  93. - `$input`: Typically the parsed body content of the request, such as from
  94. `json_decode()`.
  95. - `$params`: Typically path-info or routing parameters.
  96. - `$url`: The result of [`parse_url`](http://php.net/parse_url) as built from
  97. the `$_SERVER` keys `HTTPS`, `HTTP_HOST`/`SERVER_NAME`, `SERVER_PORT`, and
  98. `REQUEST_URI`.
  99. ### Methods
  100. The _ServerRequest_ object has these public methods.
  101. #### `withInput(mixed $input)`
  102. Sets the `$input` value on a clone of the called _ServerRequest_ instance.
  103. For example:
  104. ```php
  105. <?php
  106. $request = new ServerRequest();
  107. if ($request->contentType == 'application/json') {
  108. $input = json_decode($request->content, true);
  109. $request = $request->withInput($input);
  110. }
  111. ?>
  112. ```
  113. Note that this method returns a clone of the _ServerRequest_ instance with the
  114. new property value. It does not modify the property value on the called
  115. instance.
  116. The value may be null, scalar, or array. Arrays are recursively checked to make
  117. sure they contain only null, scalar, or array values; this is to preserve
  118. immutability of the value.
  119. #### `withParam(mixed $key, mixed $val)`
  120. Sets the value of one `$params` key on a clone of the called _ServerRequest_
  121. instance.
  122. For example:
  123. ```php
  124. <?php
  125. $request = new ServerRequest();
  126. var_dump($request->params); // []
  127. $request = $request->withParam('foo', 'bar');
  128. var_dump($request->params); // ['foo' => 'bar']
  129. ?>
  130. ```
  131. Note that this method returns a clone of the _ServerRequest_ instance with the
  132. new property value. It does not modify the property value on the called
  133. instance.
  134. The value may be null, scalar, or array. Arrays are recursively checked to make
  135. sure they contain only null, scalar, or array values; this is to preserve
  136. immutability of the value.
  137. #### `withParams(array $params)`
  138. Sets the `$params` value on a clone of the called _ServerRequest_ instance.
  139. For example:
  140. ```php
  141. <?php
  142. $request = new ServerRequest();
  143. var_dump($request->params); // []
  144. $request = $request->withParams(['foo' => 'bar']);
  145. var_dump($request->params); // ['foo' => 'bar']
  146. ?>
  147. ```
  148. Note that this method returns a clone of the _ServerRequest_ instance with the
  149. new property value. It does not modify the property value on the called
  150. instance.
  151. The value may be null, scalar, or array. Arrays are recursively checked to make
  152. sure they contain only null, scalar, or array values; this is to preserve
  153. immutability of the value.
  154. #### `withoutParam(mixed $key)`
  155. Unsets a single `$params` key on a clone of the called _ServerRequest_ instance.
  156. For example:
  157. ```php
  158. <?php
  159. $request = new ServerRequest();
  160. $request = $request->withParams(['foo' => 'bar', 'baz' => 'dib']);
  161. var_dump($request->params); // ['foo' => 'bar', 'baz' => 'dib']
  162. $request = $request->withoutParam('baz');
  163. var_dump($request->params); // ['foo' => 'bar']
  164. ?>
  165. ```
  166. Note that this method returns a clone of the _ServerRequest_ instance with the
  167. new property value. It does not modify the property value on the called
  168. instance.
  169. #### `withoutParams([array $keys = null])`
  170. Unsets multiple `$params` keys on a clone of the called _ServerRequest_
  171. instance.
  172. For example:
  173. ```php
  174. <?php
  175. $request = new ServerRequest();
  176. $request = $request->withParams([
  177. 'foo' => 'bar',
  178. 'baz' => 'dib',
  179. 'zim' => 'gir',
  180. ]);
  181. var_dump($request->params); // ['foo' => 'bar', 'baz' => 'dib', 'zim' => 'gir']
  182. $request = $request->withoutParams(['baz', 'zim']);
  183. var_dump($request->params); // ['foo' => 'bar']
  184. ?>
  185. ```
  186. Calling `withoutParams()` with no arguments removes all `$params` on a clone of
  187. the called _ServerRequest_ instance:
  188. ```php
  189. <?php
  190. $request = new ServerRequest();
  191. $request = $request->withParams([
  192. 'foo' => 'bar',
  193. 'baz' => 'dib',
  194. 'zim' => 'gir',
  195. ]);
  196. var_dump($request->params); // ['foo' => 'bar', 'baz' => 'dib', 'zim' => 'gir']
  197. $request = $request->withoutParams();
  198. var_dump($request->params); // []
  199. ?>
  200. ```
  201. Note that this method returns a clone of the _ServerRequest_ instance with the
  202. new property value. It does not modify the property value on the called
  203. instance.
  204. #### `withUrl(array $url)`
  205. Sets the value of the `$url` array on a clone of the called _ServerRequest_
  206. instance.
  207. For example:
  208. ```php
  209. <?php
  210. $request = new ServerRequest();
  211. $request = $request->withUrl([
  212. 'scheme' => 'https',
  213. 'host' => 'example.com',
  214. 'port' => 8080,
  215. 'path' => '/foo/bar',
  216. 'query' => 'baz=dib',
  217. ]);
  218. var_dump($request->url);
  219. /* [
  220. 'scheme' => 'https',
  221. 'host' => 'example.com',
  222. 'port' => 8080,
  223. 'user' => null,
  224. 'pass' => null,
  225. 'path' => '/foo/bar',
  226. 'query' => 'baz=dib',
  227. 'fragment' => null,
  228. ] */
  229. ?>
  230. ```
  231. Note that this method returns a clone of the _ServerRequest_ instance with the
  232. new property value. It does not modify the property value on the called
  233. instance.
  234. ## ServerResponse
  235. An object representing the PHP response to be sent from the server; use it in
  236. place of the `header()`, `setcookie()`, `setrawcookie()`, etc. functions. It
  237. provides:
  238. - a retention space for headers, cookies, and status, so they can be inspected
  239. before sending;
  240. - a helper method for building HTTP date strings;
  241. - a helper for building header comma- and semicolon-separated strings for headers;
  242. - support for specifying content as a download (with appropriate headers);
  243. - support for specifying content as JSON (with appropriate headers);
  244. - self-sending capability;
  245. - mutability and extensibility.
  246. ## Instantiation
  247. Instantation is straightforward:
  248. ```php
  249. <?php
  250. $response = new ServerResponse();
  251. ?>
  252. ```
  253. ### Properties
  254. _ServerResponse_ has no public properties.
  255. ### Methods
  256. _ServerResponse_ has these public methods.
  257. #### HTTP Version
  258. - `setVersion($version)`: Sets the HTTP version for the response (typically
  259. '1.0' or '1.1').
  260. - `getVersion()`: Returns the HTTP version for the response.
  261. #### Status Code
  262. - `setStatus($status)`: Sets the HTTP response code; a buffered equivalent of
  263. `http_response_code($status)`.
  264. - `getStatus()`: Gets the HTTP response code.
  265. #### Headers
  266. - `setHeader($label, $value)`: Overwrites an HTTP header; a buffered equivalent
  267. of `header("$label: $value", true)`.
  268. - `addHeader($label, $value)`: Appends to an HTTP header, comma-separating it
  269. from the existing value; a buffered equivalent of
  270. `header("$label: $value", false)`.
  271. - `getHeader($label)`: Returns the value for a particular header.
  272. - `getHeaders()`: Returns the array of headers to be sent.
  273. - `date($date)`: Returns a RFC 1123 formatted date. The `$date` argument can be
  274. any recognizable date-time string, or a _DateTime_ object.
  275. Notes:
  276. The `$value` in a `setHeader()` or `addHeader()` call may be an array, in which
  277. case it will be converted to a comma-separated and/or semicolon-separated value
  278. string. For example:
  279. ```php
  280. <?php
  281. $response = new ServerResponse();
  282. $response->setHeader('Cache-Control', [
  283. 'public',
  284. 'max-age' => '123',
  285. 's-maxage' => '456',
  286. 'no-cache',
  287. ]); // Cache-Control: public, max-age=123, s-maxage=456, no-cache
  288. $response->setHeader('content-type', [
  289. 'text/plain' => [
  290. 'charset' => 'utf-8'
  291. ],
  292. ]); // content-type: text/plain;charset=utf-8
  293. $response->setHeader('X-Whatever', [
  294. 'foo',
  295. 'bar' => [
  296. 'baz' => 'dib',
  297. 'zim',
  298. 'gir' => 'irk',
  299. ],
  300. 'qux' => 'quux',
  301. ]); // X-Whatever: foo, bar;baz=dib;zim;gir=irk, qux=quux
  302. ```
  303. Finally, the header field labels are retained internally in lower-case, and are
  304. sent as lower-case. This is to
  305. [comply with HTTP/2 requirements](https://tools.ietf.org/html/rfc7540#section-8.1.2);
  306. while HTTP/1.x has no such requirement, lower-case is also recognized as valid.
  307. #### Cookies
  308. - `setCookie(...)`: A buffered equivalent of [`setcookie()`](http://php.net/setcookie)
  309. with identical arguments.
  310. - `setRawCookie(...)`: A buffered equivalent of [`setrawcookie()`](http://php.net/setrawcookie)
  311. with identical arguments.
  312. - `getCookies()`: Returns the array of cookies to be sent.
  313. #### Content
  314. - `setContent($content)`: Sets the content of the response. This may be a
  315. string, resource, object, or anything else.
  316. - `setContentJson($value, $options = 0, $depth = 512)`: A convenience method to
  317. `json_encode($value)` as the response content, and set a
  318. `content-type: application/json` header.
  319. - `setContentDownload($fh, $name, $disposition = 'attachment', array $params = [])`:
  320. A convenience method to set the content to a resource (typically a file handle)
  321. for download to the client. This sets the headers
  322. `content-type: application/octet-stream`, `content-transfer-encoding: binary`,
  323. and `content-disposition: $disposition;filename="$name"`. (The `$params`
  324. key-value array are included as parameters on the disposition.)
  325. - `getContent()`: Returns the content of the response. This may be a string,
  326. resource, object, or anything else.
  327. #### Sending
  328. - `send()`: This sends the response version, status, headers, and cookies using
  329. native PHP functions `header()`, `setcookie()`, and `setrawcookie()`. Then,
  330. if the response content is a resource, it is sent with `fpassthru()`; if a
  331. callable object or closure, it is invoked; otherwise, the content is `echo`ed
  332. (which calls `__toString()` if the content is an object).