Skip to content

Commit 27ba657

Browse files
author
Paul M. Jones
committed
Merge pull request #482 from weierophinney/errata/psr7-immutability
[PSR-7] Clarify requirement for new instances
2 parents 50aa24a + 65e1160 commit 27ba657

File tree

2 files changed

+60
-47
lines changed

2 files changed

+60
-47
lines changed

proposed/http-message-meta.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,19 @@ The above combines assignment and notification in a single call.
324324
This practice has a side benefit of making explicit any changes to application
325325
state being made.
326326

327+
### New instances vs returning $this
328+
329+
One observation made on the various `with*()` methods is that they can likely
330+
safely `return $this;` if the argument presented will not result in a change in
331+
the value. One rationale for doing so is performance (as this will not result in
332+
a cloning operation).
333+
334+
The various interfaces have been written with verbiage indicating that
335+
immutability MUST be preserved, but only indicate that "an instance" must be
336+
returned containing the new state. Since instances that represent the same value
337+
are considered equal, returning `$this` is functionally equivalent, and thus
338+
allowed.
339+
327340
### Using streams instead of X
328341

329342
`MessageInterface` uses a body value that must implement `StreamableInterface`. This
@@ -615,6 +628,6 @@ used to populate the headers of an HTTP message.
615628

616629
* Michael Dowling
617630
* Larry Garfield
631+
* Evert Pot
618632
* Phil Sturgeon
619633
* Chris Wilkinson
620-
* Evert Pot

proposed/http-message.md

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ namespace Psr\Http\Message;
315315
*
316316
* Messages are considered immutable; all methods that might change state MUST
317317
* be implemented such that they retain the internal state of the current
318-
* message and return a new instance that contains the changed state.
318+
* message and return an instance that contains the changed state.
319319
*
320320
* @link http://www.ietf.org/rfc/rfc7230.txt
321321
* @link http://www.ietf.org/rfc/rfc7231.txt
@@ -332,13 +332,13 @@ interface MessageInterface
332332
public function getProtocolVersion();
333333

