123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- ===========================
- Request and response bodies
- ===========================
- `Entity body <http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html>`_ is the term used for the body of an HTTP
- message. The entity body of requests and responses is inherently a
- `PHP stream <http://php.net/manual/en/book.stream.php>`_ in Guzzle. The body of the request can be either a string or
- a PHP stream which are converted into a ``Guzzle\Http\EntityBody`` object using its factory method. When using a
- string, the entity body is stored in a `temp PHP stream <http://www.php.net/manual/en/wrappers.php.php>`_. The use of
- temp PHP streams helps to protect your application from running out of memory when sending or receiving large entity
- bodies in your messages. When more than 2MB of data is stored in a temp stream, it automatically stores the data on
- disk rather than in memory.
- EntityBody objects provide a great deal of functionality: compression, decompression, calculate the Content-MD5,
- calculate the Content-Length (when the resource is repeatable), guessing the Content-Type, and more. Guzzle doesn't
- need to load an entire entity body into a string when sending or retrieving data; entity bodies are streamed when
- being uploaded and downloaded.
- Here's an example of gzip compressing a text file then sending the file to a URL:
- .. code-block:: php
- use Guzzle\Http\EntityBody;
- $body = EntityBody::factory(fopen('/path/to/file.txt', 'r+'));
- echo $body->read(1024);
- $body->seek(0, SEEK_END);
- $body->write('foo');
- echo $body->ftell();
- $body->rewind();
- // Send a request using the body
- $response = $client->put('http://localhost:8080/uploads', null, $body)->send();
- The body of the request can be specified in the ``Client::put()`` or ``Client::post()`` method, or, you can specify
- the body of the request by calling the ``setBody()`` method of any
- ``Guzzle\Http\Message\EntityEnclosingRequestInterface`` object.
- Compression
- -----------
- You can compress the contents of an EntityBody object using the ``compress()`` method. The compress method accepts a
- filter that must match to one of the supported
- `PHP stream filters <http://www.php.net/manual/en/filters.compression.php>`_ on your system (e.g. `zlib.deflate`,
- ``bzip2.compress``, etc). Compressing an entity body will stream the entire entity body through a stream compression
- filter into a temporary PHP stream. You can uncompress an entity body using the ``uncompress()`` method and passing
- the PHP stream filter to use when decompressing the stream (e.g. ``zlib.inflate``).
- .. code-block:: php
- use Guzzle\Http\EntityBody;
- $body = EntityBody::factory(fopen('/tmp/test.txt', 'r+'));
- echo $body->getSize();
- // >>> 1048576
- // Compress using the default zlib.deflate filter
- $body->compress();
- echo $body->getSize();
- // >>> 314572
- // Decompress the stream
- $body->uncompress();
- echo $body->getSize();
- // >>> 1048576
- Decorators
- ----------
- Guzzle provides several EntityBody decorators that can be used to add functionality to an EntityBody at runtime.
- IoEmittingEntityBody
- ~~~~~~~~~~~~~~~~~~~~
- This decorator will emit events when data is read from a stream or written to a stream. Add an event subscriber to the
- entity body's ``body.read`` or ``body.write`` methods to receive notifications when data data is transferred.
- .. code-block:: php
- use Guzzle\Common\Event;
- use Guzzle\Http\EntityBody;
- use Guzzle\Http\IoEmittingEntityBody;
- $original = EntityBody::factory(fopen('/tmp/test.txt', 'r+'));
- $body = new IoEmittingEntityBody($original);
- // Listen for read events
- $body->getEventDispatcher()->addListener('body.read', function (Event $e) {
- // Grab data from the event
- $entityBody = $e['body'];
- // Amount of data retrieved from the body
- $lengthOfData = $e['length'];
- // The actual data that was read
- $data = $e['read'];
- });
- // Listen for write events
- $body->getEventDispatcher()->addListener('body.write', function (Event $e) {
- // Grab data from the event
- $entityBody = $e['body'];
- // The data that was written
- $data = $e['write'];
- // The actual amount of data that was written
- $data = $e['read'];
- });
- ReadLimitEntityBody
- ~~~~~~~~~~~~~~~~~~~
- The ReadLimitEntityBody decorator can be used to transfer a subset or slice of an existing EntityBody object. This can
- be useful for breaking a large file into smaller pieces to be sent in chunks (e.g. Amazon S3's multipart upload API).
- .. code-block:: php
- use Guzzle\Http\EntityBody;
- use Guzzle\Http\ReadLimitEntityBody;
- $original = EntityBody::factory(fopen('/tmp/test.txt', 'r+'));
- echo $original->getSize();
- // >>> 1048576
- // Limit the size of the body to 1024 bytes and start reading from byte 2048
- $body = new ReadLimitEntityBody($original, 1024, 2048);
- echo $body->getSize();
- // >>> 1024
- echo $body->ftell();
- // >>> 0
- CachingEntityBody
- ~~~~~~~~~~~~~~~~~
- The CachingEntityBody decorator is used to allow seeking over previously read bytes on non-seekable read streams. This
- can be useful when transferring a non-seekable entity body fails due to needing to rewind the stream (for example,
- resulting from a redirect). Data that is read from the remote stream will be buffered in a PHP temp stream so that
- previously read bytes are cached first in memory, then on disk.
- .. code-block:: php
- use Guzzle\Http\EntityBody;
- use Guzzle\Http\CachingEntityBody;
- $original = EntityBody::factory(fopen('http://www.google.com', 'r'));
- $body = new CachingEntityBody($original);
- $body->read(1024);
- echo $body->ftell();
- // >>> 1024
- $body->seek(0);
- echo $body->ftell();
- // >>> 0
|