Skip to content

http_response_code() does not override the status code generated by header() #18582

Closed

Description

@kkmuffme

Description

Originally reported here https://bugs.php.net/bug.php?id=81451
However, while the original issue won't necessarily require a fix/just a documentation update, I want to take this issue further and report it as a bug, since this behavior makes it impossible to retrieve the actual HTTP status code after it was changed with http_response_status()

The following code:

<?php
http_response_code( 401 );
header( 'HTTP/1.1 404 Not Found' );
$is_404 = http_response_code( 403 );
$should_be_404_but_is_403 = http_response_code();

echo $is_404 . PHP_EOL;
echo $should_be_404_but_is_403 . PHP_EOL;

Resulted in this output:

404
403

But I expected this output instead:

404
404

Since headers_list() does not contain the original header() either, it's impossible to identify the actual HTTP response code when the HTTP response header was set manually and it was later overwritten (since the overwritten value is not actually used)

I think the way forward with this issue is:

  1. if the header is manually set already and http_response_code( 123 ) is used, PHP should emit a warning, that this has no effect since the HTTP status is manually set
  2. with the next major version, remove this warning again and actually fix the behavior, so http_response_code will actually overwrite any manual HTTP response code headers

PHP Version

PHP 8.4

Operating System

No response

Activity

  1. iluuu1994 commented on Jun 27, 2025

    @iluuu1994
    Member

    Sorry for the delay. Would it not be better to allow http_response_code() as long as headers have not been sent yet? This is consistent with how header('HTTP/1.1 xyz Message') itself works. This can be implemented simply by clearing SG(sapi_headers).http_status_line on http_response_code().

    I created a PR for this here: #18962

  2. kkmuffme commented on Jun 29, 2025

    @kkmuffme
    Author

    Would it not be better to allow http_response_code() as long as headers have not been sent yet?

    Yes, that was my "step 2"
    If this can be done right away it's even better 👍

  3. bukka commented on Jul 21, 2025

    @bukka
    Member

    I commented on the PR, as that silent change approach seems like a BC break to me even though it makes things more consistent.

    I would personally prefer the approach with warnings.

  4. added a commit that references this issue on Sep 23, 2025
    f389ade
  5. kkmuffme commented on Oct 6, 2025

    @kkmuffme
    Author

    I created a follow-up PR #20036 to fix the original bug that http_response_code() returned the wrong HTTP status:

    this behavior makes it impossible to retrieve the actual HTTP status code

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