334334
/**
335-
* Create a new instance with the specified HTTP protocol version.
335+
* Return an instance with the specified HTTP protocol version.
336336
*
337337
* The version string MUST contain only the HTTP version number (e.g.,
338338
* "1.1", "1.0").
339339
*
340340
* This method MUST be implemented in such a way as to retain the
341-
* immutability of the message, and MUST return a new instance that has the
341+
* immutability of the message, and MUST return an instance that has the
342342
* new protocol version.
343343
*
344344
* @param string $version HTTP protocol version
@@ -413,14 +413,14 @@ interface MessageInterface
413413
public function getHeaderLines($name);
414414

415415
/**
416-
* Create a new instance with the provided header, replacing any existing
416+
* Return an instance with the provided header, replacing any existing
417417
* values of any headers with the same case-insensitive name.
418418
*
419419
* While header names are case-insensitive, the casing of the header will
420420
* be preserved by this function, and returned from getHeaders().
421421
*
422422
* This method MUST be implemented in such a way as to retain the
423-
* immutability of the message, and MUST return a new instance that has the
423+
* immutability of the message, and MUST return an instance that has the
424424
* new and/or updated header and value.
425425
*
426426
* @param string $name Case-insensitive header field name.
@@ -431,15 +431,15 @@ interface MessageInterface
431431
public function withHeader($name, $value);
432432

433433
/**
434-
* Creates a new instance, with the specified header appended with the
434+
* Return an instance with the specified header appended with the
435435
* given value.
436436
*
437437
* Existing values for the specified header will be maintained. The new
438438
* value(s) will be appended to the existing list. If the header did not
439439
* exist previously, it will be added.
440440
*
441441
* This method MUST be implemented in such a way as to retain the
442-
* immutability of the message, and MUST return a new instance that has the
442+
* immutability of the message, and MUST return an instance that has the
443443
* new header and/or value.
444444
*
445445
* @param string $name Case-insensitive header field name to add.
@@ -450,12 +450,12 @@ interface MessageInterface
450450
public function withAddedHeader($name, $value);
451451

452452
/**
453-
* Creates a new instance, without the specified header.
453+
* Return an instance without the specified header.
454454
*
455455
* Header resolution MUST be done without case-sensitivity.
456456
*
457457
* This method MUST be implemented in such a way as to retain the
458-
* immutability of the message, and MUST return a new instance that removes
458+
* immutability of the message, and MUST return an instance that removes
459459
* the named header.
460460
*
461461
* @param string $name Case-insensitive header field name to remove.
@@ -471,7 +471,7 @@ interface MessageInterface
471471
public function getBody();
472472

473473
/**
474-
* Create a new instance, with the specified message body.
474+
* Return an instance with the specified message body.
475475
*
476476
* The body MUST be a StreamableInterface object.
477477
*
@@ -508,7 +508,7 @@ namespace Psr\Http\Message;
508508
*
509509
* Requests are considered immutable; all methods that might change state MUST
510510
* be implemented such that they retain the internal state of the current
511-
* message and return a new instance that contains the changed state.
511+
* message and return an instance that contains the changed state.
512512
*/
513513
interface RequestInterface extends MessageInterface
514514
{
@@ -583,15 +583,15 @@ interface RequestInterface extends MessageInterface
583583
public function getRequestTarget();
584584

585585
/**
586-
* Create a new instance with a specific request-target.
586+
* Return an instance with the specific request-target.
587587
*
588588
* If the request needs a non-origin-form request-target — e.g., for
589589
* specifying an absolute-form, authority-form, or asterisk-form —
590590
* this method may be used to create an instance with the specified
591591
* request-target, verbatim.
592592
*
593593
* This method MUST be implemented in such a way as to retain the
594-
* immutability of the message, and MUST return a new instance that has the
594+
* immutability of the message, and MUST return an instance that has the
595595
* changed request target.
596596
*
597597
* @link http://tools.ietf.org/html/rfc7230#section-2.7 (for the various
@@ -609,14 +609,14 @@ interface RequestInterface extends MessageInterface
609609
public function getMethod();
610610

611611
/**
612-
* Create a new instance with the provided HTTP method.
612+
* Return an instance with the provided HTTP method.
613613
*
614614
* While HTTP method names are typically all uppercase characters, HTTP
615615
* method names are case-sensitive and thus implementations SHOULD NOT
616616
* modify the given string.
617617
*
618618
* This method MUST be implemented in such a way as to retain the
619-
* immutability of the message, and MUST return a new instance that has the
619+
* immutability of the message, and MUST return an instance that has the
620620
* changed request method.
621621
*
622622
* @param string $method Case-insensitive method.
@@ -637,10 +637,10 @@ interface RequestInterface extends MessageInterface
637637
public function getUri();
638638

639639
/**
640-
* Create a new instance with the provided URI.
640+
* Return an instance with the provided URI.
641641
*
642642
* This method MUST be implemented in such a way as to retain the
643-
* immutability of the message, and MUST return a new instance that has the
643+
* immutability of the message, and MUST return an instance that has the
644644
* new UriInterface instance.
645645
*
646646
* @link http://tools.ietf.org/html/rfc3986#section-4.3
@@ -694,7 +694,7 @@ namespace Psr\Http\Message;
694694
*
695695
* Requests are considered immutable; all methods that might change state MUST
696696
* be implemented such that they retain the internal state of the current
697-
* message and return a new instance that contains the changed state.
697+
* message and return an instance that contains the changed state.
698698
*/
699699
interface ServerRequestInterface extends RequestInterface
700700
{
@@ -722,14 +722,14 @@ interface ServerRequestInterface extends RequestInterface
722722
public function getCookieParams();
723723

724724
/**
725-
* Create a new instance with the specified cookies.
725+
* Return an instance with the specified cookies.
726726
*
727727
* The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST
728728
* be compatible with the structure of $_COOKIE. Typically, this data will
729729
* be injected at instantiation.
730730
*
731731
* This method MUST be implemented in such a way as to retain the
732-
* immutability of the message, and MUST return a new instance that has the
732+
* immutability of the message, and MUST return an instance that has the
733733
* updated cookie values.
734734
*
735735
* @param array $cookies Array of key/value pairs representing cookies.
@@ -752,7 +752,7 @@ interface ServerRequestInterface extends RequestInterface
752752
public function getQueryParams();
753753

754754
/**
755-
* Create a new instance with the specified query string arguments.
755+
* Return an instance with the specified query string arguments.
756756
*
757757
* These values SHOULD remain immutable over the course of the incoming
758758
* request. They MAY be injected during instantiation, such as from PHP's
@@ -766,7 +766,7 @@ interface ServerRequestInterface extends RequestInterface
766766
* request, nor the values in the server params.
767767
*
768768
* This method MUST be implemented in such a way as to retain the
769-
* immutability of the message, and MUST return a new instance that has the
769+
* immutability of the message, and MUST return an instance that has the
770770
* updated query string arguments.
771771
*
772772
* @param array $query Array of query string arguments, typically from
@@ -807,7 +807,7 @@ interface ServerRequestInterface extends RequestInterface
807807
public function getParsedBody();
808808

809809
/**
810-
* Create a new instance with the specified body parameters.
810+
* Return an instance with the specified body parameters.
811811
*
812812
* These MAY be injected during instantiation.
813813
*
@@ -825,7 +825,7 @@ interface ServerRequestInterface extends RequestInterface
825825
* instance with the deserialized parameters.
826826
*
827827
* This method MUST be implemented in such a way as to retain the
828-
* immutability of the message, and MUST return a new instance that has the
828+
* immutability of the message, and MUST return an instance that has the
829829
* updated body parameters.
830830
*
831831
* @param null|array|object $data The deserialized body data. This will
@@ -865,13 +865,13 @@ interface ServerRequestInterface extends RequestInterface
865865
public function getAttribute($name, $default = null);
866866

867867
/**
868-
* Create a new instance with the specified derived request attribute.
868+
* Return an instance with the specified derived request attribute.
869869
*
870870
* This method allows setting a single derived request attribute as
871871
* described in getAttributes().
872872
*
873873
* This method MUST be implemented in such a way as to retain the
874-
* immutability of the message, and MUST return a new instance that has the
874+
* immutability of the message, and MUST return an instance that has the
875875
* updated attribute.
876876
*
877877
* @see getAttributes()
@@ -882,14 +882,14 @@ interface ServerRequestInterface extends RequestInterface
882882
public function withAttribute($name, $value);
883883

884884
/**
885-
* Create a new instance that removes the specified derived request
885+
* Return an instance that removes the specified derived request
886886
* attribute.
887887
*
888888
* This method allows removing a single derived request attribute as
889889
* described in getAttributes().
890890
*
891891
* This method MUST be implemented in such a way as to retain the
892-
* immutability of the message, and MUST return a new instance that removes
892+
* immutability of the message, and MUST return an instance that removes
893893
* the attribute.
894894
*
895895
* @see getAttributes()
@@ -920,7 +920,7 @@ namespace Psr\Http\Message;
920920
*
921921
* Responses are considered immutable; all methods that might change state MUST
922922
* be implemented such that they retain the internal state of the current
923-
* message and return a new instance that contains the changed state.
923+
* message and return an instance that contains the changed state.
924924
*/
925925
interface ResponseInterface extends MessageInterface
926926
{
@@ -935,15 +935,15 @@ interface ResponseInterface extends MessageInterface
935935
public function getStatusCode();
936936

937937
/**
938-
* Create a new instance with the specified status code, and optionally
938+
* Return an instance with the specified status code, and optionally
939939
* reason phrase, for the response.
940940
*
941941
* If no Reason-Phrase is specified, implementations MAY choose to default
942942
* to the RFC 7231 or IANA recommended reason phrase for the response's
943943
* Status-Code.
944944
*
945945
* This method MUST be implemented in such a way as to retain the
946-
* immutability of the message, and MUST return a new instance that has the
946+
* immutability of the message, and MUST return an instance that has the
947947
* updated status and reason phrase.
948948
*
949949
* @link http://tools.ietf.org/html/rfc7231#section-6
@@ -1144,7 +1144,7 @@ namespace Psr\Http\Message;
11441144
*
11451145
* Instances of this interface are considered immutable; all methods that
11461146
* might change state MUST be implemented such that they retain the internal
1147-
* state of the current instance and return a new instance that contains the
1147+
* state of the current instance and return an instance that contains the
11481148
* changed state.
11491149
*
11501150
* Typically the Host header will be also be present in the request message.
@@ -1265,10 +1265,10 @@ interface UriInterface
12651265
public function getFragment();
12661266

12671267
/**
1268-
* Create a new instance with the specified scheme.
1268+
* Return an instance with the specified scheme.
12691269
*
12701270
* This method MUST retain the state of the current instance, and return
1271-
* a new instance that contains the specified scheme. If the scheme
1271+
* an instance that contains the specified scheme. If the scheme
12721272
* provided includes the "://" delimiter, it MUST be removed.
12731273
*
12741274
* Implementations SHOULD restrict values to "http", "https", or an empty
@@ -1283,10 +1283,10 @@ interface UriInterface
12831283
public function withScheme($scheme);
12841284

12851285
/**
1286-
* Create a new instance with the specified user information.
1286+
* Return an instance with the specified user information.
12871287
*
12881288
* This method MUST retain the state of the current instance, and return
1289-
* a new instance that contains the specified user information.
1289+
* an instance that contains the specified user information.
12901290
*
12911291
* Password is optional, but the user information MUST include the
12921292
* user; an empty string for the user is equivalent to removing user
@@ -1299,10 +1299,10 @@ interface UriInterface
12991299
public function withUserInfo($user, $password = null);
13001300

13011301
/**
1302-
* Create a new instance with the specified host.
1302+
* Return an instance with the specified host.
13031303
*
13041304
* This method MUST retain the state of the current instance, and return
1305-
* a new instance that contains the specified host.
1305+
* an instance that contains the specified host.
13061306
*
13071307
* An empty host value is equivalent to removing the host.
13081308
*
@@ -1313,10 +1313,10 @@ interface UriInterface
13131313
public function withHost($host);
13141314

13151315
/**
1316-
* Create a new instance with the specified port.
1316+
* Return an instance with the specified port.
13171317
*
13181318
* This method MUST retain the state of the current instance, and return
1319-
* a new instance that contains the specified port.
1319+
* an instance that contains the specified port.
13201320
*
13211321
* Implementations MUST raise an exception for ports outside the
13221322
* established TCP and UDP port ranges.
@@ -1332,10 +1332,10 @@ interface UriInterface
13321332
public function withPort($port);
13331333

13341334
/**
1335-
* Create a new instance with the specified path.
1335+
* Return an instance with the specified path.
13361336
*
13371337
* This method MUST retain the state of the current instance, and return
1338-
* a new instance that contains the specified path.
1338+
* an instance that contains the specified path.
13391339
*
13401340
* The path MUST be prefixed with "/"; if not, the implementation MAY
13411341
* provide the prefix itself.
@@ -1353,10 +1353,10 @@ interface UriInterface
13531353
public function withPath($path);
13541354

13551355
/**
1356-
* Create a new instance with the specified query string.
1356+
* Return an instance with the specified query string.
13571357
*
13581358
* This method MUST retain the state of the current instance, and return
1359-
* a new instance that contains the specified query string.
1359+
* an instance that contains the specified query string.
13601360
*
13611361
* If the query string is prefixed by "?", that character MUST be removed.
13621362
* Additionally, the query string SHOULD be parseable by parse_str() in
@@ -1375,10 +1375,10 @@ interface UriInterface
13751375
public function withQuery($query);
13761376

13771377
/**
1378-
* Create a new instance with the specified URI fragment.
1378+
* Return an instance with the specified URI fragment.
13791379
*
13801380
* This method MUST retain the state of the current instance, and return
1381-
* a new instance that contains the specified URI fragment.
1381+
* an instance that contains the specified URI fragment.
13821382
*
13831383
* If the fragment is prefixed by "#", that character MUST be removed.
13841384
*

0 commit comments

Comments
 (0)