123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667 |
- =====================
- Using Request objects
- =====================
- HTTP request messages
- ---------------------
- Request objects are all about building an HTTP message. Each part of an HTTP request message can be set individually
- using methods on the request object or set in bulk using the ``setUrl()`` method. Here's the format of an HTTP request
- with each part of the request referencing the method used to change it::
- PUT(a) /path(b)?query=123(c) HTTP/1.1(d)
- X-Header(e): header
- Content-Length(e): 4
- data(f)
- +-------------------------+---------------------------------------------------------------------------------+
- | a. **Method** | The request method can only be set when instantiating a request |
- +-------------------------+---------------------------------------------------------------------------------+
- | b. **Path** | ``$request->setPath('/path');`` |
- +-------------------------+---------------------------------------------------------------------------------+
- | c. **Query** | ``$request->getQuery()->set('query', '123');`` |
- +-------------------------+---------------------------------------------------------------------------------+
- | d. **Protocol version** | ``$request->setProtocolVersion('1.1');`` |
- +-------------------------+---------------------------------------------------------------------------------+
- | e. **Header** | ``$request->setHeader('X-Header', 'header');`` |
- +-------------------------+---------------------------------------------------------------------------------+
- | f. **Entity Body** | ``$request->setBody('data'); // Only available with PUT, POST, PATCH, DELETE`` |
- +-------------------------+---------------------------------------------------------------------------------+
- Creating requests with a client
- -------------------------------
- Client objects are responsible for creating HTTP request objects.
- GET requests
- ~~~~~~~~~~~~
- `GET requests <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3>`_ are the most common form of HTTP
- requests. When you visit a website in your browser, the HTML of the website is downloaded using a GET request. GET
- requests are idempotent requests that are typically used to download content (an entity) identified by a request URL.
- .. code-block:: php
- use Guzzle\Http\Client;
- $client = new Client();
- // Create a request that has a query string and an X-Foo header
- $request = $client->get('http://www.amazon.com?a=1', array('X-Foo' => 'Bar'));
- // Send the request and get the response
- $response = $request->send();
- You can change where the body of a response is downloaded on any request using the
- ``$request->setResponseBody(string|EntityBodyInterface|resource)`` method of a request. You can also set the ``save_to``
- option of a request:
- .. code-block:: php
- // Send the response body to a file
- $request = $client->get('http://test.com', array(), array('save_to' => '/path/to/file'));
- // Send the response body to an fopen resource
- $request = $client->get('http://test.com', array(), array('save_to' => fopen('/path/to/file', 'w')));
- HEAD requests
- ~~~~~~~~~~~~~
- `HEAD requests <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4>`_ work exactly like GET requests except
- that they do not actually download the response body (entity) of the response message. HEAD requests are useful for
- retrieving meta information about an entity identified by a Request-URI.
- .. code-block:: php
- $client = new Guzzle\Http\Client();
- $request = $client->head('http://www.amazon.com');
- $response = $request->send();
- echo $response->getContentLength();
- // >>> Will output the Content-Length header value
- DELETE requests
- ~~~~~~~~~~~~~~~
- A `DELETE method <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7>`_ requests that the origin server
- delete the resource identified by the Request-URI.
- .. code-block:: php
- $client = new Guzzle\Http\Client();
- $request = $client->delete('http://example.com');
- $response = $request->send();
- POST requests
- ~~~~~~~~~~~~~
- While `POST requests <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5>`_ can be used for a number of
- reasons, POST requests are often used when submitting HTML form data to a website. POST requests can include an entity
- body in the HTTP request.
- POST requests in Guzzle are sent with an ``application/x-www-form-urlencoded`` Content-Type header if POST fields are
- present but no files are being sent in the POST. If files are specified in the POST request, then the Content-Type
- header will become ``multipart/form-data``.
- The ``post()`` method of a client object accepts four arguments: the URL, optional headers, post fields, and an array of
- request options. To send files in the POST request, prepend the ``@`` symbol to the array value (just like you would if
- you were using the PHP ``curl_setopt`` function).
- Here's how to create a multipart/form-data POST request containing files and fields:
- .. code-block:: php
- $request = $client->post('http://httpbin.org/post', array(), array(
- 'custom_field' => 'my custom value',
- 'file_field' => '@/path/to/file.xml'
- ));
- $response = $request->send();
- .. note::
- Remember to **always** sanitize user input when sending POST requests:
- .. code-block:: php
- // Prevent users from accessing sensitive files by sanitizing input
- $_POST = array('firstname' => '@/etc/passwd');
- $request = $client->post('http://www.example.com', array(), array (
- 'firstname' => str_replace('@', '', $_POST['firstname'])
- ));
- You can alternatively build up the contents of a POST request.
- .. code-block:: php
- $request = $client->post('http://httpbin.org/post')
- ->setPostField('custom_field', 'my custom value')
- ->addPostFile('file', '/path/to/file.xml');
- $response = $request->send();
- Raw POST data
- ^^^^^^^^^^^^^
- POST requests can also contain raw POST data that is not related to HTML forms.
- .. code-block:: php
- $request = $client->post('http://httpbin.org/post', array(), 'this is the body');
- $response = $request->send();
- You can set the body of POST request using the ``setBody()`` method of the
- ``Guzzle\Http\Message\EntityEnclosingRequest`` object. This method accepts a string, a resource returned from
- ``fopen``, or a ``Guzzle\Http\EntityBodyInterface`` object.
- .. code-block:: php
- $request = $client->post('http://httpbin.org/post');
- // Set the body of the POST to stream the contents of /path/to/large_body.txt
- $request->setBody(fopen('/path/to/large_body.txt', 'r'));
- $response = $request->send();
- PUT requests
- ~~~~~~~~~~~~
- The `PUT method <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6>`_ requests that the enclosed entity be
- stored under the supplied Request-URI. PUT requests are similar to POST requests in that they both can send an entity
- body in the request message.
- The body of a PUT request (any any ``Guzzle\Http\Message\EntityEnclosingRequestInterface`` object) is always stored as
- a ``Guzzle\Http\Message\EntityBodyInterface`` object. This allows a great deal of flexibility when sending data to a
- remote server. For example, you can stream the contents of a stream returned by fopen, stream the contents of a
- callback function, or simply send a string of data.
- .. code-block:: php
- $request = $client->put('http://httpbin.org/put', array(), 'this is the body');
- $response = $request->send();
- Just like with POST, PATH, and DELETE requests, you can set the body of a PUT request using the ``setBody()`` method.
- .. code-block:: php
- $request = $client->put('http://httpbin.org/put');
- $request->setBody(fopen('/path/to/large_body.txt', 'r'));
- $response = $request->send();
- PATCH requests
- ~~~~~~~~~~~~~~
- `PATCH requests <http://tools.ietf.org/html/rfc5789>`_ are used to modify a resource.
- .. code-block:: php
- $request = $client->patch('http://httpbin.org', array(), 'this is the body');
- $response = $request->send();
- OPTIONS requests
- ~~~~~~~~~~~~~~~~
- The `OPTIONS method <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2>`_ represents a request for
- information about the communication options available on the request/response chain identified by the Request-URI.
- .. code-block:: php
- $request = $client->options('http://httpbin.org');
- $response = $request->send();
- // Check if the PUT method is supported by this resource
- var_export($response->isMethodAllows('PUT'));
- Custom requests
- ~~~~~~~~~~~~~~~
- You can create custom HTTP requests that use non-standard HTTP methods using the ``createRequest()`` method of a
- client object.
- .. code-block:: php
- $request = $client->createRequest('COPY', 'http://example.com/foo', array(
- 'Destination' => 'http://example.com/bar',
- 'Overwrite' => 'T'
- ));
- $response = $request->send();
- Query string parameters
- -----------------------
- Query string parameters of a request are owned by a request's ``Guzzle\Http\Query`` object that is accessible by
- calling ``$request->getQuery()``. The Query class extends from ``Guzzle\Common\Collection`` and allows you to set one
- or more query string parameters as key value pairs. You can set a parameter on a Query object using the
- ``set($key, $value)`` method or access the query string object like an associative array. Any previously specified
- value for a key will be overwritten when using ``set()``. Use ``add($key, $value)`` to add a value to query string
- object, and in the event of a collision with an existing value at a specific key, the value will be converted to an
- array that contains all of the previously set values.
- .. code-block:: php
- $request = new Guzzle\Http\Message\Request('GET', 'http://www.example.com?foo=bar&abc=123');
- $query = $request->getQuery();
- echo "{$query}\n";
- // >>> foo=bar&abc=123
- $query->remove('abc');
- echo "{$query}\n";
- // >>> foo=bar
- $query->set('foo', 'baz');
- echo "{$query}\n";
- // >>> foo=baz
- $query->add('foo', 'bar');
- echo "{$query}\n";
- // >>> foo%5B0%5D=baz&foo%5B1%5D=bar
- Whoah! What happened there? When ``foo=bar`` was added to the existing ``foo=baz`` query string parameter, the
- aggregator associated with the Query object was used to help convert multi-value query string parameters into a string.
- Let's disable URL-encoding to better see what's happening.
- .. code-block:: php
- $query->useUrlEncoding(false);
- echo "{$query}\n";
- // >>> foo[0]=baz&foo[1]=bar
- .. note::
- URL encoding can be disabled by passing false, enabled by passing true, set to use RFC 1738 by passing
- ``Query::FORM_URLENCODED`` (internally uses PHP's ``urlencode`` function), or set to RFC 3986 by passing
- ``Query::RFC_3986`` (this is the default and internally uses PHP's ``rawurlencode`` function).
- As you can see, the multiple values were converted into query string parameters following the default PHP convention of
- adding numerically indexed square bracket suffixes to each key (``foo[0]=baz&foo[1]=bar``). The strategy used to convert
- multi-value parameters into a string can be customized using the ``setAggregator()`` method of the Query class. Guzzle
- ships with the following query string aggregators by default:
- 1. ``Guzzle\Http\QueryAggregator\PhpAggregator``: Aggregates using PHP style brackets (e.g. ``foo[0]=baz&foo[1]=bar``)
- 2. ``Guzzle\Http\QueryAggregator\DuplicateAggregator``: Performs no aggregation and allows for key value pairs to be
- repeated in a URL (e.g. ``foo=baz&foo=bar``)
- 3. ``Guzzle\Http\QueryAggregator\CommaAggregator``: Aggregates using commas (e.g. ``foo=baz,bar``)
- .. _http-message-headers:
- HTTP Message Headers
- --------------------
- HTTP message headers are case insensitive, multiple occurrences of any header can be present in an HTTP message
- (whether it's valid or not), and some servers require specific casing of particular headers. Because of this, request
- and response headers are stored in ``Guzzle\Http\Message\Header`` objects. The Header object can be cast as a string,
- counted, or iterated to retrieve each value from the header. Casting a Header object to a string will return all of
- the header values concatenated together using a glue string (typically ", ").
- A request (and response) object have several methods that allow you to retrieve and modify headers.
- * ``getHeaders()``: Get all of the headers of a message as a ``Guzzle\Http\Message\Header\HeaderCollection`` object.
- * ``getHeader($header)``: Get a specific header from a message. If the header exists, you'll get a
- ``Guzzle\Http\Message\Header`` object. If the header does not exist, this methods returns ``null``.
- * ``hasHeader($header)``: Returns true or false based on if the message has a particular header.
- * ``setHeader($header, $value)``: Set a header value and overwrite any previously set value for this header.
- * ``addHeader($header, $value)``: Add a header with a particular name. If a previous value was already set by the same,
- then the header will contain multiple values.
- * ``removeHeader($header)``: Remove a header by name from the message.
- .. code-block:: php
- $request = new Request('GET', 'http://httpbin.com/cookies');
- // addHeader will set and append to any existing header values
- $request->addHeader('Foo', 'bar');
- $request->addHeader('foo', 'baz');
- // setHeader overwrites any existing values
- $request->setHeader('Test', '123');
- // Request headers can be cast as a string
- echo $request->getHeader('Foo');
- // >>> bar, baz
- echo $request->getHeader('Test');
- // >>> 123
- // You can count the number of headers of a particular case insensitive name
- echo count($request->getHeader('foO'));
- // >>> 2
- // You can iterate over Header objects
- foreach ($request->getHeader('foo') as $header) {
- echo $header . "\n";
- }
- // You can get all of the request headers as a Guzzle\Http\Message\Header\HeaderCollection object
- $headers = $request->getHeaders();
- // Missing headers return NULL
- var_export($request->getHeader('Missing'));
- // >>> null
- // You can see all of the different variations of a header by calling raw() on the Header
- var_export($request->getHeader('foo')->raw());
- Setting the body of a request
- -----------------------------
- Requests that can send a body (e.g. PUT, POST, DELETE, PATCH) are instances of
- ``Guzzle\Http\Message\EntityEnclosingRequestInterface``. Entity enclosing requests contain several methods that allow
- you to specify the body to send with a request.
- Use the ``setBody()`` method of a request to set the body that will be sent with a request. This method accepts a
- string, a resource returned by ``fopen()``, an array, or an instance of ``Guzzle\Http\EntityBodyInterface``. The body
- will then be streamed from the underlying ``EntityBodyInterface`` object owned by the request. When setting the body
- of the request, you can optionally specify a Content-Type header and whether or not to force the request to use
- chunked Transfer-Encoding.
- .. code-block:: php
- $request = $client->put('/user.json');
- $request->setBody('{"foo":"baz"}', 'application/json');
- Content-Type header
- ~~~~~~~~~~~~~~~~~~~
- Guzzle will automatically add a Content-Type header to a request if the Content-Type can be guessed based on the file
- extension of the payload being sent or the file extension present in the path of a request.
- .. code-block:: php
- $request = $client->put('/user.json', array(), '{"foo":"bar"}');
- // The Content-Type was guessed based on the path of the request
- echo $request->getHeader('Content-Type');
- // >>> application/json
- $request = $client->put('/user.json');
- $request->setBody(fopen('/tmp/user_data.json', 'r'));
- // The Content-Type was guessed based on the path of the entity body
- echo $request->getHeader('Content-Type');
- // >>> application/json
- Transfer-Encoding: chunked header
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- When sending HTTP requests that contain a payload, you must let the remote server know how to determine when the entire
- message has been sent. This usually is done by supplying a ``Content-Length`` header that tells the origin server the
- size of the body that is to be sent. In some cases, the size of the payload being sent in a request cannot be known
- before initiating the transfer. In these cases (when using HTTP/1.1), you can use the ``Transfer-Encoding: chunked``
- header.
- If the Content-Length cannot be determined (i.e. using a PHP ``http://`` stream), then Guzzle will automatically add
- the ``Transfer-Encoding: chunked`` header to the request.
- .. code-block:: php
- $request = $client->put('/user.json');
- $request->setBody(fopen('http://httpbin.org/get', 'r'));
- // The Content-Length could not be determined
- echo $request->getHeader('Transfer-Encoding');
- // >>> chunked
- See :doc:`/http-client/entity-bodies` for more information on entity bodies.
- Expect: 100-Continue header
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``Expect: 100-Continue`` header is used to help a client prevent sending a large payload to a server that will
- reject the request. This allows clients to fail fast rather than waste bandwidth sending an erroneous payload. Guzzle
- will automatically add the ``Expect: 100-Continue`` header to a request when the size of the payload exceeds 1MB or if
- the body of the request is not seekable (this helps to prevent errors when a non-seekable body request is redirected).
- .. note::
- If you find that your larger requests are taking too long to complete, you should first check if the
- ``Expect: 100-Continue`` header is being sent with the request. Some servers do not respond well to this header,
- which causes cURL to sleep for `1 second <http://curl.haxx.se/mail/lib-2010-01/0182.html>`_.
- POST fields and files
- ~~~~~~~~~~~~~~~~~~~~~
- Any entity enclosing request can send POST style fields and files. This includes POST, PUT, PATCH, and DELETE requests.
- Any request that has set POST fields or files will use cURL's POST message functionality.
- .. code-block:: php
- $request = $client->post('/post');
- // Set an overwrite any previously specified value
- $request->setPostField('foo', 'bar');
- // Append a value to any existing values
- $request->getPostFields()->add('foo', 'baz');
- // Remove a POST field by name
- $request->removePostField('fizz');
- // Add a file to upload (forces multipart/form-data)
- $request->addPostFile('my_file', '/path/to/file', 'plain/text');
- // Remove a POST file by POST key name
- $request->removePostFile('my_other_file');
- .. tip::
- Adding a large number of POST fields to a POST request is faster if you use the ``addPostFields()`` method so that
- you can add and process multiple fields with a single call. Adding multiple POST files is also faster using
- ``addPostFiles()``.
- Working with cookies
- --------------------
- Cookies can be modified and retrieved from a request using the following methods:
- .. code-block:: php
- $request->addCookie($name, $value);
- $request->removeCookie($name);
- $value = $request->getCookie($name);
- $valueArray = $request->getCookies();
- Use the :doc:`cookie plugin </plugins/cookie-plugin>` if you need to reuse cookies between requests.
- .. _request-set-response-body:
- Changing where a response is downloaded
- ----------------------------------------
- When a request is sent, the body of the response will be stored in a PHP temp stream by default. You can change the
- location in which the response will be downloaded using ``$request->setResponseBody($body)`` or the ``save_to`` request
- option. This can be useful for downloading the contents of a URL to a specific file.
- Here's an example of using request options:
- .. code-block:: php
- $request = $this->client->get('http://example.com/large.mov', array(), array(
- 'save_to' => '/tmp/large_file.mov'
- ));
- $request->send();
- var_export(file_exists('/tmp/large_file.mov'));
- // >>> true
- Here's an example of using ``setResponseBody()``:
- .. code-block:: php
- $body = fopen('/tmp/large_file.mov', 'w');
- $request = $this->client->get('http://example.com/large.mov');
- $request->setResponseBody($body);
- // You can more easily specify the name of a file to save the contents
- // of the response to by passing a string to ``setResponseBody()``.
- $request = $this->client->get('http://example.com/large.mov');
- $request->setResponseBody('/tmp/large_file.mov');
- Custom cURL options
- -------------------
- Most of the functionality implemented in the libcurl bindings has been simplified and abstracted by Guzzle. Developers
- who need access to `cURL specific functionality <http://www.php.net/curl_setopt>`_ can still add cURL handle
- specific behavior to Guzzle HTTP requests by modifying the cURL options collection of a request:
- .. code-block:: php
- $request->getCurlOptions()->set(CURLOPT_LOW_SPEED_LIMIT, 200);
- Other special options that can be set in the ``curl.options`` array include:
- +-------------------------+---------------------------------------------------------------------------------+
- | debug | Adds verbose cURL output to a temp stream owned by the cURL handle object |
- +-------------------------+---------------------------------------------------------------------------------+
- | progress | Instructs cURL to emit events when IO events occur. This allows you to be |
- | | notified when bytes are transferred over the wire by subscribing to a request's |
- | | ``curl.callback.read``, ``curl.callback.write``, and ``curl.callback.progress`` |
- | | events. |
- +-------------------------+---------------------------------------------------------------------------------+
- Request options
- ---------------
- Requests options can be specified when creating a request or in the ``request.options`` parameter of a client. These
- options can control various aspects of a request including: headers to send, query string data, where the response
- should be downloaded, proxies, auth, etc.
- .. code-block:: php
- $request = $client->get($url, $headers, array('proxy' => 'http://proxy.com'));
- See :ref:`Request options <request-options>` for more information.
- Working with errors
- -------------------
- HTTP errors
- ~~~~~~~~~~~
- Requests that receive a 4xx or 5xx response will throw a ``Guzzle\Http\Exception\BadResponseException``. More
- specifically, 4xx errors throw a ``Guzzle\Http\Exception\ClientErrorResponseException``, and 5xx errors throw a
- ``Guzzle\Http\Exception\ServerErrorResponseException``. You can catch the specific exceptions or just catch the
- BadResponseException to deal with either type of error. Here's an example of catching a generic BadResponseException:
- .. code-block:: php
- try {
- $response = $client->get('/not_found.xml')->send();
- } catch (Guzzle\Http\Exception\BadResponseException $e) {
- echo 'Uh oh! ' . $e->getMessage();
- echo 'HTTP request URL: ' . $e->getRequest()->getUrl() . "\n";
- echo 'HTTP request: ' . $e->getRequest() . "\n";
- echo 'HTTP response status: ' . $e->getResponse()->getStatusCode() . "\n";
- echo 'HTTP response: ' . $e->getResponse() . "\n";
- }
- Throwing an exception when a 4xx or 5xx response is encountered is the default behavior of Guzzle requests. This
- behavior can be overridden by adding an event listener with a higher priority than -255 that stops event propagation.
- You can subscribe to ``request.error`` to receive notifications any time an unsuccessful response is received.
- You can change the response that will be associated with the request by calling ``setResponse()`` on the
- ``$event['request']`` object passed into your listener, or by changing the ``$event['response']`` value of the
- ``Guzzle\Common\Event`` object that is passed to your listener. Transparently changing the response associated with a
- request by modifying the event allows you to retry failed requests without complicating the code that uses the client.
- This might be useful for sending requests to a web service that has expiring auth tokens. When a response shows that
- your token has expired, you can get a new token, retry the request with the new token, and return the successful
- response to the user.
- Here's an example of retrying a request using updated authorization credentials when a 401 response is received,
- overriding the response of the original request with the new response, and still allowing the default exception
- behavior to be called when other non-200 response status codes are encountered:
- .. code-block:: php
- // Add custom error handling to any request created by this client
- $client->getEventDispatcher()->addListener('request.error', function(Event $event) {
- if ($event['response']->getStatusCode() == 401) {
- $newRequest = $event['request']->clone();
- $newRequest->setHeader('X-Auth-Header', MyApplication::getNewAuthToken());
- $newResponse = $newRequest->send();
- // Set the response object of the request without firing more events
- $event['response'] = $newResponse;
- // You can also change the response and fire the normal chain of
- // events by calling $event['request']->setResponse($newResponse);
- // Stop other events from firing when you override 401 responses
- $event->stopPropagation();
- }
- });
- cURL errors
- ~~~~~~~~~~~
- Connection problems and cURL specific errors can also occur when transferring requests using Guzzle. When Guzzle
- encounters cURL specific errors while transferring a single request, a ``Guzzle\Http\Exception\CurlException`` is
- thrown with an informative error message and access to the cURL error message.
- A ``Guzzle\Http\Exception\MultiTransferException`` exception is thrown when a cURL specific error occurs while
- transferring multiple requests in parallel. You can then iterate over all of the exceptions encountered during the
- transfer.
- Plugins and events
- ------------------
- Guzzle request objects expose various events that allow you to hook in custom logic. A request object owns a
- ``Symfony\Component\EventDispatcher\EventDispatcher`` object that can be accessed by calling
- ``$request->getEventDispatcher()``. You can use the event dispatcher to add listeners (a simple callback function) or
- event subscribers (classes that listen to specific events of a dispatcher). You can add event subscribers to a request
- directly by just calling ``$request->addSubscriber($mySubscriber);``.
- .. _request-events:
- Events emitted from a request
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A ``Guzzle\Http\Message\Request`` and ``Guzzle\Http\Message\EntityEnclosingRequest`` object emit the following events:
- +------------------------------+--------------------------------------------+------------------------------------------+
- | Event name | Description | Event data |
- +==============================+============================================+==========================================+
- | request.before_send | About to send request | * request: Request to be sent |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | request.sent | Sent the request | * request: Request that was sent |
- | | | * response: Received response |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | request.complete | Completed a full HTTP transaction | * request: Request that was sent |
- | | | * response: Received response |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | request.success | Completed a successful request | * request: Request that was sent |
- | | | * response: Received response |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | request.error | Completed an unsuccessful request | * request: Request that was sent |
- | | | * response: Received response |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | request.exception | An unsuccessful response was | * request: Request |
- | | received. | * response: Received response |
- | | | * exception: BadResponseException |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | request.receive.status_line | Received the start of a response | * line: Full response start line |
- | | | * status_code: Status code |
- | | | * reason_phrase: Reason phrase |
- | | | * previous_response: (e.g. redirect) |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | curl.callback.progress | cURL progress event (only dispatched when | * handle: CurlHandle |
- | | ``emit_io`` is set on a request's curl | * download_size: Total download size |
- | | options) | * downloaded: Bytes downloaded |
- | | | * upload_size: Total upload bytes |
- | | | * uploaded: Bytes uploaded |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | curl.callback.write | cURL event called when data is written to | * request: Request |
- | | an outgoing stream | * write: Data being written |
- +------------------------------+--------------------------------------------+------------------------------------------+
- | curl.callback.read | cURL event called when data is written to | * request: Request |
- | | an incoming stream | * read: Data being read |
- +------------------------------+--------------------------------------------+------------------------------------------+
- Creating a request event listener
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Here's an example that listens to the ``request.complete`` event of a request and prints the request and response.
- .. code-block:: php
- use Guzzle\Common\Event;
- $request = $client->get('http://www.google.com');
- // Echo out the response that was received
- $request->getEventDispatcher()->addListener('request.complete', function (Event $e) {
- echo $e['request'] . "\n\n";
- echo $e['response'];
- });
|