Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add session support #62

Merged
merged 8 commits into from
Sep 30, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/usage-advanced.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
Advanced Usage
==============

Session Handling
----------------
Making multiple requests to the same site with similar options can be a pain,
since you end up repeating yourself. The Session object can be used to set
default parameters for these.

Let's simulate communicating with GitHub.

```php
$session = new Requests_Session('https://api.github.com/');
$session->headers['X-ContactAuthor'] = 'rmccue';
$session->useragent = 'My-Awesome-App';

$response = $session->get('/zen');
```

You can use the `url`, `headers`, `data` and `options` properties of the Session
object to set the defaults for this session, and the constructor also takes
parameters in the same order as `Requests::request()`. Accessing any other
properties will set the corresponding key in the options array; that is:

```php
// Setting the property...
$session->useragent = 'My-Awesome-App';

// ...is the same as setting the option
$session->options['useragent'] = 'My-Awesome-App';
```


Secure Requests with SSL
------------------------
By default, HTTPS requests will use the most secure options available:
Expand Down
24 changes: 24 additions & 0 deletions examples/session.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

// First, include Requests
include('../library/Requests.php');

// Next, make sure Requests can load internal classes
Requests::register_autoloader();

// Set up our session
$session = new Requests_Session('http://httpbin.org/');
$session->headers['Accept'] = 'application/json';
$session->useragent = 'Awesomesauce';

// Now let's make a request!
$request = $session->get('/get');

// Check what we received
var_dump($request);

// Let's check our user agent!
$request = $session->get('/user-agent');

// And check again
var_dump($request);
252 changes: 252 additions & 0 deletions library/Requests/Session.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
<?php
/**
* Session handler for persistent requests and default parameters
*
* @package Requests
* @subpackage Session Handler
*/

/**
* Session handler for persistent requests and default parameters
*
* Allows various options to be set as default values, and merges both the
* options and URL properties together. A base URL can be set for all requests,
* with all subrequests resolved from this. Base options can be set (including
* a shared cookie jar), then overridden for individual requests.
*
* @package Requests
* @subpackage Session Handler
*/
class Requests_Session {
/**
* Base URL for requests
*
* URLs will be made absolute using this as the base
* @var string|null
*/
public $url = null;

/**
* Base headers for requests
* @var array
*/
public $headers = array();

/**
* Base data for requests
*
* If both the base data and the per-request data are arrays, the data will
* be merged before sending the request.
*
* @var array
*/
public $data = array();

/**
* Base options for requests
*
* The base options are merged with the per-request data for each request.
* The only default option is a shared cookie jar between requests.
*
* Values here can also be set directly via properties on the Session
* object, e.g. `$session->useragent = 'X';`
*
* @var array
*/
public $options = array();

/**
* Create a new session
*
* @param string|null $url Base URL for requests
* @param array $headers Default headers for requests
* @param array $data Default data for requests
* @param array $options Default options for requests
*/
public function __construct($url = null, $headers = array(), $data = array(), $options = array()) {
$this->url = $url;
$this->headers = $headers;
$this->data = $data;
$this->options = $options;

if (empty($this->options['cookies'])) {
$this->options['cookies'] = new Requests_Cookie_Jar();
}
}

/**
* Get a property's value
*
* @param string $key Property key
* @return mixed|null Property value, null if none found
*/
public function __get($key) {
if (isset($this->options[$key]))
return $this->options[$key];

return null;
}

/**
* Set a property's value
*
* @param string $key Property key
* @param mixed $value Property value
*/
public function __set($key, $value) {
$this->options[$key] = $value;
}

/**
* Remove a property's value
*
* @param string $key Property key
*/
public function __isset($key) {
return isset($this->options[$key]);
}

/**
* Remove a property's value
*
* @param string $key Property key
*/
public function __unset($key) {
$this->options[$key] = null;
}

/**#@+
* @see request()
* @param string $url
* @param array $headers
* @param array $options
* @return Requests_Response
*/
/**
* Send a GET request
*/
public function get($url, $headers = array(), $options = array()) {
return $this->request($url, $headers, null, Requests::GET, $options);
}

/**
* Send a HEAD request
*/
public function head($url, $headers = array(), $options = array()) {
return $this->request($url, $headers, null, Requests::HEAD, $options);
}

/**
* Send a DELETE request
*/
public function delete($url, $headers = array(), $options = array()) {
return $this->request($url, $headers, null, Requests::DELETE, $options);
}

/**#@+
* @see request()
* @param string $url
* @param array $headers
* @param array $data
* @param array $options
* @return Requests_Response
*/
/**
* Send a POST request
*/
public function post($url, $headers = array(), $data = array(), $options = array()) {
return $this->request($url, $headers, $data, Requests::POST, $options);
}

/**
* Send a PUT request
*/
public function put($url, $headers = array(), $data = array(), $options = array()) {
return $this->request($url, $headers, $data, Requests::PUT, $options);
}

/**
* Send a PATCH request
*
* Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
* specification recommends that should send an ETag
*
* @link http://tools.ietf.org/html/rfc5789
*/
public function patch($url, $headers, $data = array(), $options = array()) {
return $this->request($url, $headers, $data, Requests::PATCH, $options);
}
/**#@-*/

/**
* Main interface for HTTP requests
*
* This method initiates a request and sends it via a transport before
* parsing.
*
* @see Requests::request()
*
* @throws Requests_Exception On invalid URLs (`nonhttp`)
*
* @param string $url URL to request
* @param array $headers Extra headers to send with the request
* @param array $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
* @param string $type HTTP request type (use Requests constants)
* @param array $options Options for the request (see {@see Requests::request})
* @return Requests_Response
*/
public function request($url, $headers = array(), $data = array(), $type = Requests::GET, $options = array()) {
$request = $this->merge_request(compact('url', 'headers', 'data', 'options'));

return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']);
}

/**
* Send multiple HTTP requests simultaneously
*
* @see Requests::request_multiple()
*
* @param array $requests Requests data (see {@see Requests::request_multiple})
* @param array $options Global and default options (see {@see Requests::request})
* @return array Responses (either Requests_Response or a Requests_Exception object)
*/
public function request_multiple($requests, $options = array()) {
foreach ($requests as $key => $request) {
$requests[$key] = $this->merge_request($request, false);
}

$options = array_merge($this->options, $options);

// Disallow forcing the type, as that's a per request setting
unset($options['type']);

return Requests::request_multiple($requests, $options);
}

/**
* Merge a request's data with the default data
*
* @param array $request Request data (same form as {@see request_multiple})
* @param boolean $merge_options Should we merge options as well?
* @return array Request data
*/
protected function merge_request($request, $merge_options = true) {
if ($this->url !== null) {
$request['url'] = Requests_IRI::absolutize($this->url, $request['url']);
$request['url'] = $request['url']->uri;
}
$request['headers'] = array_merge($this->headers, $request['headers']);

if (is_array($request['data']) && is_array($this->data)) {
$request['data'] = array_merge($this->data, $request['data']);
}

if ($merge_options !== false) {
$request['options'] = array_merge($this->options, $request['options']);

// Disallow forcing the type, as that's a per request setting
unset($request['options']['type']);
}
return $request;
}
}
Loading