Skip to content

Should $http_response_header be deprecated? #19651

Closed

Description

@campbell-m

Description

The following code:

<?php
declare(strict_types=1);

error_reporting(-1);
ini_set('display_errors', '1');

echo PHP_VERSION . "<br>\n";

function get_contents() {
  file_get_contents("https://www.php.net/manual/en/reserved.variables.httpresponseheader.php");
  $headers = $http_response_header;
  var_dump($headers);
}

get_contents();

Resulted in this output:

8.5.0beta2
array(12) { [0]=> string(15) "HTTP/1.1 200 OK" [1]=> string(17) "Server: myracloud" [2]=> string(35) "Date: Sun, 31 Aug 2025 07:39:53 GMT" [3]=> string(38) "Content-Type: text/html; charset=utf-8" [4]=> string(17) "Connection: close" [5]=> string(20) "Content-language: en" [6]=> string(38) "Permissions-Policy: interest-cohort=()" [7]=> string(27) "X-Frame-Options: SAMEORIGIN" [8]=> string(93) "Link: ; rel=shorturl" [9]=> string(44) "Last-Modified: Sun, 31 Aug 2025 06:00:41 GMT" [10]=> string(38) "Expires: Sun, 31 Aug 2025 07:39:53 GMT" [11]=> string(24) "Cache-Control: max-age=0" }

But I expected this output instead:

8.5.0beta2
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in C:\inetpub\wwwroot\... on line ...
array(12) { [0]=> string(15) "HTTP/1.1 200 OK" [1]=> string(17) "Server: myracloud" [2]=> string(35) "Date: Sun, 31 Aug 2025 07:39:53 GMT" [3]=> string(38) "Content-Type: text/html; charset=utf-8" [4]=> string(17) "Connection: close" [5]=> string(20) "Content-language: en" [6]=> string(38) "Permissions-Policy: interest-cohort=()" [7]=> string(27) "X-Frame-Options: SAMEORIGIN" [8]=> string(93) "Link: ; rel=shorturl" [9]=> string(44) "Last-Modified: Sun, 31 Aug 2025 06:00:41 GMT" [10]=> string(38) "Expires: Sun, 31 Aug 2025 07:39:53 GMT" [11]=> string(24) "Cache-Control: max-age=0" }

I have been testing PHP 8.5.0beta2 on Windows and have occasionally been getting the message "Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in ...". However, I couldn't reproduce it reliably and wrote the small test program above, expecting to get the deprecation message, but didn't.

PHP Version

PHP Version 8.5.0beta2

Operating System

Microsoft-IIS/10.0

Activity

  1. DanielEScherzer commented on Aug 31, 2025

    @DanielEScherzer
    Member

    #19464 was included in 8.5.0beta2 - can you give us an example of code that sometimes triggers the warning and sometimes doesn't?
    The code above definitely should be triggering the warnings
    CC @Girgias

  2. ndossche commented on Aug 31, 2025

    @ndossche
    Member

    One important thing to note is that the deprecation will only be triggered on compilation. So if you use opcache then you only get the error once (unless you change the source code again). Are you using opcache?
    The listed example code does trigger the deprecation.

  3. campbell-m commented on Aug 31, 2025

    @campbell-m
    Author

    One important thing to note is that the deprecation will only be triggered on compilation.

    Ah, that explains a lot, but not everything. Yes, I was using opcache. I've now turned it off and can reliably reproduce the deprecation message in both my original code and my test code. It seems that even with opcache turned on it's not enough to simply change the source code. If I do that in my test code I can't generate the error at all; in my original code I can generate it sometimes. There must be something else that triggers the message - maybe a more complex change to the source code, or the passage of time.

    Anyway, my main concern was to how to use $http_response_header in code that is designed to run on both PHP 8.3 and PHP 8.5. I had hoped to use something like:

    $headers = (function_exists('http_get_last_response_headers')) ? http_get_last_response_headers() : $http_response_header;

    However that still produces the deprecation message because it's produced at compile time. And the only way I can prevent the error message being displayed is to put display_errors = Off in the php.ini file - which isn't necessarily under my control. I can't turn them off with a call to ini_set() because that's too late.

    Is it possible to make the deprecation message a run-time rather than a compile-time error? Or can you suggest another solution?

  4. ndossche commented on Aug 31, 2025

    @ndossche
    Member

    Doing the check at run time is too costly.
    Why don't you use the @ operator?

  5. campbell-m commented on Aug 31, 2025

    @campbell-m
    Author

    I tried the @ operator, but it didn't make any difference:

    $headers = (function_exists('http_get_last_response_headers')) ? http_get_last_response_headers() : @$http_response_header;

    I assumed that it only takes effect at runtime. Or should it also take effect at compile time?

  6. ndossche commented on Aug 31, 2025

    @ndossche
    Member

    Oh right of course.
    Then I'm not sure how to address this in a nice way. You can likely trick the compiler by using variable-variables.
    I.e.

    $var = "http_reponse_header";
    $headers = $$var;
  7. campbell-m commented on Aug 31, 2025

    @campbell-m
    Author

    No, that doesn't work either (even after I've corrected the $var string). It tricks the compiler so much that $$var returns NULL.

  8. campbell-m commented on Aug 31, 2025

    @campbell-m
    Author

    Is it possible to make the @ operator apply at compile time? Looking at the documentation there doesn't seem to be anything that says it's only effective at runtime.

  9. Girgias commented on Aug 31, 2025

    @Girgias
    Member

    Anyway, my main concern was to how to use $http_response_header in code that is designed to run on both PHP 8.3 and PHP 8.5. I had hoped to use something like:

    $headers = (function_exists('http_get_last_response_headers')) ? http_get_last_response_headers() : $http_response_header;

    The way that is tested to work across multiple PHP versions would be:

    if (function_exists('http_get_last_response_headers')) {
       $http_response_header = http_get_last_response_headers();
    }
    $headers = $http_response_header;

    Which will be better explaining in the migration guide.

    However that still produces the deprecation message because it's produced at compile time. And the only way I can prevent the error message being displayed is to put display_errors = Off in the php.ini file - which isn't necessarily under my control. I can't turn them off with a call to ini_set() because that's too late.

    Is it possible to make the deprecation message a run-time rather than a compile-time error? Or can you suggest another solution?

    The only conceivable way is to not actually register the variable at all and hook into the undefined variable code, but this is an extremely complicated change that affects many many many different parts compared to checking this at compile time.

  10. Girgias commented on Aug 31, 2025

    @Girgias
    Member

    The other way to trick the compiler is to just have a $http_response_header = null; at the beginning of the function.

  11. campbell-m commented on Aug 31, 2025

    @campbell-m
    Author
    if (function_exists('http_get_last_response_headers')) {
       $http_response_header = http_get_last_response_headers();
    }
    $headers = $http_response_header;

    Thank you! That works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions