rfc:http-last-response-headers

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:http-last-response-headers [2024/01/03 15:07] – Fix title girgiasrfc:http-last-response-headers [2024/02/29 16:42] (current) – Implemented girgias
Line 1: Line 1:
 ====== PHP RFC: Add http_(get|clear)_last_response_headers() function ====== ====== PHP RFC: Add http_(get|clear)_last_response_headers() function ======
  
-  * Version: 0.1+  * Version: 0.2
   * Date: 2024-01-03   * Date: 2024-01-03
   * Author: Gina Peter Banyard <girgias@php.net>   * Author: Gina Peter Banyard <girgias@php.net>
-  * Status: Under Discussion+  * Status: Implemented in PHP 8.4: https://github.com/php/php-src/commit/47a199c8b43dbf84e66ff6b63f665541ab4eb1d0
   * Target Version: PHP 8.4   * Target Version: PHP 8.4
   * Implementation: [[https://github.com/php/php-src/pull/12500|https://github.com/php/php-src/pull/12500]]   * Implementation: [[https://github.com/php/php-src/pull/12500|https://github.com/php/php-src/pull/12500]]
Line 14: Line 14:
 variable is magically created in the local scope whenever an HTTP request is performed through PHP's stream layer, variable is magically created in the local scope whenever an HTTP request is performed through PHP's stream layer,
 i.e. when using the [[https://www.php.net/manual/en/wrappers.http.php|HTTP wrapper]]. i.e. when using the [[https://www.php.net/manual/en/wrappers.http.php|HTTP wrapper]].
-One such usage is using <php>file_get_content()</php> to retrieve the content of a URL. +One such usage is using <php>file_get_contents()</php> to retrieve the content of a URL.
  
 The [[https://www.php.net/manual/en/reserved.variables.httpresponseheader.php|$http_response_header]] The [[https://www.php.net/manual/en/reserved.variables.httpresponseheader.php|$http_response_header]]
 variable will contain all the HTTP headers that were encountered during the request performed via the HTTP wrapper. variable will contain all the HTTP headers that were encountered during the request performed via the HTTP wrapper.
  
-Because creating a variable in the local scope is a terrible way of returning additional information, +All other features using this operating principle, 
-we have removed all other features using this operating principle, +such as [[https://www.php.net/manual/en/reserved.variables.phperrormsg.php|$php_errormsg]]
-such as [[https://www.php.net/manual/en/reserved.variables.phperrormsg.php|$php_errormsg]]. +have been removed because creating a variable in the local scope is a terrible way of returning additional information
-This variable was initially slated [[rfc:deprecations_php_8_1#predefined_variable_http_response_header|to be deprecated in PHP 8.1]], +This variable itself was initially slated [[rfc:deprecations_php_8_1#predefined_variable_http_response_header|to be deprecated in PHP 8.1]], 
-but due to the lack of convenient alternatives it was removed from the proposal.+but due to lack of convenient alternativesit was removed from the proposal at that time.
  
-Indeed, this variable is created and populated even if the HTTP request fails. +This variable is created and populated even if the HTTP request fails, 
-Something that is only possible to achieve when dropping down to the stream layer when providing an additional +a behaviour that requires dropping down to the stream layerproviding an additional 
-stream context which ignores errors. +stream context to ignore errors. 
-Which requires manually parsing and detecting if the HTTP request failed or not instead of just checking if the return value is <php>false</php>.+Subsequently, the user can manually parse the response header and detect if the HTTP request failed or not
 +This is impractical and a better interface would be simply checking if the return value of the initial call was <php>false</php>.
  
-Thus, we propose adding functions similar to <php>error_get_last()</php>/<php>error_clear_last()</php> which replaced+As a replacement, we propose adding functions similar to <php>error_get_last()</php>/<php>error_clear_last()</php> which replaced
 [[https://www.php.net/manual/en/reserved.variables.phperrormsg.php|$php_errormsg]]. [[https://www.php.net/manual/en/reserved.variables.phperrormsg.php|$php_errormsg]].
 +
 +===== Motivation =====
 +
 +The primary motivation for adding this function, is to be able to remove the [[https://www.php.net/manual/en/reserved.variables.httpresponseheader.php|$http_response_header]]
 +variable completely. To create this variable one needs to use the <php>zend_set_local_var_str()</php> engine function.
 +This is also the last usage of this engine function and its sibling function <php>zend_set_local_var()</php>.
 +
 +Moreover, this variable needs to be special cased in the optimizer/JIT
 +(via the <php>HTTP_RESPONSE_HEADER_ALIAS</php> enum case of <php>zend_ssa_alias_kind</php>).
 +Which means that any extension that would use this engine API would misbehave under opcache.
 +
 +See the [[rfc:http-last-response-headers#backward_incompatible_changes|Backward Incompatible Changes]]
 +section for an impact analysis of the removal of this feature.
  
 ===== Proposal ===== ===== Proposal =====
Line 40: Line 53:
   * <php>function http_clear_last_response_header(): void</php>   * <php>function http_clear_last_response_header(): void</php>
  
-<php>http_get_last_response_header()</php> would behave like+<php>http_get_last_response_header()</php> would provide the same information as
 [[https://www.php.net/manual/en/reserved.variables.httpresponseheader.php|$http_response_header]] [[https://www.php.net/manual/en/reserved.variables.httpresponseheader.php|$http_response_header]]
-if a request via the HTTP wrapper is made and return the headers as an array even when the request fails. +if a request via the HTTP wrapper is madeand also return the headers as an array even when the request fails. 
-If no request via the HTTP wrapper is made, or the previous headers have been cleared by using+If no request via the HTTP wrapper is made, or the last headers have been cleared by calling
 <php>http_clear_last_response_header()</php>, then <php>null</php> is returned. <php>http_clear_last_response_header()</php>, then <php>null</php> is returned.
  
Line 52: Line 65:
 there are no backward incompatible changes. there are no backward incompatible changes.
  
-However, considering the possible engine and optimizer simplifications by removing +Considering the possible simplification to the engine and the optimizer by removing 
-the last usage of the engine creating a variable, we have conducted a usage analysis of this feature. +this last usage of the capability to create a variable in this way, we have conducted a usage analysis of the feature. 
-We have found 65 usages in 30 projects across over 900 projects +We found only 65 usages in 30 projects across a sample of over 900 projects 
-(composer packages, standalone open source projects, and private codebases) that were analyzed with [[https://www.exakat.io|Exakat]]. [1]+(composer packages, standalone open source projects, and private codebases) which were analyzed with [[https://www.exakat.io|Exakat]]. [1]
 Most of those usages stem from packages like Guzzle or OAuth client libraries. Most of those usages stem from packages like Guzzle or OAuth client libraries.
  
Line 68: Line 81:
 </PHP> </PHP>
  
-Considering the low usage of this feature, the possibility to write cross version compatible code,+Considering the sparse usage of this feature, the possibility to write cross version compatible code,
 and the possible engine and optimizer simplifications, and the possible engine and optimizer simplifications,
-it seems reasonable to be able to remove this feature even without a deprecation notice if the need arises.+it seems reasonable to slate this feature for removal even without a deprecation notice if the need arises
 + 
 +===== Rejected ideas ===== 
 + 
 +One suggested idea was to provide those headers via a by-reference entry to the stream context. 
 +This idea was rejected by us, and other members of the PHP Foundation, 
 +as we wish to maintain stream contexts as a stateless configuration data structure passed to the stream. 
 + 
 +This one-to-one feature replacement does not prevent the introduction of a more generic solution for other stream wrappers. 
 +And this pair of new functions can always be slated for future deprecation and removal.
  
 ===== Version ===== ===== Version =====
Line 80: Line 102:
 As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted. As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted.
  
-Voting started on 2024-XX-XX and will end on 2024-XX-XX.+Voting started on 2024-01-29 and will end on 2024-02-14.
    
 <doodle title="Accept Add http_(get|clear)_last_response_headers() function RFC?" auth="girgias" voteType="single" closed="true"> <doodle title="Accept Add http_(get|clear)_last_response_headers() function RFC?" auth="girgias" voteType="single" closed="true">
rfc/http-last-response-headers.1704294450.txt.gz · Last modified: 2024/01/03 15:07 by girgias