rfc:request_response

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:request_response [2020/02/28 15:20] – add rejected feature pmjonesrfc:request_response [2020/04/08 12:47] (current) – add epilogue link pmjones
Line 1: Line 1:
 ====== PHP RFC: Server-Side Request and Response Objects ====== ====== PHP RFC: Server-Side Request and Response Objects ======
  
-  * Version: 2.1 +  * Version: 2.2 
-  * Date: 2020-02-19+  * Date: 2020-03-17
   * Author: Paul M. Jones, pmjones@pmjones.io   * Author: Paul M. Jones, pmjones@pmjones.io
-  * Status: Under Discussion+  * Status: Declined
   * First Published at: [[http://wiki.php.net/rfc/request_response]]   * First Published at: [[http://wiki.php.net/rfc/request_response]]
  
Line 19: Line 19:
 This RFC proposes an extension to declare three new classes and one interface in the root namespace: This RFC proposes an extension to declare three new classes and one interface in the root namespace:
  
-  * ServerRequest, composed of immutable read-only copies of PHP superglobals, and some other commonly-used values parsed out from those superglobals+  * SapiRequest, composed of immutable read-only copies of PHP superglobals, and some other commonly-used values parsed out from those superglobals
  
-  * ServerResponse and ServerResponseInterface, a buffer for response-related PHP functions+  * SapiResponse and SapiResponseInterface, a buffer for response-related PHP functions
  
-  * ServerResponseSender, to emit the ServerResponse using PHP functions+  * SapiResponseSender, to emit the SapiResponse using PHP functions
  
 The full README, working code, and all tests are available at [[https://github.com/pmjones/ext-request]], in the 2.x branch. The full README, working code, and all tests are available at [[https://github.com/pmjones/ext-request]], in the 2.x branch.
Line 33: Line 33:
 <code> <code>
  
-Instead of the superglobal ...          ... use ServerRequest:+Instead of the superglobal ...          ... use SapiRequest:
 --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
 $_COOKIE                                $request->cookie $_COOKIE                                $request->cookie
Line 49: Line 49:
 $_SERVER['PHP_AUTH_USER'              $request->authUser $_SERVER['PHP_AUTH_USER'              $request->authUser
  
-Instead of parsing ...                  ... use ServerRequest:+Instead of parsing ...                  ... use SapiRequest:
 --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
 $_FILES to look more like $_POST        $request->uploads $_FILES to look more like $_POST        $request->uploads
Line 62: Line 62:
 $_SERVER['PHP_AUTH_DIGEST'            $request->authDigest $_SERVER['PHP_AUTH_DIGEST'            $request->authDigest
  
-Instead of emitting ...                  ... buffer with ServerResponse:+Instead of emitting ...                  ... buffer with SapiResponse:
 --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
 header('HTTP/1.1', true, 200)           $response->setVersion('1.1'); header('HTTP/1.1', true, 200)           $response->setVersion('1.1');
Line 72: Line 72:
 echo $content;                          $response->setContent($content); echo $content;                          $response->setContent($content);
  
-Instead of sending with ...             ... send with ServerResponseSender:+Instead of sending with ...             ... send with SapiResponseSender:
 --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
 echo, header(), setcookie(), etc.       $responseSender->send($response); echo, header(), setcookie(), etc.       $responseSender->send($response);
Line 182: Line 182:
 === Other Questions And Comments === === Other Questions And Comments ===
  
-Q: Does ServerRequest hold references to the superglobals, or copies?+Q: The proposal compares and contrasts with HttpFoundation and the various PSR-7 implementations; how does it compare to other projects?
  
-A: Copies, made at instantiation timeChanges to `$_GET` after the ServerRequest is instantiated will not be reflected in the existing instance.+A: See this message for a starting point: [[https://externals.io/message/108436#108889]]. In short, the proposed functionality is representative of functionality common to the dozen-plus researched projects.
  
-Q: Since the $get, $post etc. properties are the same as $_GET and $_POST, does that mean they retain the same name mangling scheme?+Q: Are these global single-instance objects?
  
-A: They do; that is, ServerRequest uses whatever is passed into it at construction time. If PHP changes its name mangling, or if different array values are passed in, ServerRequest will use those instead.+A: No, you can create as many instances as you like, in whatever scopes you like. 
 + 
 +Q: Do these objects replace the superglobals? 
 + 
 +A: No. 
 + 
 +Q: Do these objects deal with $_SESSION and the session functions? 
 + 
 +A: No; it is explicitly out of scope for this RFC. 
 + 
 +Q: Does SapiRequest hold references to the superglobals, or copies? 
 + 
 +A: Copies, made at instantiation time. Changes to `$_GET` after the SapiRequest is instantiated will not be reflected in the existing instance. 
 + 
 +Q: Since the $query, $post etc. properties are the same as $_GET and $_POST, does that mean they retain the same name mangling scheme? 
 + 
 +A: They do; that is, SapiRequest uses whatever is passed into it at construction time. If PHP changes its name mangling, or if different array values are passed in, SapiRequest will use those instead.
  
 Q: Readonly properties are unusual for PHP. Q: Readonly properties are unusual for PHP.
  
-A: Granted, though not unheard of. PdoStatement::$queryString is one precedent here.+A: Granted, though not unheard of. PdoStatement::$queryString is one precedent here. Further, of the researched userland projects, more than half of them present the relevant superglobals as nominally readonly in the public scope, making readonly access a reasonable choice here.
  
 Q: Does this has any performance impact? Q: Does this has any performance impact?
Line 198: Line 214:
 A: Compared to userland, probably greater performance, but the scope is so small that I expect little end-to-end impact on applications as a whole. A: Compared to userland, probably greater performance, but the scope is so small that I expect little end-to-end impact on applications as a whole.
  
-Q: Why is ServerRequest readonly, and ServerResponse mutable?+Q: Why is SapiRequest readonly, and SapiResponse mutable?
  
-A: It makes sense that you would not want to change what you have received as a request; however, as you are in charge of creating the response, modifying it as needed seems reasonable.+A: It makes sense that you would not want to change what you have received as a request; however, as you are in charge of creating the response, modifying it as needed seems reasonable. Further, the "readonly request with mutable response" matches half or more of the researched userland projects.
  
-Q: Why is ServerRequest composed only of properties, and ServerResponse composed only of methods?+Q: Why is SapiRequest composed only of properties, and SapiResponse composed only of methods?
  
 A: It's an outgrowth of an asymmetry that already exists in PHP: $_GET, $_POST, et al. are properties representing the request, whereas header(), setcookie(), et al. are all functions for sending a response. A: It's an outgrowth of an asymmetry that already exists in PHP: $_GET, $_POST, et al. are properties representing the request, whereas header(), setcookie(), et al. are all functions for sending a response.
  
-Q:  Why not write (PSR-7|HttpFoundation|OtherImplementation) in C, instead of your own version?+Q: Why not write (PSR-7|HttpFoundation|OtherImplementation) in C, instead of your own version?
  
 A: This is not "my own version." This is an OO-approach to what PHP itself already does; it is representative of PHP's way of doing things, not "my" way of doing things. A: This is not "my own version." This is an OO-approach to what PHP itself already does; it is representative of PHP's way of doing things, not "my" way of doing things.
Line 217: Line 233:
  
 A: Async is not in scope for the proposed API. A: Async is not in scope for the proposed API.
 +
 +Q: What would a migration path look like?
 +
 +A: Something like the one outlined in the later portion of this message: [[https://externals.io/message/108436#108893]]
  
 ==== Changes From The 1.x Version ==== ==== Changes From The 1.x Version ====
Line 222: Line 242:
 Based on user feedback over the past couple of years, this proposal differs from the earlier 1.x version in the following substantial ways: Based on user feedback over the past couple of years, this proposal differs from the earlier 1.x version in the following substantial ways:
  
-  * Some users objected on principle to the ServerRequest constructing itself using the superglobals internally. As a result, the constructor now requires a single array parameter; the corresponding argument is typically $GLOBALS but can be any array that mimics the $GLOBALS structure.+  * The "Server" prefix on the class names has been changed to "Sapi".
  
-  * The ServerRequest object no longer has the immutable application-related functionality represented by withInput(), withParams(), withUrl(), and their sibling methods. Some users felt this functionality was better left to application-specific implementations; other users merely did not need them and were happy to ignore themThis means ServerRequest is now only public read-only set of properties with immutable values, while still being extensible in userland for application concerns if desired.+  * Some users objected on principle to the SapiRequest constructing itself using the superglobals internallyAs a result, the constructor now requires single array parameter; the corresponding argument is typically $GLOBALS but can be any array that mimics the $GLOBALS structure.
  
-  * The ServerResponse object no longer has setContent() convenience methods such as setContentJson() and setContentDownload(). Users found these less convenient than anticipated, and preferred to add their own application-specific convenience methods.+  * The SapiRequest object no longer has the immutable application-related functionality represented by withInput(), withParams(), withUrl(), and their sibling methods. Some users felt this functionality was better left to application-specific implementations; other users merely did not need them and were happy to ignore them. This means SapiRequest is now only a public read-only set of properties with immutable values, while still being extensible in userland for application concerns if desired.
  
-  * ServerResponse no longer has a self-sending capabilityIt was noted that to customize sending logicyou needed a custom ServerResponse object. As a result, the sending logic has been extracted to a ServerResponseSender class.+  * The SapiResponse object no longer has setContent() convenience methods such as setContentJson() and setContentDownload()Users found these less convenient than anticipatedand preferred to add their own application-specific convenience methods.
  
-  * To address some concerns from an earlier round of discussionall ServerResponse properties are now privateand all its methods are now final, though the class itself is not. This keeps the class open for extension but closed for modification.+  * SapiResponse no longer has a self-sending capability. It was noted that to customize sending logicyou needed a custom SapiResponse object. As a result, the sending logic has been extracted to a SapiResponseSender class.
  
-  * ServerResponse::setHeader() and addHeader() methods no longer convert array values to CSV header strings; this functionality was so rarely used as to be unnecessary. Removing it brings these methods back in line with the PHP header() signature. Likewise, the date() helper method is similarly removed. These helper methods, if ever needed, are easily added to userland implementations.+  * To address some concerns from an earlier round of discussion, all SapiResponse properties are now private, and all its methods are now final, though the class itself is not. This keeps the class open for extension but closed for modification. 
 + 
 +  * SapiResponse::setHeader() and addHeader() methods no longer convert array values to CSV header strings; this functionality was so rarely used as to be unnecessary. Removing it brings these methods back in line with the PHP header() signature. Likewise, the date() helper method is similarly removed. These helper methods, if ever needed, are easily added to userland implementations.
  
 In all, these removals and changes bring the proposal much closer to PHP as-it-is. In all, these removals and changes bring the proposal much closer to PHP as-it-is.
Line 238: Line 260:
 ==== Open Questions ==== ==== Open Questions ====
  
-1. Are the more appropriate names other than ServerRequest, ServerResponse, and ServerResponseSender? The primary considerations here are (a) to indicate that these are the request received by PHP and the response being sent by PHP, and (b) to have as small a conflict as possible with pre-existing userland names in the global namespace. +1. Should these classes go into an existing extension, rather than one of their own? Or should they go into "core" proper?
- +
-2. Should these classes go into an existing extension, rather than one of their own? +
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
  
-Userland code that declares classes named ServerRequestServerResponse, or ServerReponseSender will need to rename those classes.+Userland code that declares classes named SapiRequestSapiResponse, or SapiReponseSender will need to rename those classes.
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
Line 323: Line 342:
 [[https://www.reddit.com/r/PHP/comments/f26a7m/rfc_for_builtin_request_and_response_objects/]] [[https://www.reddit.com/r/PHP/comments/f26a7m/rfc_for_builtin_request_and_response_objects/]]
  
-[[https://externals.io/message/108436]]+[[https://externals.io/message/108436]] (discussion thread) 
 + 
 +[[https://externals.io/message/109161]] (voting thread) 
 + 
 +[[https://externals.io/message/109563]] (epilogue)
  
 ===== Rejected Features ===== ===== Rejected Features =====
  
-Add filter_input integration to ServerRequest.+Add filter_input integration to SapiRequest.
  
 Add .ini setting(s) to disable superglobals, and/or warn on their use. Add .ini setting(s) to disable superglobals, and/or warn on their use.
Line 333: Line 356:
 Add .ini setting(s) to disable response-related functions, and/or warn on their use. Add .ini setting(s) to disable response-related functions, and/or warn on their use.
  
-Expand the number of classes provided, to allow for various ServerRequest-related value objects.+Expand the number of classes provided, to allow for various SapiRequest-related value objects
 + 
 +Provide builder and locking methods for SapiRequest. 
 + 
 +Make the SapiRequest properties mutable.
  
-Provide builder and locking methods for ServerRequest.+Add a SapiResponse::addContent() method.
  
-Make the ServerRequest properties mutable.+Embed the PHP multipart/form-data and application/x-www-url-ncoded parsing mechanisms into SapiRequest, possibly exposing them wider use.
  
-Add a ServerResponse::addContent() method.+===== Vote =====
  
-Embed the PHP multipart/form-data and application/x-www-url-ncoded parsing mechanisms into ServerRequest, possibly exposing them wider use.+<doodle title="Adopt Server-Side Request and Response Objects?" auth="pmjones" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle>
  
rfc/request_response.1582903206.txt.gz · Last modified: 2020/02/28 15:20 by pmjones