1 # PSR-7 Message Implementation
3 This repository contains a full [PSR-7](http://www.php-fig.org/psr/psr-7/)
4 message implementation, several stream decorators, and some helpful
5 functionality like query string parsing.
8 [![Build Status](https://travis-ci.org/guzzle/psr7.svg?branch=master)](https://travis-ci.org/guzzle/psr7)
11 # Stream implementation
13 This package comes with a number of stream implementations and stream
19 `GuzzleHttp\Psr7\AppendStream`
21 Reads from multiple streams, one after the other.
26 $a = Psr7\stream_for('abc, ');
27 $b = Psr7\stream_for('123.');
28 $composed = new Psr7\AppendStream([$a, $b]);
30 $composed->addStream(Psr7\stream_for(' Above all listen to me'));
32 echo $composed; // abc, 123. Above all listen to me.
38 `GuzzleHttp\Psr7\BufferStream`
40 Provides a buffer stream that can be written to fill a buffer, and read
41 from to remove bytes from the buffer.
43 This stream returns a "hwm" metadata value that tells upstream consumers
44 what the configured high water mark of the stream is, or the maximum
45 preferred size of the buffer.
50 // When more than 1024 bytes are in the buffer, it will begin returning
51 // false to writes. This is an indication that writers should slow down.
52 $buffer = new Psr7\BufferStream(1024);
58 The CachingStream is used to allow seeking over previously read bytes on
59 non-seekable streams. This can be useful when transferring a non-seekable
60 entity body fails due to needing to rewind the stream (for example, resulting
61 from a redirect). Data that is read from the remote stream will be buffered in
62 a PHP temp stream so that previously read bytes are cached first in memory,
68 $original = Psr7\stream_for(fopen('http://www.google.com', 'r'));
69 $stream = new Psr7\CachingStream($original);
83 `GuzzleHttp\Psr7\DroppingStream`
85 Stream decorator that begins dropping data once the size of the underlying
86 stream becomes too full.
91 // Create an empty stream
92 $stream = Psr7\stream_for();
94 // Start dropping data when the stream has more than 10 bytes
95 $dropping = new Psr7\DroppingStream($stream, 10);
97 $dropping->write('01234567890123456789');
98 echo $stream; // 0123456789
104 `GuzzleHttp\Psr7\FnStream`
106 Compose stream implementations based on a hash of functions.
108 Allows for easy testing and extension of a provided stream without needing
109 to create a concrete class for a simple extension point.
115 $stream = Psr7\stream_for('hi');
116 $fnStream = Psr7\FnStream::decorate($stream, [
117 'rewind' => function () use ($stream) {
118 echo 'About to rewind - ';
125 // Outputs: About to rewind - rewound!
131 `GuzzleHttp\Psr7\InflateStream`
133 Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
135 This stream decorator skips the first 10 bytes of the given stream to remove
136 the gzip header, converts the provided stream to a PHP stream resource,
137 then appends the zlib.inflate filter. The stream is then converted back
138 to a Guzzle stream resource to be used as a Guzzle stream.
143 `GuzzleHttp\Psr7\LazyOpenStream`
145 Lazily reads or writes to a file that is opened only after an IO operation
146 take place on the stream.
151 $stream = new Psr7\LazyOpenStream('/path/to/file', 'r');
152 // The file has not yet been opened...
154 echo $stream->read(10);
155 // The file is opened and read from only when needed.
161 `GuzzleHttp\Psr7\LimitStream`
163 LimitStream can be used to read a subset or slice of an existing stream object.
164 This can be useful for breaking a large file into smaller pieces to be sent in
165 chunks (e.g. Amazon S3's multipart upload API).
170 $original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+'));
171 echo $original->getSize();
174 // Limit the size of the body to 1024 bytes and start reading from byte 2048
175 $stream = new Psr7\LimitStream($original, 1024, 2048);
176 echo $stream->getSize();
178 echo $stream->tell();
185 `GuzzleHttp\Psr7\MultipartStream`
187 Stream that when read returns bytes for a streaming multipart or
188 multipart/form-data stream.
193 `GuzzleHttp\Psr7\NoSeekStream`
195 NoSeekStream wraps a stream and does not allow seeking.
200 $original = Psr7\stream_for('foo');
201 $noSeek = new Psr7\NoSeekStream($original);
203 echo $noSeek->read(3);
205 var_export($noSeek->isSeekable());
208 var_export($noSeek->read(3));
215 `GuzzleHttp\Psr7\PumpStream`
217 Provides a read only stream that pumps data from a PHP callable.
219 When invoking the provided callable, the PumpStream will pass the amount of
220 data requested to read to the callable. The callable can choose to ignore
221 this value and return fewer or more bytes than requested. Any extra data
222 returned by the provided callable is buffered internally until drained using
223 the read() function of the PumpStream. The provided callable MUST return
224 false when there is no more data to read.
227 ## Implementing stream decorators
229 Creating a stream decorator is very easy thanks to the
230 `GuzzleHttp\Psr7\StreamDecoratorTrait`. This trait provides methods that
231 implement `Psr\Http\Message\StreamInterface` by proxying to an underlying
232 stream. Just `use` the `StreamDecoratorTrait` and implement your custom
235 For example, let's say we wanted to call a specific function each time the last
236 byte is read from a stream. This could be implemented by overriding the
240 use Psr\Http\Message\StreamInterface;
241 use GuzzleHttp\Psr7\StreamDecoratorTrait;
243 class EofCallbackStream implements StreamInterface
245 use StreamDecoratorTrait;
249 public function __construct(StreamInterface $stream, callable $cb)
251 $this->stream = $stream;
252 $this->callback = $cb;
255 public function read($length)
257 $result = $this->stream->read($length);
259 // Invoke the callback when EOF is hit.
261 call_user_func($this->callback);
269 This decorator could be added to any existing stream and used like so:
274 $original = Psr7\stream_for('foo');
276 $eofStream = new EofCallbackStream($original, function () {
291 You can use the `GuzzleHttp\Psr7\StreamWrapper` class if you need to use a
292 PSR-7 stream as a PHP stream resource.
294 Use the `GuzzleHttp\Psr7\StreamWrapper::getResource()` method to create a PHP
295 stream from a PSR-7 stream.
298 use GuzzleHttp\Psr7\StreamWrapper;
300 $stream = GuzzleHttp\Psr7\stream_for('hello!');
301 $resource = StreamWrapper::getResource($stream);
302 echo fread($resource, 6); // outputs hello!
308 There are various functions available under the `GuzzleHttp\Psr7` namespace.
313 `function str(MessageInterface $message)`
315 Returns the string representation of an HTTP message.
318 $request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
319 echo GuzzleHttp\Psr7\str($request);
323 ## `function uri_for`
325 `function uri_for($uri)`
327 This function accepts a string or `Psr\Http\Message\UriInterface` and returns a
328 UriInterface for the given value. If the value is already a `UriInterface`, it
332 $uri = GuzzleHttp\Psr7\uri_for('http://example.com');
333 assert($uri === GuzzleHttp\Psr7\uri_for($uri));
337 ## `function stream_for`
339 `function stream_for($resource = '', array $options = [])`
341 Create a new stream based on the input type.
343 Options is an associative array that can contain the following keys:
345 * - metadata: Array of custom metadata.
346 * - size: Size of the stream.
348 This method accepts the following `$resource` types:
350 - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
351 - `string`: Creates a stream object that uses the given string as the contents.
352 - `resource`: Creates a stream object that wraps the given PHP stream resource.
353 - `Iterator`: If the provided value implements `Iterator`, then a read-only
354 stream object will be created that wraps the given iterable. Each time the
355 stream is read from, data from the iterator will fill a buffer and will be
356 continuously called until the buffer is equal to the requested read size.
357 Subsequent read calls will first read from the buffer and then call `next`
358 on the underlying iterator until it is exhausted.
359 - `object` with `__toString()`: If the object has the `__toString()` method,
360 the object will be cast to a string and then a stream will be returned that
361 uses the string value.
362 - `NULL`: When `null` is passed, an empty stream object is returned.
363 - `callable` When a callable is passed, a read-only stream object will be
364 created that invokes the given callable. The callable is invoked with the
365 number of suggested bytes to read. The callable can return any number of
366 bytes, but MUST return `false` when there is no more data to return. The
367 stream object that wraps the callable will invoke the callable until the
368 number of requested bytes are available. Any additional bytes will be
369 buffered and used in subsequent reads.
372 $stream = GuzzleHttp\Psr7\stream_for('foo');
373 $stream = GuzzleHttp\Psr7\stream_for(fopen('/path/to/file', 'r'));
375 $generator = function ($bytes) {
376 for ($i = 0; $i < $bytes; $i++) {
381 $stream = GuzzleHttp\Psr7\stream_for($generator(100));
385 ## `function parse_header`
387 `function parse_header($header)`
389 Parse an array of header values containing ";" separated data into an array of
390 associative arrays representing the header key value pair data of the header.
391 When a parameter does not contain a value, but just contains a key, this
392 function will inject a key with a '' string value.
395 ## `function normalize_header`
397 `function normalize_header($header)`
399 Converts an array of header values that may contain comma separated headers
400 into an array of headers with no comma separated values.
403 ## `function modify_request`
405 `function modify_request(RequestInterface $request, array $changes)`
407 Clone and modify a request with the given changes. This method is useful for
408 reducing the number of clones needed to mutate a message.
410 The changes can be one of:
412 - method: (string) Changes the HTTP method.
413 - set_headers: (array) Sets the given headers.
414 - remove_headers: (array) Remove the given headers.
415 - body: (mixed) Sets the given body.
416 - uri: (UriInterface) Set the URI.
417 - query: (string) Set the query string value of the URI.
418 - version: (string) Set the protocol version.
421 ## `function rewind_body`
423 `function rewind_body(MessageInterface $message)`
425 Attempts to rewind a message body and throws an exception on failure. The body
426 of the message will only be rewound if a call to `tell()` returns a value other
430 ## `function try_fopen`
432 `function try_fopen($filename, $mode)`
434 Safely opens a PHP stream resource using a filename.
436 When fopen fails, PHP normally raises a warning. This function adds an error
437 handler that checks for errors and throws an exception instead.
440 ## `function copy_to_string`
442 `function copy_to_string(StreamInterface $stream, $maxLen = -1)`
444 Copy the contents of a stream into a string until the given number of bytes
448 ## `function copy_to_stream`
450 `function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)`
452 Copy the contents of a stream into another stream until the given number of
453 bytes have been read.
458 `function hash(StreamInterface $stream, $algo, $rawOutput = false)`
460 Calculate a hash of a Stream. This method reads the entire stream to calculate
461 a rolling hash (based on PHP's hash_init functions).
464 ## `function readline`
466 `function readline(StreamInterface $stream, $maxLength = null)`
468 Read a line from the stream up to the maximum allowed buffer length.
471 ## `function parse_request`
473 `function parse_request($message)`
475 Parses a request message string into a request object.
478 ## `function parse_response`
480 `function parse_response($message)`
482 Parses a response message string into a response object.
485 ## `function parse_query`
487 `function parse_query($str, $urlEncoding = true)`
489 Parse a query string into an associative array.
491 If multiple values are found for the same key, the value of that key value pair
492 will become an array. This function does not parse nested PHP style arrays into
493 an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into
494 `['foo[a]' => '1', 'foo[b]' => '2']`).
497 ## `function build_query`
499 `function build_query(array $params, $encoding = PHP_QUERY_RFC3986)`
501 Build a query string from an array of key value pairs.
503 This function can use the return value of parse_query() to build a query string.
504 This function does not modify the provided keys when an array is encountered
505 (like http_build_query would).
508 ## `function mimetype_from_filename`
510 `function mimetype_from_filename($filename)`
512 Determines the mimetype of a file by looking at its extension.
515 ## `function mimetype_from_extension`
517 `function mimetype_from_extension($extension)`
519 Maps a file extensions to a mimetype.
522 # Additional URI Methods
524 Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class,
525 this library also provides additional functionality when working with URIs as static methods.
529 An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference.
530 An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI,
531 the base URI. Relative references can be divided into several forms according to
532 [RFC 3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2):
534 - network-path references, e.g. `//example.com/path`
535 - absolute-path references, e.g. `/path`
536 - relative-path references, e.g. `subpath`
538 The following methods can be used to identify the type of the URI.
540 ### `GuzzleHttp\Psr7\Uri::isAbsolute`
542 `public static function isAbsolute(UriInterface $uri): bool`
544 Whether the URI is absolute, i.e. it has a scheme.
546 ### `GuzzleHttp\Psr7\Uri::isNetworkPathReference`
548 `public static function isNetworkPathReference(UriInterface $uri): bool`
550 Whether the URI is a network-path reference. A relative reference that begins with two slash characters is
551 termed an network-path reference.
553 ### `GuzzleHttp\Psr7\Uri::isAbsolutePathReference`
555 `public static function isAbsolutePathReference(UriInterface $uri): bool`
557 Whether the URI is a absolute-path reference. A relative reference that begins with a single slash character is
558 termed an absolute-path reference.
560 ### `GuzzleHttp\Psr7\Uri::isRelativePathReference`
562 `public static function isRelativePathReference(UriInterface $uri): bool`
564 Whether the URI is a relative-path reference. A relative reference that does not begin with a slash character is
565 termed a relative-path reference.
567 ### `GuzzleHttp\Psr7\Uri::isSameDocumentReference`
569 `public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool`
571 Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its
572 fragment component, identical to the base URI. When no base URI is given, only an empty URI reference
573 (apart from its fragment) is considered a same-document reference.
577 Additional methods to work with URI components.
579 ### `GuzzleHttp\Psr7\Uri::isDefaultPort`
581 `public static function isDefaultPort(UriInterface $uri): bool`
583 Whether the URI has the default port of the current scheme. `Psr\Http\Message\UriInterface::getPort` may return null
584 or the standard port. This method can be used independently of the implementation.
586 ### `GuzzleHttp\Psr7\Uri::composeComponents`
588 `public static function composeComponents($scheme, $authority, $path, $query, $fragment): string`
590 Composes a URI reference string from its various components according to
591 [RFC 3986 Section 5.3](https://tools.ietf.org/html/rfc3986#section-5.3). Usually this method does not need to be called
592 manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`.
594 ### `GuzzleHttp\Psr7\Uri::fromParts`
596 `public static function fromParts(array $parts): UriInterface`
598 Creates a URI from a hash of [`parse_url`](http://php.net/manual/en/function.parse-url.php) components.
601 ### `GuzzleHttp\Psr7\Uri::withQueryValue`
603 `public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface`
605 Creates a new URI with a specific query string value. Any existing query string values that exactly match the
606 provided key are removed and replaced with the given key value pair. A value of null will set the query string
607 key without a value, e.g. "key" instead of "key=value".
609 ### `GuzzleHttp\Psr7\Uri::withQueryValues`
611 `public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface`
613 Creates a new URI with multiple query string values. It has the same behavior as `withQueryValue()` but for an
614 associative array of key => value.
616 ### `GuzzleHttp\Psr7\Uri::withoutQueryValue`
618 `public static function withoutQueryValue(UriInterface $uri, $key): UriInterface`
620 Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the
621 provided key are removed.
623 ## Reference Resolution
625 `GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according
626 to [RFC 3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5). This is for example also what web browsers
627 do when resolving a link in a website based on the current request URI.
629 ### `GuzzleHttp\Psr7\UriResolver::resolve`
631 `public static function resolve(UriInterface $base, UriInterface $rel): UriInterface`
633 Converts the relative URI into a new URI that is resolved against the base URI.
635 ### `GuzzleHttp\Psr7\UriResolver::removeDotSegments`
637 `public static function removeDotSegments(string $path): string`
639 Removes dot segments from a path and returns the new path according to
640 [RFC 3986 Section 5.2.4](https://tools.ietf.org/html/rfc3986#section-5.2.4).
642 ### `GuzzleHttp\Psr7\UriResolver::relativize`
644 `public static function relativize(UriInterface $base, UriInterface $target): UriInterface`
646 Returns the target URI as a relative reference from the base URI. This method is the counterpart to resolve():
649 (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
652 One use-case is to use the current request URI as base URI and then generate relative links in your documents
653 to reduce the document size or offer self-contained downloadable document archives.
656 $base = new Uri('http://example.com/a/b/');
657 echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'.
658 echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'.
659 echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
660 echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'.
663 ## Normalization and Comparison
665 `GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to
666 [RFC 3986 Section 6](https://tools.ietf.org/html/rfc3986#section-6).
668 ### `GuzzleHttp\Psr7\UriNormalizer::normalize`
670 `public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS): UriInterface`
672 Returns a normalized URI. The scheme and host component are already normalized to lowercase per PSR-7 UriInterface.
673 This methods adds additional normalizations that can be configured with the `$flags` parameter which is a bitmask
674 of normalizations to apply. The following normalizations are available:
676 - `UriNormalizer::PRESERVING_NORMALIZATIONS`
678 Default normalizations which only include the ones that preserve semantics.
680 - `UriNormalizer::CAPITALIZE_PERCENT_ENCODING`
682 All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized.
684 Example: `http://example.org/a%c2%b1b` → `http://example.org/a%C2%B1b`
686 - `UriNormalizer::DECODE_UNRESERVED_CHARACTERS`
688 Decodes percent-encoded octets of unreserved characters. For consistency, percent-encoded octets in the ranges of
689 ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should
690 not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved
691 characters by URI normalizers.
693 Example: `http://example.org/%7Eusern%61me/` → `http://example.org/~username/`
695 - `UriNormalizer::CONVERT_EMPTY_PATH`
697 Converts the empty path to "/" for http and https URIs.
699 Example: `http://example.org` → `http://example.org/`
701 - `UriNormalizer::REMOVE_DEFAULT_HOST`
703 Removes the default host of the given URI scheme from the URI. Only the "file" scheme defines the default host
704 "localhost". All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile` are equivalent according to
707 Example: `file://localhost/myfile` → `file:///myfile`
709 - `UriNormalizer::REMOVE_DEFAULT_PORT`
711 Removes the default port of the given URI scheme from the URI.
713 Example: `http://example.org:80/` → `http://example.org/`
715 - `UriNormalizer::REMOVE_DOT_SEGMENTS`
717 Removes unnecessary dot-segments. Dot-segments in relative-path references are not removed as it would
718 change the semantics of the URI reference.
720 Example: `http://example.org/../a/b/../c/./d.html` → `http://example.org/a/c/d.html`
722 - `UriNormalizer::REMOVE_DUPLICATE_SLASHES`
724 Paths which include two or more adjacent slashes are converted to one. Webservers usually ignore duplicate slashes
725 and treat those URIs equivalent. But in theory those URIs do not need to be equivalent. So this normalization
726 may change the semantics. Encoded slashes (%2F) are not removed.
728 Example: `http://example.org//foo///bar.html` → `http://example.org/foo/bar.html`
730 - `UriNormalizer::SORT_QUERY_PARAMETERS`
732 Sort query parameters with their values in alphabetical order. However, the order of parameters in a URI may be
733 significant (this is not defined by the standard). So this normalization is not safe and may change the semantics
736 Example: `?lang=en&article=fred` → `?article=fred&lang=en`
738 ### `GuzzleHttp\Psr7\UriNormalizer::isEquivalent`
740 `public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS): bool`
742 Whether two URIs can be considered equivalent. Both URIs are normalized automatically before comparison with the given
743 `$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent.
744 This of course assumes they will be resolved against the same base URI. If this is not the case, determination of
745 equivalence or difference of relative references does not mean anything.