Session.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. /**
  3. * Session handler for persistent requests and default parameters
  4. *
  5. * @package Requests
  6. * @subpackage Session Handler
  7. */
  8. /**
  9. * Session handler for persistent requests and default parameters
  10. *
  11. * Allows various options to be set as default values, and merges both the
  12. * options and URL properties together. A base URL can be set for all requests,
  13. * with all subrequests resolved from this. Base options can be set (including
  14. * a shared cookie jar), then overridden for individual requests.
  15. *
  16. * @package Requests
  17. * @subpackage Session Handler
  18. */
  19. class Requests_Session {
  20. /**
  21. * Base URL for requests
  22. *
  23. * URLs will be made absolute using this as the base
  24. * @var string|null
  25. */
  26. public $url = null;
  27. /**
  28. * Base headers for requests
  29. * @var array
  30. */
  31. public $headers = array();
  32. /**
  33. * Base data for requests
  34. *
  35. * If both the base data and the per-request data are arrays, the data will
  36. * be merged before sending the request.
  37. *
  38. * @var array
  39. */
  40. public $data = array();
  41. /**
  42. * Base options for requests
  43. *
  44. * The base options are merged with the per-request data for each request.
  45. * The only default option is a shared cookie jar between requests.
  46. *
  47. * Values here can also be set directly via properties on the Session
  48. * object, e.g. `$session->useragent = 'X';`
  49. *
  50. * @var array
  51. */
  52. public $options = array();
  53. /**
  54. * Create a new session
  55. *
  56. * @param string|null $url Base URL for requests
  57. * @param array $headers Default headers for requests
  58. * @param array $data Default data for requests
  59. * @param array $options Default options for requests
  60. */
  61. public function __construct($url = null, $headers = array(), $data = array(), $options = array()) {
  62. $this->url = $url;
  63. $this->headers = $headers;
  64. $this->data = $data;
  65. $this->options = $options;
  66. if (empty($this->options['cookies'])) {
  67. $this->options['cookies'] = new Requests_Cookie_Jar();
  68. }
  69. }
  70. /**
  71. * Get a property's value
  72. *
  73. * @param string $key Property key
  74. * @return mixed|null Property value, null if none found
  75. */
  76. public function __get($key) {
  77. if (isset($this->options[$key])) {
  78. return $this->options[$key];
  79. }
  80. return null;
  81. }
  82. /**
  83. * Set a property's value
  84. *
  85. * @param string $key Property key
  86. * @param mixed $value Property value
  87. */
  88. public function __set($key, $value) {
  89. $this->options[$key] = $value;
  90. }
  91. /**
  92. * Remove a property's value
  93. *
  94. * @param string $key Property key
  95. */
  96. public function __isset($key) {
  97. return isset($this->options[$key]);
  98. }
  99. /**
  100. * Remove a property's value
  101. *
  102. * @param string $key Property key
  103. */
  104. public function __unset($key) {
  105. if (isset($this->options[$key])) {
  106. unset($this->options[$key]);
  107. }
  108. }
  109. /**#@+
  110. * @see request()
  111. * @param string $url
  112. * @param array $headers
  113. * @param array $options
  114. * @return Requests_Response
  115. */
  116. /**
  117. * Send a GET request
  118. */
  119. public function get($url, $headers = array(), $options = array()) {
  120. return $this->request($url, $headers, null, Requests::GET, $options);
  121. }
  122. /**
  123. * Send a HEAD request
  124. */
  125. public function head($url, $headers = array(), $options = array()) {
  126. return $this->request($url, $headers, null, Requests::HEAD, $options);
  127. }
  128. /**
  129. * Send a DELETE request
  130. */
  131. public function delete($url, $headers = array(), $options = array()) {
  132. return $this->request($url, $headers, null, Requests::DELETE, $options);
  133. }
  134. /**#@-*/
  135. /**#@+
  136. * @see request()
  137. * @param string $url
  138. * @param array $headers
  139. * @param array $data
  140. * @param array $options
  141. * @return Requests_Response
  142. */
  143. /**
  144. * Send a POST request
  145. */
  146. public function post($url, $headers = array(), $data = array(), $options = array()) {
  147. return $this->request($url, $headers, $data, Requests::POST, $options);
  148. }
  149. /**
  150. * Send a PUT request
  151. */
  152. public function put($url, $headers = array(), $data = array(), $options = array()) {
  153. return $this->request($url, $headers, $data, Requests::PUT, $options);
  154. }
  155. /**
  156. * Send a PATCH request
  157. *
  158. * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
  159. * specification recommends that should send an ETag
  160. *
  161. * @link https://tools.ietf.org/html/rfc5789
  162. */
  163. public function patch($url, $headers, $data = array(), $options = array()) {
  164. return $this->request($url, $headers, $data, Requests::PATCH, $options);
  165. }
  166. /**#@-*/
  167. /**
  168. * Main interface for HTTP requests
  169. *
  170. * This method initiates a request and sends it via a transport before
  171. * parsing.
  172. *
  173. * @see Requests::request()
  174. *
  175. * @throws Requests_Exception On invalid URLs (`nonhttp`)
  176. *
  177. * @param string $url URL to request
  178. * @param array $headers Extra headers to send with the request
  179. * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
  180. * @param string $type HTTP request type (use Requests constants)
  181. * @param array $options Options for the request (see {@see Requests::request})
  182. * @return Requests_Response
  183. */
  184. public function request($url, $headers = array(), $data = array(), $type = Requests::GET, $options = array()) {
  185. $request = $this->merge_request(compact('url', 'headers', 'data', 'options'));
  186. return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']);
  187. }
  188. /**
  189. * Send multiple HTTP requests simultaneously
  190. *
  191. * @see Requests::request_multiple()
  192. *
  193. * @param array $requests Requests data (see {@see Requests::request_multiple})
  194. * @param array $options Global and default options (see {@see Requests::request})
  195. * @return array Responses (either Requests_Response or a Requests_Exception object)
  196. */
  197. public function request_multiple($requests, $options = array()) {
  198. foreach ($requests as $key => $request) {
  199. $requests[$key] = $this->merge_request($request, false);
  200. }
  201. $options = array_merge($this->options, $options);
  202. // Disallow forcing the type, as that's a per request setting
  203. unset($options['type']);
  204. return Requests::request_multiple($requests, $options);
  205. }
  206. /**
  207. * Merge a request's data with the default data
  208. *
  209. * @param array $request Request data (same form as {@see request_multiple})
  210. * @param boolean $merge_options Should we merge options as well?
  211. * @return array Request data
  212. */
  213. protected function merge_request($request, $merge_options = true) {
  214. if ($this->url !== null) {
  215. $request['url'] = Requests_IRI::absolutize($this->url, $request['url']);
  216. $request['url'] = $request['url']->uri;
  217. }
  218. if (empty($request['headers'])) {
  219. $request['headers'] = array();
  220. }
  221. $request['headers'] = array_merge($this->headers, $request['headers']);
  222. if (empty($request['data'])) {
  223. if (is_array($this->data)) {
  224. $request['data'] = $this->data;
  225. }
  226. }
  227. elseif (is_array($request['data']) && is_array($this->data)) {
  228. $request['data'] = array_merge($this->data, $request['data']);
  229. }
  230. if ($merge_options !== false) {
  231. $request['options'] = array_merge($this->options, $request['options']);
  232. // Disallow forcing the type, as that's a per request setting
  233. unset($request['options']['type']);
  234. }
  235. return $request;
  236. }
  237. }