570 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			570 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # PSR-7 Message Implementation
 | |
| 
 | |
| This repository contains a full [PSR-7](http://www.php-fig.org/psr/psr-7/)
 | |
| message implementation, several stream decorators, and some helpful
 | |
| functionality like query string parsing.
 | |
| 
 | |
| 
 | |
| [](https://travis-ci.org/guzzle/psr7)
 | |
| 
 | |
| 
 | |
| # Stream implementation
 | |
| 
 | |
| This package comes with a number of stream implementations and stream
 | |
| decorators.
 | |
| 
 | |
| 
 | |
| ## AppendStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\AppendStream`
 | |
| 
 | |
| Reads from multiple streams, one after the other.
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| $a = Psr7\stream_for('abc, ');
 | |
| $b = Psr7\stream_for('123.');
 | |
| $composed = new Psr7\AppendStream([$a, $b]);
 | |
| 
 | |
| $composed->addStream(Psr7\stream_for(' Above all listen to me'));
 | |
| 
 | |
| echo $composed; // abc, 123. Above all listen to me.
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## BufferStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\BufferStream`
 | |
| 
 | |
| Provides a buffer stream that can be written to fill a buffer, and read
 | |
| from to remove bytes from the buffer.
 | |
| 
 | |
| This stream returns a "hwm" metadata value that tells upstream consumers
 | |
| what the configured high water mark of the stream is, or the maximum
 | |
| preferred size of the buffer.
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| // When more than 1024 bytes are in the buffer, it will begin returning
 | |
| // false to writes. This is an indication that writers should slow down.
 | |
| $buffer = new Psr7\BufferStream(1024);
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## CachingStream
 | |
| 
 | |
| The CachingStream is used to allow seeking over previously read bytes on
 | |
| non-seekable 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.
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| $original = Psr7\stream_for(fopen('http://www.google.com', 'r'));
 | |
| $stream = new Psr7\CachingStream($original);
 | |
| 
 | |
| $stream->read(1024);
 | |
| echo $stream->tell();
 | |
| // 1024
 | |
| 
 | |
| $stream->seek(0);
 | |
| echo $stream->tell();
 | |
| // 0
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## DroppingStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\DroppingStream`
 | |
| 
 | |
| Stream decorator that begins dropping data once the size of the underlying
 | |
| stream becomes too full.
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| // Create an empty stream
 | |
| $stream = Psr7\stream_for();
 | |
| 
 | |
| // Start dropping data when the stream has more than 10 bytes
 | |
| $dropping = new Psr7\DroppingStream($stream, 10);
 | |
| 
 | |
| $dropping->write('01234567890123456789');
 | |
| echo $stream; // 0123456789
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## FnStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\FnStream`
 | |
| 
 | |
| Compose stream implementations based on a hash of functions.
 | |
| 
 | |
| Allows for easy testing and extension of a provided stream without needing
 | |
| to create a concrete class for a simple extension point.
 | |
| 
 | |
| ```php
 | |
| 
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| $stream = Psr7\stream_for('hi');
 | |
| $fnStream = Psr7\FnStream::decorate($stream, [
 | |
|     'rewind' => function () use ($stream) {
 | |
|         echo 'About to rewind - ';
 | |
|         $stream->rewind();
 | |
|         echo 'rewound!';
 | |
|     }
 | |
| ]);
 | |
| 
 | |
| $fnStream->rewind();
 | |
| // Outputs: About to rewind - rewound!
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## InflateStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\InflateStream`
 | |
| 
 | |
| Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
 | |
| 
 | |
| This stream decorator skips the first 10 bytes of the given stream to remove
 | |
| the gzip header, converts the provided stream to a PHP stream resource,
 | |
| then appends the zlib.inflate filter. The stream is then converted back
 | |
| to a Guzzle stream resource to be used as a Guzzle stream.
 | |
| 
 | |
| 
 | |
| ## LazyOpenStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\LazyOpenStream`
 | |
| 
 | |
| Lazily reads or writes to a file that is opened only after an IO operation
 | |
| take place on the stream.
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| $stream = new Psr7\LazyOpenStream('/path/to/file', 'r');
 | |
| // The file has not yet been opened...
 | |
| 
 | |
| echo $stream->read(10);
 | |
| // The file is opened and read from only when needed.
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## LimitStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\LimitStream`
 | |
| 
 | |
| LimitStream can be used to read a subset or slice of an existing stream 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).
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| $original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+'));
 | |
| echo $original->getSize();
 | |
| // >>> 1048576
 | |
| 
 | |
| // Limit the size of the body to 1024 bytes and start reading from byte 2048
 | |
| $stream = new Psr7\LimitStream($original, 1024, 2048);
 | |
| echo $stream->getSize();
 | |
| // >>> 1024
 | |
| echo $stream->tell();
 | |
| // >>> 0
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## MultipartStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\MultipartStream`
 | |
| 
 | |
| Stream that when read returns bytes for a streaming multipart or
 | |
| multipart/form-data stream.
 | |
| 
 | |
| 
 | |
| ## NoSeekStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\NoSeekStream`
 | |
| 
 | |
| NoSeekStream wraps a stream and does not allow seeking.
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| $original = Psr7\stream_for('foo');
 | |
| $noSeek = new Psr7\NoSeekStream($original);
 | |
| 
 | |
| echo $noSeek->read(3);
 | |
| // foo
 | |
| var_export($noSeek->isSeekable());
 | |
| // false
 | |
| $noSeek->seek(0);
 | |
| var_export($noSeek->read(3));
 | |
| // NULL
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## PumpStream
 | |
| 
 | |
| `GuzzleHttp\Psr7\PumpStream`
 | |
| 
 | |
| Provides a read only stream that pumps data from a PHP callable.
 | |
| 
 | |
| When invoking the provided callable, the PumpStream will pass the amount of
 | |
| data requested to read to the callable. The callable can choose to ignore
 | |
| this value and return fewer or more bytes than requested. Any extra data
 | |
| returned by the provided callable is buffered internally until drained using
 | |
| the read() function of the PumpStream. The provided callable MUST return
 | |
| false when there is no more data to read.
 | |
| 
 | |
| 
 | |
| ## Implementing stream decorators
 | |
| 
 | |
| Creating a stream decorator is very easy thanks to the
 | |
| `GuzzleHttp\Psr7\StreamDecoratorTrait`. This trait provides methods that
 | |
| implement `Psr\Http\Message\StreamInterface` by proxying to an underlying
 | |
| stream. Just `use` the `StreamDecoratorTrait` and implement your custom
 | |
| methods.
 | |
| 
 | |
| For example, let's say we wanted to call a specific function each time the last
 | |
| byte is read from a stream. This could be implemented by overriding the
 | |
| `read()` method.
 | |
| 
 | |
| ```php
 | |
| use Psr\Http\Message\StreamInterface;
 | |
| use GuzzleHttp\Psr7\StreamDecoratorTrait;
 | |
| 
 | |
| class EofCallbackStream implements StreamInterface
 | |
| {
 | |
|     use StreamDecoratorTrait;
 | |
| 
 | |
|     private $callback;
 | |
| 
 | |
|     public function __construct(StreamInterface $stream, callable $cb)
 | |
|     {
 | |
|         $this->stream = $stream;
 | |
|         $this->callback = $cb;
 | |
|     }
 | |
| 
 | |
|     public function read($length)
 | |
|     {
 | |
|         $result = $this->stream->read($length);
 | |
| 
 | |
|         // Invoke the callback when EOF is hit.
 | |
|         if ($this->eof()) {
 | |
|             call_user_func($this->callback);
 | |
|         }
 | |
| 
 | |
|         return $result;
 | |
|     }
 | |
| }
 | |
| ```
 | |
| 
 | |
| This decorator could be added to any existing stream and used like so:
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7;
 | |
| 
 | |
| $original = Psr7\stream_for('foo');
 | |
| 
 | |
| $eofStream = new EofCallbackStream($original, function () {
 | |
|     echo 'EOF!';
 | |
| });
 | |
| 
 | |
| $eofStream->read(2);
 | |
| $eofStream->read(1);
 | |
| // echoes "EOF!"
 | |
| $eofStream->seek(0);
 | |
| $eofStream->read(3);
 | |
| // echoes "EOF!"
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## PHP StreamWrapper
 | |
| 
 | |
| You can use the `GuzzleHttp\Psr7\StreamWrapper` class if you need to use a
 | |
| PSR-7 stream as a PHP stream resource.
 | |
| 
 | |
| Use the `GuzzleHttp\Psr7\StreamWrapper::getResource()` method to create a PHP
 | |
| stream from a PSR-7 stream.
 | |
| 
 | |
| ```php
 | |
| use GuzzleHttp\Psr7\StreamWrapper;
 | |
| 
 | |
| $stream = GuzzleHttp\Psr7\stream_for('hello!');
 | |
| $resource = StreamWrapper::getResource($stream);
 | |
| echo fread($resource, 6); // outputs hello!
 | |
| ```
 | |
| 
 | |
| 
 | |
| # Function API
 | |
| 
 | |
| There are various functions available under the `GuzzleHttp\Psr7` namespace.
 | |
| 
 | |
| 
 | |
| ## `function str`
 | |
| 
 | |
| `function str(MessageInterface $message)`
 | |
| 
 | |
| Returns the string representation of an HTTP message.
 | |
| 
 | |
| ```php
 | |
| $request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
 | |
| echo GuzzleHttp\Psr7\str($request);
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## `function uri_for`
 | |
| 
 | |
| `function uri_for($uri)`
 | |
| 
 | |
| This function accepts a string or `Psr\Http\Message\UriInterface` and returns a
 | |
| UriInterface for the given value. If the value is already a `UriInterface`, it
 | |
| is returned as-is.
 | |
| 
 | |
| ```php
 | |
| $uri = GuzzleHttp\Psr7\uri_for('http://example.com');
 | |
| assert($uri === GuzzleHttp\Psr7\uri_for($uri));
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## `function stream_for`
 | |
| 
 | |
| `function stream_for($resource = '', array $options = [])`
 | |
| 
 | |
| Create a new stream based on the input type.
 | |
| 
 | |
| Options is an associative array that can contain the following keys:
 | |
| 
 | |
| * - metadata: Array of custom metadata.
 | |
| * - size: Size of the stream.
 | |
| 
 | |
| This method accepts the following `$resource` types:
 | |
| 
 | |
| - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
 | |
| - `string`: Creates a stream object that uses the given string as the contents.
 | |
| - `resource`: Creates a stream object that wraps the given PHP stream resource.
 | |
| - `Iterator`: If the provided value implements `Iterator`, then a read-only
 | |
|   stream object will be created that wraps the given iterable. Each time the
 | |
|   stream is read from, data from the iterator will fill a buffer and will be
 | |
|   continuously called until the buffer is equal to the requested read size.
 | |
|   Subsequent read calls will first read from the buffer and then call `next`
 | |
|   on the underlying iterator until it is exhausted.
 | |
| - `object` with `__toString()`: If the object has the `__toString()` method,
 | |
|   the object will be cast to a string and then a stream will be returned that
 | |
|   uses the string value.
 | |
| - `NULL`: When `null` is passed, an empty stream object is returned.
 | |
| - `callable` When a callable is passed, a read-only stream object will be
 | |
|   created that invokes the given callable. The callable is invoked with the
 | |
|   number of suggested bytes to read. The callable can return any number of
 | |
|   bytes, but MUST return `false` when there is no more data to return. The
 | |
|   stream object that wraps the callable will invoke the callable until the
 | |
|   number of requested bytes are available. Any additional bytes will be
 | |
|   buffered and used in subsequent reads.
 | |
| 
 | |
| ```php
 | |
| $stream = GuzzleHttp\Psr7\stream_for('foo');
 | |
| $stream = GuzzleHttp\Psr7\stream_for(fopen('/path/to/file', 'r'));
 | |
| 
 | |
| $generator function ($bytes) {
 | |
|     for ($i = 0; $i < $bytes; $i++) {
 | |
|         yield ' ';
 | |
|     }
 | |
| }
 | |
| 
 | |
| $stream = GuzzleHttp\Psr7\stream_for($generator(100));
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## `function parse_header`
 | |
| 
 | |
| `function parse_header($header)`
 | |
| 
 | |
| Parse an array of header values containing ";" separated data into an array of
 | |
| associative arrays representing the header key value pair data of the header.
 | |
| When a parameter does not contain a value, but just contains a key, this
 | |
| function will inject a key with a '' string value.
 | |
| 
 | |
| 
 | |
| ## `function normalize_header`
 | |
| 
 | |
| `function normalize_header($header)`
 | |
| 
 | |
| Converts an array of header values that may contain comma separated headers
 | |
| into an array of headers with no comma separated values.
 | |
| 
 | |
| 
 | |
| ## `function modify_request`
 | |
| 
 | |
| `function modify_request(RequestInterface $request, array $changes)`
 | |
| 
 | |
| Clone and modify a request with the given changes. This method is useful for
 | |
| reducing the number of clones needed to mutate a message.
 | |
| 
 | |
| The changes can be one of:
 | |
| 
 | |
| - method: (string) Changes the HTTP method.
 | |
| - set_headers: (array) Sets the given headers.
 | |
| - remove_headers: (array) Remove the given headers.
 | |
| - body: (mixed) Sets the given body.
 | |
| - uri: (UriInterface) Set the URI.
 | |
| - query: (string) Set the query string value of the URI.
 | |
| - version: (string) Set the protocol version.
 | |
| 
 | |
| 
 | |
| ## `function rewind_body`
 | |
| 
 | |
| `function rewind_body(MessageInterface $message)`
 | |
| 
 | |
| Attempts to rewind a message body and throws an exception on failure. The body
 | |
| of the message will only be rewound if a call to `tell()` returns a value other
 | |
| than `0`.
 | |
| 
 | |
| 
 | |
| ## `function try_fopen`
 | |
| 
 | |
| `function try_fopen($filename, $mode)`
 | |
| 
 | |
| Safely opens a PHP stream resource using a filename.
 | |
| 
 | |
| When fopen fails, PHP normally raises a warning. This function adds an error
 | |
| handler that checks for errors and throws an exception instead.
 | |
| 
 | |
| 
 | |
| ## `function copy_to_string`
 | |
| 
 | |
| `function copy_to_string(StreamInterface $stream, $maxLen = -1)`
 | |
| 
 | |
| Copy the contents of a stream into a string until the given number of bytes
 | |
| have been read.
 | |
| 
 | |
| 
 | |
| ## `function copy_to_stream`
 | |
| 
 | |
| `function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)`
 | |
| 
 | |
| Copy the contents of a stream into another stream until the given number of
 | |
| bytes have been read.
 | |
| 
 | |
| 
 | |
| ## `function hash`
 | |
| 
 | |
| `function hash(StreamInterface $stream, $algo, $rawOutput = false)`
 | |
| 
 | |
| Calculate a hash of a Stream. This method reads the entire stream to calculate
 | |
| a rolling hash (based on PHP's hash_init functions).
 | |
| 
 | |
| 
 | |
| ## `function readline`
 | |
| 
 | |
| `function readline(StreamInterface $stream, $maxLength = null)`
 | |
| 
 | |
| Read a line from the stream up to the maximum allowed buffer length.
 | |
| 
 | |
| 
 | |
| ## `function parse_request`
 | |
| 
 | |
| `function parse_request($message)`
 | |
| 
 | |
| Parses a request message string into a request object.
 | |
| 
 | |
| 
 | |
| ## `function parse_response`
 | |
| 
 | |
| `function parse_response($message)`
 | |
| 
 | |
| Parses a response message string into a response object.
 | |
| 
 | |
| 
 | |
| ## `function parse_query`
 | |
| 
 | |
| `function parse_query($str, $urlEncoding = true)`
 | |
| 
 | |
| Parse a query string into an associative array.
 | |
| 
 | |
| If multiple values are found for the same key, the value of that key value pair
 | |
| will become an array. This function does not parse nested PHP style arrays into
 | |
| an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into
 | |
| `['foo[a]' => '1', 'foo[b]' => '2']`).
 | |
| 
 | |
| 
 | |
| ## `function build_query`
 | |
| 
 | |
| `function build_query(array $params, $encoding = PHP_QUERY_RFC3986)`
 | |
| 
 | |
| Build a query string from an array of key value pairs.
 | |
| 
 | |
| This function can use the return value of parse_query() to build a query string.
 | |
| This function does not modify the provided keys when an array is encountered
 | |
| (like http_build_query would).
 | |
| 
 | |
| 
 | |
| ## `function mimetype_from_filename`
 | |
| 
 | |
| `function mimetype_from_filename($filename)`
 | |
| 
 | |
| Determines the mimetype of a file by looking at its extension.
 | |
| 
 | |
| 
 | |
| ## `function mimetype_from_extension`
 | |
| 
 | |
| `function mimetype_from_extension($extension)`
 | |
| 
 | |
| Maps a file extensions to a mimetype.
 | |
| 
 | |
| 
 | |
| # Static URI methods
 | |
| 
 | |
| The `GuzzleHttp\Psr7\Uri` class has several static methods to manipulate URIs.
 | |
| 
 | |
| 
 | |
| ## `GuzzleHttp\Psr7\Uri::removeDotSegments`
 | |
| 
 | |
| `public static function removeDotSegments(string $path): string`
 | |
| 
 | |
| Removes dot segments from a path and returns the new path.
 | |
| 
 | |
| See http://tools.ietf.org/html/rfc3986#section-5.2.4
 | |
| 
 | |
| 
 | |
| ## `GuzzleHttp\Psr7\Uri::resolve`
 | |
| 
 | |
| `public static function resolve(UriInterface $base, $rel): UriInterface`
 | |
| 
 | |
| Resolve a base URI with a relative URI and return a new URI.
 | |
| 
 | |
| See http://tools.ietf.org/html/rfc3986#section-5
 | |
| 
 | |
| 
 | |
| ## `GuzzleHttp\Psr7\Uri::withQueryValue`
 | |
| 
 | |
| `public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface`
 | |
| 
 | |
| Create a new URI with a specific query string value.
 | |
| 
 | |
| Any existing query string values that exactly match the provided key are
 | |
| removed and replaced with the given key value pair.
 | |
| 
 | |
| 
 | |
| ## `GuzzleHttp\Psr7\Uri::withoutQueryValue`
 | |
| 
 | |
| `public static function withoutQueryValue(UriInterface $uri, $key): UriInterface`
 | |
| 
 | |
| Create a new URI with a specific query string value removed.
 | |
| 
 | |
| Any existing query string values that exactly match the provided key are
 | |
| removed.
 | |
| 
 | |
| 
 | |
| ## `GuzzleHttp\Psr7\Uri::fromParts`
 | |
| 
 | |
| `public static function fromParts(array $parts): UriInterface`
 | |
| 
 | |
| Create a `GuzzleHttp\Psr7\Uri` object from a hash of `parse_url` parts.
 | 
