dokuwiki-matrixnotifierwas-plugin – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 # PSR-7 Message Implementation
2  
3 This repository contains a full [PSR-7](https://www.php-fig.org/psr/psr-7/)
4 message implementation, several stream decorators, and some helpful
5 functionality like query string parsing.
6  
7 ![CI](https://github.com/guzzle/psr7/workflows/CI/badge.svg)
8 ![Static analysis](https://github.com/guzzle/psr7/workflows/Static%20analysis/badge.svg)
9  
10  
11 ## Features
12  
13 This package comes with a number of stream implementations and stream
14 decorators.
15  
16  
17 ## Installation
18  
19 ```shell
20 composer require guzzlehttp/psr7
21 ```
22  
23 ## Version Guidance
24  
25 | Version | Status | PHP Version |
26 |---------|---------------------|--------------|
27 | 1.x | Security fixes only | >=5.4,<8.1 |
28 | 2.x | Latest | >=7.2.5,<8.4 |
29  
30  
31 ## AppendStream
32  
33 `GuzzleHttp\Psr7\AppendStream`
34  
35 Reads from multiple streams, one after the other.
36  
37 ```php
38 use GuzzleHttp\Psr7;
39  
40 $a = Psr7\Utils::streamFor('abc, ');
41 $b = Psr7\Utils::streamFor('123.');
42 $composed = new Psr7\AppendStream([$a, $b]);
43  
44 $composed->addStream(Psr7\Utils::streamFor(' Above all listen to me'));
45  
46 echo $composed; // abc, 123. Above all listen to me.
47 ```
48  
49  
50 ## BufferStream
51  
52 `GuzzleHttp\Psr7\BufferStream`
53  
54 Provides a buffer stream that can be written to fill a buffer, and read
55 from to remove bytes from the buffer.
56  
57 This stream returns a "hwm" metadata value that tells upstream consumers
58 what the configured high water mark of the stream is, or the maximum
59 preferred size of the buffer.
60  
61 ```php
62 use GuzzleHttp\Psr7;
63  
64 // When more than 1024 bytes are in the buffer, it will begin returning
65 // false to writes. This is an indication that writers should slow down.
66 $buffer = new Psr7\BufferStream(1024);
67 ```
68  
69  
70 ## CachingStream
71  
72 The CachingStream is used to allow seeking over previously read bytes on
73 non-seekable streams. This can be useful when transferring a non-seekable
74 entity body fails due to needing to rewind the stream (for example, resulting
75 from a redirect). Data that is read from the remote stream will be buffered in
76 a PHP temp stream so that previously read bytes are cached first in memory,
77 then on disk.
78  
79 ```php
80 use GuzzleHttp\Psr7;
81  
82 $original = Psr7\Utils::streamFor(fopen('http://www.google.com', 'r'));
83 $stream = new Psr7\CachingStream($original);
84  
85 $stream->read(1024);
86 echo $stream->tell();
87 // 1024
88  
89 $stream->seek(0);
90 echo $stream->tell();
91 // 0
92 ```
93  
94  
95 ## DroppingStream
96  
97 `GuzzleHttp\Psr7\DroppingStream`
98  
99 Stream decorator that begins dropping data once the size of the underlying
100 stream becomes too full.
101  
102 ```php
103 use GuzzleHttp\Psr7;
104  
105 // Create an empty stream
106 $stream = Psr7\Utils::streamFor();
107  
108 // Start dropping data when the stream has more than 10 bytes
109 $dropping = new Psr7\DroppingStream($stream, 10);
110  
111 $dropping->write('01234567890123456789');
112 echo $stream; // 0123456789
113 ```
114  
115  
116 ## FnStream
117  
118 `GuzzleHttp\Psr7\FnStream`
119  
120 Compose stream implementations based on a hash of functions.
121  
122 Allows for easy testing and extension of a provided stream without needing
123 to create a concrete class for a simple extension point.
124  
125 ```php
126  
127 use GuzzleHttp\Psr7;
128  
129 $stream = Psr7\Utils::streamFor('hi');
130 $fnStream = Psr7\FnStream::decorate($stream, [
131 'rewind' => function () use ($stream) {
132 echo 'About to rewind - ';
133 $stream->rewind();
134 echo 'rewound!';
135 }
136 ]);
137  
138 $fnStream->rewind();
139 // Outputs: About to rewind - rewound!
140 ```
141  
142  
143 ## InflateStream
144  
145 `GuzzleHttp\Psr7\InflateStream`
146  
147 Uses PHP's zlib.inflate filter to inflate zlib (HTTP deflate, RFC1950) or gzipped (RFC1952) content.
148  
149 This stream decorator converts the provided stream to a PHP stream resource,
150 then appends the zlib.inflate filter. The stream is then converted back
151 to a Guzzle stream resource to be used as a Guzzle stream.
152  
153  
154 ## LazyOpenStream
155  
156 `GuzzleHttp\Psr7\LazyOpenStream`
157  
158 Lazily reads or writes to a file that is opened only after an IO operation
159 take place on the stream.
160  
161 ```php
162 use GuzzleHttp\Psr7;
163  
164 $stream = new Psr7\LazyOpenStream('/path/to/file', 'r');
165 // The file has not yet been opened...
166  
167 echo $stream->read(10);
168 // The file is opened and read from only when needed.
169 ```
170  
171  
172 ## LimitStream
173  
174 `GuzzleHttp\Psr7\LimitStream`
175  
176 LimitStream can be used to read a subset or slice of an existing stream object.
177 This can be useful for breaking a large file into smaller pieces to be sent in
178 chunks (e.g. Amazon S3's multipart upload API).
179  
180 ```php
181 use GuzzleHttp\Psr7;
182  
183 $original = Psr7\Utils::streamFor(fopen('/tmp/test.txt', 'r+'));
184 echo $original->getSize();
185 // >>> 1048576
186  
187 // Limit the size of the body to 1024 bytes and start reading from byte 2048
188 $stream = new Psr7\LimitStream($original, 1024, 2048);
189 echo $stream->getSize();
190 // >>> 1024
191 echo $stream->tell();
192 // >>> 0
193 ```
194  
195  
196 ## MultipartStream
197  
198 `GuzzleHttp\Psr7\MultipartStream`
199  
200 Stream that when read returns bytes for a streaming multipart or
201 multipart/form-data stream.
202  
203  
204 ## NoSeekStream
205  
206 `GuzzleHttp\Psr7\NoSeekStream`
207  
208 NoSeekStream wraps a stream and does not allow seeking.
209  
210 ```php
211 use GuzzleHttp\Psr7;
212  
213 $original = Psr7\Utils::streamFor('foo');
214 $noSeek = new Psr7\NoSeekStream($original);
215  
216 echo $noSeek->read(3);
217 // foo
218 var_export($noSeek->isSeekable());
219 // false
220 $noSeek->seek(0);
221 var_export($noSeek->read(3));
222 // NULL
223 ```
224  
225  
226 ## PumpStream
227  
228 `GuzzleHttp\Psr7\PumpStream`
229  
230 Provides a read only stream that pumps data from a PHP callable.
231  
232 When invoking the provided callable, the PumpStream will pass the amount of
233 data requested to read to the callable. The callable can choose to ignore
234 this value and return fewer or more bytes than requested. Any extra data
235 returned by the provided callable is buffered internally until drained using
236 the read() function of the PumpStream. The provided callable MUST return
237 false when there is no more data to read.
238  
239  
240 ## Implementing stream decorators
241  
242 Creating a stream decorator is very easy thanks to the
243 `GuzzleHttp\Psr7\StreamDecoratorTrait`. This trait provides methods that
244 implement `Psr\Http\Message\StreamInterface` by proxying to an underlying
245 stream. Just `use` the `StreamDecoratorTrait` and implement your custom
246 methods.
247  
248 For example, let's say we wanted to call a specific function each time the last
249 byte is read from a stream. This could be implemented by overriding the
250 `read()` method.
251  
252 ```php
253 use Psr\Http\Message\StreamInterface;
254 use GuzzleHttp\Psr7\StreamDecoratorTrait;
255  
256 class EofCallbackStream implements StreamInterface
257 {
258 use StreamDecoratorTrait;
259  
260 private $callback;
261  
262 private $stream;
263  
264 public function __construct(StreamInterface $stream, callable $cb)
265 {
266 $this->stream = $stream;
267 $this->callback = $cb;
268 }
269  
270 public function read($length)
271 {
272 $result = $this->stream->read($length);
273  
274 // Invoke the callback when EOF is hit.
275 if ($this->eof()) {
276 ($this->callback)();
277 }
278  
279 return $result;
280 }
281 }
282 ```
283  
284 This decorator could be added to any existing stream and used like so:
285  
286 ```php
287 use GuzzleHttp\Psr7;
288  
289 $original = Psr7\Utils::streamFor('foo');
290  
291 $eofStream = new EofCallbackStream($original, function () {
292 echo 'EOF!';
293 });
294  
295 $eofStream->read(2);
296 $eofStream->read(1);
297 // echoes "EOF!"
298 $eofStream->seek(0);
299 $eofStream->read(3);
300 // echoes "EOF!"
301 ```
302  
303  
304 ## PHP StreamWrapper
305  
306 You can use the `GuzzleHttp\Psr7\StreamWrapper` class if you need to use a
307 PSR-7 stream as a PHP stream resource.
308  
309 Use the `GuzzleHttp\Psr7\StreamWrapper::getResource()` method to create a PHP
310 stream from a PSR-7 stream.
311  
312 ```php
313 use GuzzleHttp\Psr7\StreamWrapper;
314  
315 $stream = GuzzleHttp\Psr7\Utils::streamFor('hello!');
316 $resource = StreamWrapper::getResource($stream);
317 echo fread($resource, 6); // outputs hello!
318 ```
319  
320  
321 # Static API
322  
323 There are various static methods available under the `GuzzleHttp\Psr7` namespace.
324  
325  
326 ## `GuzzleHttp\Psr7\Message::toString`
327  
328 `public static function toString(MessageInterface $message): string`
329  
330 Returns the string representation of an HTTP message.
331  
332 ```php
333 $request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
334 echo GuzzleHttp\Psr7\Message::toString($request);
335 ```
336  
337  
338 ## `GuzzleHttp\Psr7\Message::bodySummary`
339  
340 `public static function bodySummary(MessageInterface $message, int $truncateAt = 120): string|null`
341  
342 Get a short summary of the message body.
343  
344 Will return `null` if the response is not printable.
345  
346  
347 ## `GuzzleHttp\Psr7\Message::rewindBody`
348  
349 `public static function rewindBody(MessageInterface $message): void`
350  
351 Attempts to rewind a message body and throws an exception on failure.
352  
353 The body of the message will only be rewound if a call to `tell()`
354 returns a value other than `0`.
355  
356  
357 ## `GuzzleHttp\Psr7\Message::parseMessage`
358  
359 `public static function parseMessage(string $message): array`
360  
361 Parses an HTTP message into an associative array.
362  
363 The array contains the "start-line" key containing the start line of
364 the message, "headers" key containing an associative array of header
365 array values, and a "body" key containing the body of the message.
366  
367  
368 ## `GuzzleHttp\Psr7\Message::parseRequestUri`
369  
370 `public static function parseRequestUri(string $path, array $headers): string`
371  
372 Constructs a URI for an HTTP request message.
373  
374  
375 ## `GuzzleHttp\Psr7\Message::parseRequest`
376  
377 `public static function parseRequest(string $message): Request`
378  
379 Parses a request message string into a request object.
380  
381  
382 ## `GuzzleHttp\Psr7\Message::parseResponse`
383  
384 `public static function parseResponse(string $message): Response`
385  
386 Parses a response message string into a response object.
387  
388  
389 ## `GuzzleHttp\Psr7\Header::parse`
390  
391 `public static function parse(string|array $header): array`
392  
393 Parse an array of header values containing ";" separated data into an
394 array of associative arrays representing the header key value pair data
395 of the header. When a parameter does not contain a value, but just
396 contains a key, this function will inject a key with a '' string value.
397  
398  
399 ## `GuzzleHttp\Psr7\Header::splitList`
400  
401 `public static function splitList(string|string[] $header): string[]`
402  
403 Splits a HTTP header defined to contain a comma-separated list into
404 each individual value:
405  
406 ```
407 $knownEtags = Header::splitList($request->getHeader('if-none-match'));
408 ```
409  
410 Example headers include `accept`, `cache-control` and `if-none-match`.
411  
412  
413 ## `GuzzleHttp\Psr7\Header::normalize` (deprecated)
414  
415 `public static function normalize(string|array $header): array`
416  
417 `Header::normalize()` is deprecated in favor of [`Header::splitList()`](README.md#guzzlehttppsr7headersplitlist)
418 which performs the same operation with a cleaned up API and improved
419 documentation.
420  
421 Converts an array of header values that may contain comma separated
422 headers into an array of headers with no comma separated values.
423  
424  
425 ## `GuzzleHttp\Psr7\Query::parse`
426  
427 `public static function parse(string $str, int|bool $urlEncoding = true): array`
428  
429 Parse a query string into an associative array.
430  
431 If multiple values are found for the same key, the value of that key
432 value pair will become an array. This function does not parse nested
433 PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
434 will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
435  
436  
437 ## `GuzzleHttp\Psr7\Query::build`
438  
439 `public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986): string`
440  
441 Build a query string from an array of key value pairs.
442  
443 This function can use the return value of `parse()` to build a query
444 string. This function does not modify the provided keys when an array is
445 encountered (like `http_build_query()` would).
446  
447  
448 ## `GuzzleHttp\Psr7\Utils::caselessRemove`
449  
450 `public static function caselessRemove(iterable<string> $keys, $keys, array $data): array`
451  
452 Remove the items given by the keys, case insensitively from the data.
453  
454  
455 ## `GuzzleHttp\Psr7\Utils::copyToStream`
456  
457 `public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1): void`
458  
459 Copy the contents of a stream into another stream until the given number
460 of bytes have been read.
461  
462  
463 ## `GuzzleHttp\Psr7\Utils::copyToString`
464  
465 `public static function copyToString(StreamInterface $stream, int $maxLen = -1): string`
466  
467 Copy the contents of a stream into a string until the given number of
468 bytes have been read.
469  
470  
471 ## `GuzzleHttp\Psr7\Utils::hash`
472  
473 `public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = false): string`
474  
475 Calculate a hash of a stream.
476  
477 This method reads the entire stream to calculate a rolling hash, based on
478 PHP's `hash_init` functions.
479  
480  
481 ## `GuzzleHttp\Psr7\Utils::modifyRequest`
482  
483 `public static function modifyRequest(RequestInterface $request, array $changes): RequestInterface`
484  
485 Clone and modify a request with the given changes.
486  
487 This method is useful for reducing the number of clones needed to mutate
488 a message.
489  
490 - method: (string) Changes the HTTP method.
491 - set_headers: (array) Sets the given headers.
492 - remove_headers: (array) Remove the given headers.
493 - body: (mixed) Sets the given body.
494 - uri: (UriInterface) Set the URI.
495 - query: (string) Set the query string value of the URI.
496 - version: (string) Set the protocol version.
497  
498  
499 ## `GuzzleHttp\Psr7\Utils::readLine`
500  
501 `public static function readLine(StreamInterface $stream, int $maxLength = null): string`
502  
503 Read a line from the stream up to the maximum allowed buffer length.
504  
505  
506 ## `GuzzleHttp\Psr7\Utils::streamFor`
507  
508 `public static function streamFor(resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource = '', array $options = []): StreamInterface`
509  
510 Create a new stream based on the input type.
511  
512 Options is an associative array that can contain the following keys:
513  
514 - metadata: Array of custom metadata.
515 - size: Size of the stream.
516  
517 This method accepts the following `$resource` types:
518  
519 - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
520 - `string`: Creates a stream object that uses the given string as the contents.
521 - `resource`: Creates a stream object that wraps the given PHP stream resource.
522 - `Iterator`: If the provided value implements `Iterator`, then a read-only
523 stream object will be created that wraps the given iterable. Each time the
524 stream is read from, data from the iterator will fill a buffer and will be
525 continuously called until the buffer is equal to the requested read size.
526 Subsequent read calls will first read from the buffer and then call `next`
527 on the underlying iterator until it is exhausted.
528 - `object` with `__toString()`: If the object has the `__toString()` method,
529 the object will be cast to a string and then a stream will be returned that
530 uses the string value.
531 - `NULL`: When `null` is passed, an empty stream object is returned.
532 - `callable` When a callable is passed, a read-only stream object will be
533 created that invokes the given callable. The callable is invoked with the
534 number of suggested bytes to read. The callable can return any number of
535 bytes, but MUST return `false` when there is no more data to return. The
536 stream object that wraps the callable will invoke the callable until the
537 number of requested bytes are available. Any additional bytes will be
538 buffered and used in subsequent reads.
539  
540 ```php
541 $stream = GuzzleHttp\Psr7\Utils::streamFor('foo');
542 $stream = GuzzleHttp\Psr7\Utils::streamFor(fopen('/path/to/file', 'r'));
543  
544 $generator = function ($bytes) {
545 for ($i = 0; $i < $bytes; $i++) {
546 yield ' ';
547 }
548 }
549  
550 $stream = GuzzleHttp\Psr7\Utils::streamFor($generator(100));
551 ```
552  
553  
554 ## `GuzzleHttp\Psr7\Utils::tryFopen`
555  
556 `public static function tryFopen(string $filename, string $mode): resource`
557  
558 Safely opens a PHP stream resource using a filename.
559  
560 When fopen fails, PHP normally raises a warning. This function adds an
561 error handler that checks for errors and throws an exception instead.
562  
563  
564 ## `GuzzleHttp\Psr7\Utils::tryGetContents`
565  
566 `public static function tryGetContents(resource $stream): string`
567  
568 Safely gets the contents of a given stream.
569  
570 When stream_get_contents fails, PHP normally raises a warning. This
571 function adds an error handler that checks for errors and throws an
572 exception instead.
573  
574  
575 ## `GuzzleHttp\Psr7\Utils::uriFor`
576  
577 `public static function uriFor(string|UriInterface $uri): UriInterface`
578  
579 Returns a UriInterface for the given value.
580  
581 This function accepts a string or UriInterface and returns a
582 UriInterface for the given value. If the value is already a
583 UriInterface, it is returned as-is.
584  
585  
586 ## `GuzzleHttp\Psr7\MimeType::fromFilename`
587  
588 `public static function fromFilename(string $filename): string|null`
589  
590 Determines the mimetype of a file by looking at its extension.
591  
592  
593 ## `GuzzleHttp\Psr7\MimeType::fromExtension`
594  
595 `public static function fromExtension(string $extension): string|null`
596  
597 Maps a file extensions to a mimetype.
598  
599  
600 ## Upgrading from Function API
601  
602 The static API was first introduced in 1.7.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API was removed in 2.0.0. A migration table has been provided here for your convenience:
603  
604 | Original Function | Replacement Method |
605 |----------------|----------------|
606 | `str` | `Message::toString` |
607 | `uri_for` | `Utils::uriFor` |
608 | `stream_for` | `Utils::streamFor` |
609 | `parse_header` | `Header::parse` |
610 | `normalize_header` | `Header::normalize` |
611 | `modify_request` | `Utils::modifyRequest` |
612 | `rewind_body` | `Message::rewindBody` |
613 | `try_fopen` | `Utils::tryFopen` |
614 | `copy_to_string` | `Utils::copyToString` |
615 | `copy_to_stream` | `Utils::copyToStream` |
616 | `hash` | `Utils::hash` |
617 | `readline` | `Utils::readLine` |
618 | `parse_request` | `Message::parseRequest` |
619 | `parse_response` | `Message::parseResponse` |
620 | `parse_query` | `Query::parse` |
621 | `build_query` | `Query::build` |
622 | `mimetype_from_filename` | `MimeType::fromFilename` |
623 | `mimetype_from_extension` | `MimeType::fromExtension` |
624 | `_parse_message` | `Message::parseMessage` |
625 | `_parse_request_uri` | `Message::parseRequestUri` |
626 | `get_message_body_summary` | `Message::bodySummary` |
627 | `_caseless_remove` | `Utils::caselessRemove` |
628  
629  
630 # Additional URI Methods
631  
632 Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class,
633 this library also provides additional functionality when working with URIs as static methods.
634  
635 ## URI Types
636  
637 An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference.
638 An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI,
639 the base URI. Relative references can be divided into several forms according to
640 [RFC 3986 Section 4.2](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2):
641  
642 - network-path references, e.g. `//example.com/path`
643 - absolute-path references, e.g. `/path`
644 - relative-path references, e.g. `subpath`
645  
646 The following methods can be used to identify the type of the URI.
647  
648 ### `GuzzleHttp\Psr7\Uri::isAbsolute`
649  
650 `public static function isAbsolute(UriInterface $uri): bool`
651  
652 Whether the URI is absolute, i.e. it has a scheme.
653  
654 ### `GuzzleHttp\Psr7\Uri::isNetworkPathReference`
655  
656 `public static function isNetworkPathReference(UriInterface $uri): bool`
657  
658 Whether the URI is a network-path reference. A relative reference that begins with two slash characters is
659 termed an network-path reference.
660  
661 ### `GuzzleHttp\Psr7\Uri::isAbsolutePathReference`
662  
663 `public static function isAbsolutePathReference(UriInterface $uri): bool`
664  
665 Whether the URI is a absolute-path reference. A relative reference that begins with a single slash character is
666 termed an absolute-path reference.
667  
668 ### `GuzzleHttp\Psr7\Uri::isRelativePathReference`
669  
670 `public static function isRelativePathReference(UriInterface $uri): bool`
671  
672 Whether the URI is a relative-path reference. A relative reference that does not begin with a slash character is
673 termed a relative-path reference.
674  
675 ### `GuzzleHttp\Psr7\Uri::isSameDocumentReference`
676  
677 `public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool`
678  
679 Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its
680 fragment component, identical to the base URI. When no base URI is given, only an empty URI reference
681 (apart from its fragment) is considered a same-document reference.
682  
683 ## URI Components
684  
685 Additional methods to work with URI components.
686  
687 ### `GuzzleHttp\Psr7\Uri::isDefaultPort`
688  
689 `public static function isDefaultPort(UriInterface $uri): bool`
690  
691 Whether the URI has the default port of the current scheme. `Psr\Http\Message\UriInterface::getPort` may return null
692 or the standard port. This method can be used independently of the implementation.
693  
694 ### `GuzzleHttp\Psr7\Uri::composeComponents`
695  
696 `public static function composeComponents($scheme, $authority, $path, $query, $fragment): string`
697  
698 Composes a URI reference string from its various components according to
699 [RFC 3986 Section 5.3](https://datatracker.ietf.org/doc/html/rfc3986#section-5.3). Usually this method does not need
700 to be called manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`.
701  
702 ### `GuzzleHttp\Psr7\Uri::fromParts`
703  
704 `public static function fromParts(array $parts): UriInterface`
705  
706 Creates a URI from a hash of [`parse_url`](https://www.php.net/manual/en/function.parse-url.php) components.
707  
708  
709 ### `GuzzleHttp\Psr7\Uri::withQueryValue`
710  
711 `public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface`
712  
713 Creates a new URI with a specific query string value. Any existing query string values that exactly match the
714 provided key are removed and replaced with the given key value pair. A value of null will set the query string
715 key without a value, e.g. "key" instead of "key=value".
716  
717 ### `GuzzleHttp\Psr7\Uri::withQueryValues`
718  
719 `public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface`
720  
721 Creates a new URI with multiple query string values. It has the same behavior as `withQueryValue()` but for an
722 associative array of key => value.
723  
724 ### `GuzzleHttp\Psr7\Uri::withoutQueryValue`
725  
726 `public static function withoutQueryValue(UriInterface $uri, $key): UriInterface`
727  
728 Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the
729 provided key are removed.
730  
731 ## Cross-Origin Detection
732  
733 `GuzzleHttp\Psr7\UriComparator` provides methods to determine if a modified URL should be considered cross-origin.
734  
735 ### `GuzzleHttp\Psr7\UriComparator::isCrossOrigin`
736  
737 `public static function isCrossOrigin(UriInterface $original, UriInterface $modified): bool`
738  
739 Determines if a modified URL should be considered cross-origin with respect to an original URL.
740  
741 ## Reference Resolution
742  
743 `GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according
744 to [RFC 3986 Section 5](https://datatracker.ietf.org/doc/html/rfc3986#section-5). This is for example also what web
745 browsers do when resolving a link in a website based on the current request URI.
746  
747 ### `GuzzleHttp\Psr7\UriResolver::resolve`
748  
749 `public static function resolve(UriInterface $base, UriInterface $rel): UriInterface`
750  
751 Converts the relative URI into a new URI that is resolved against the base URI.
752  
753 ### `GuzzleHttp\Psr7\UriResolver::removeDotSegments`
754  
755 `public static function removeDotSegments(string $path): string`
756  
757 Removes dot segments from a path and returns the new path according to
758 [RFC 3986 Section 5.2.4](https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4).
759  
760 ### `GuzzleHttp\Psr7\UriResolver::relativize`
761  
762 `public static function relativize(UriInterface $base, UriInterface $target): UriInterface`
763  
764 Returns the target URI as a relative reference from the base URI. This method is the counterpart to resolve():
765  
766 ```php
767 (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
768 ```
769  
770 One use-case is to use the current request URI as base URI and then generate relative links in your documents
771 to reduce the document size or offer self-contained downloadable document archives.
772  
773 ```php
774 $base = new Uri('http://example.com/a/b/');
775 echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'.
776 echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'.
777 echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
778 echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'.
779 ```
780  
781 ## Normalization and Comparison
782  
783 `GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to
784 [RFC 3986 Section 6](https://datatracker.ietf.org/doc/html/rfc3986#section-6).
785  
786 ### `GuzzleHttp\Psr7\UriNormalizer::normalize`
787  
788 `public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS): UriInterface`
789  
790 Returns a normalized URI. The scheme and host component are already normalized to lowercase per PSR-7 UriInterface.
791 This methods adds additional normalizations that can be configured with the `$flags` parameter which is a bitmask
792 of normalizations to apply. The following normalizations are available:
793  
794 - `UriNormalizer::PRESERVING_NORMALIZATIONS`
795  
796 Default normalizations which only include the ones that preserve semantics.
797  
798 - `UriNormalizer::CAPITALIZE_PERCENT_ENCODING`
799  
800 All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized.
801  
802 Example: `http://example.org/a%c2%b1b` → `http://example.org/a%C2%B1b`
803  
804 - `UriNormalizer::DECODE_UNRESERVED_CHARACTERS`
805  
806 Decodes percent-encoded octets of unreserved characters. For consistency, percent-encoded octets in the ranges of
807 ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should
808 not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved
809 characters by URI normalizers.
810  
811 Example: `http://example.org/%7Eusern%61me/` → `http://example.org/~username/`
812  
813 - `UriNormalizer::CONVERT_EMPTY_PATH`
814  
815 Converts the empty path to "/" for http and https URIs.
816  
817 Example: `http://example.org` → `http://example.org/`
818  
819 - `UriNormalizer::REMOVE_DEFAULT_HOST`
820  
821 Removes the default host of the given URI scheme from the URI. Only the "file" scheme defines the default host
822 "localhost". All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile` are equivalent according to
823 RFC 3986.
824  
825 Example: `file://localhost/myfile` → `file:///myfile`
826  
827 - `UriNormalizer::REMOVE_DEFAULT_PORT`
828  
829 Removes the default port of the given URI scheme from the URI.
830  
831 Example: `http://example.org:80/` → `http://example.org/`
832  
833 - `UriNormalizer::REMOVE_DOT_SEGMENTS`
834  
835 Removes unnecessary dot-segments. Dot-segments in relative-path references are not removed as it would
836 change the semantics of the URI reference.
837  
838 Example: `http://example.org/../a/b/../c/./d.html` → `http://example.org/a/c/d.html`
839  
840 - `UriNormalizer::REMOVE_DUPLICATE_SLASHES`
841  
842 Paths which include two or more adjacent slashes are converted to one. Webservers usually ignore duplicate slashes
843 and treat those URIs equivalent. But in theory those URIs do not need to be equivalent. So this normalization
844 may change the semantics. Encoded slashes (%2F) are not removed.
845  
846 Example: `http://example.org//foo///bar.html` → `http://example.org/foo/bar.html`
847  
848 - `UriNormalizer::SORT_QUERY_PARAMETERS`
849  
850 Sort query parameters with their values in alphabetical order. However, the order of parameters in a URI may be
851 significant (this is not defined by the standard). So this normalization is not safe and may change the semantics
852 of the URI.
853  
854 Example: `?lang=en&article=fred` → `?article=fred&lang=en`
855  
856 ### `GuzzleHttp\Psr7\UriNormalizer::isEquivalent`
857  
858 `public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS): bool`
859  
860 Whether two URIs can be considered equivalent. Both URIs are normalized automatically before comparison with the given
861 `$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent.
862 This of course assumes they will be resolved against the same base URI. If this is not the case, determination of
863 equivalence or difference of relative references does not mean anything.
864  
865  
866 ## Security
867  
868 If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/psr7/security/policy) for more information.
869  
870  
871 ## License
872  
873 Guzzle is made available under the MIT License (MIT). Please see [License File](LICENSE) for more information.
874  
875  
876 ## For Enterprise
877  
878 Available as part of the Tidelift Subscription
879  
880 The maintainers of Guzzle and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-guzzlehttp-psr7?utm_source=packagist-guzzlehttp-psr7&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)