How to send a status code in PHP, without maintaining an array of status names?

68,477

Solution 1

There is a new function for this in PHP >= 5.4.0 http_response_code

Simply do http_response_code(404).

If you have a lower PHP version try header(' ', true, 404); (note the whitespace in the string).

If you want to set the reason phrase as well try:

header('HTTP/ 433 Reason Phrase As You Wish');

Solution 2

The actual text of the code is irrelevant. You could do

header('The goggles, they do nawtink!', true, 404);

and it'd still be seen as a 404 by the browser - it's the code that matters.

Solution 3

Zend Framework has a packaged solution in Zend_Http_Response

Zend_Http_Response::$messages contains:

/**
 * List of all known HTTP response codes - used by responseCodeAsText() to
 * translate numeric codes to messages.
 *
 * @var array
 */
protected static $messages = array(
    // Informational 1xx
    100 => 'Continue',
    101 => 'Switching Protocols',

    // Success 2xx
    200 => 'OK',
    201 => 'Created',
    202 => 'Accepted',
    203 => 'Non-Authoritative Information',
    204 => 'No Content',
    205 => 'Reset Content',
    206 => 'Partial Content',

    // Redirection 3xx
    300 => 'Multiple Choices',
    301 => 'Moved Permanently',
    302 => 'Found',  // 1.1
    303 => 'See Other',
    304 => 'Not Modified',
    305 => 'Use Proxy',
    // 306 is deprecated but reserved
    307 => 'Temporary Redirect',

    // Client Error 4xx
    400 => 'Bad Request',
    401 => 'Unauthorized',
    402 => 'Payment Required',
    403 => 'Forbidden',
    404 => 'Not Found',
    405 => 'Method Not Allowed',
    406 => 'Not Acceptable',
    407 => 'Proxy Authentication Required',
    408 => 'Request Timeout',
    409 => 'Conflict',
    410 => 'Gone',
    411 => 'Length Required',
    412 => 'Precondition Failed',
    413 => 'Request Entity Too Large',
    414 => 'Request-URI Too Long',
    415 => 'Unsupported Media Type',
    416 => 'Requested Range Not Satisfiable',
    417 => 'Expectation Failed',

    // Server Error 5xx
    500 => 'Internal Server Error',
    501 => 'Not Implemented',
    502 => 'Bad Gateway',
    503 => 'Service Unavailable',
    504 => 'Gateway Timeout',
    505 => 'HTTP Version Not Supported',
    509 => 'Bandwidth Limit Exceeded'
);

Even if you're not using zend-framework you might be able to break this out for personal use.

Solution 4

Yeah, just do this...

header('x', true, 404);

The first string parameter can be anything that doesn't contain a :. PHP will then replace and go with the standard phrase. The second parameter specifies "always replace", and the 3rd is the status code you want.

References:

Share:
68,477
NikiC
Author by

NikiC

PHP core developer working at JetBrains. Studied physics and computer science at TU Berlin. Blog Twitter GitHub PHP-Parser: A PHP parser written in PHP FastRoute: Fast request router for PHP scalar_objects: Extension adding support for method calls on primitive types in PHP iter: Iteration primitives using generators Contact mail: [email protected]

Updated on December 16, 2020

Comments

  • NikiC
    NikiC over 3 years

    All I want to do, is send a 404 status code from PHP - but in a generic fashion. Both Router::statusCode(404) and Router::statusCode(403) should work, as well as any other valid HTTP status code.

    I do know, that you can specify a status code as third parameter to header. Sadly this only works if you specify a string. Thus calling header('', false, 404) does not work.

    Furthermore I know, that one can send a status code via a header call with a status line: header('HTTP/1.1 404 Not Found')

    But to do this I have to maintain an array of reason phrases (Not Found) for all status codes (404). I don't like the idea of this, as it somehow is a duplication of what PHP already does itself (for the third header parameter).

    So, my question is: Is there any simple and clean way to send a status code in PHP?

  • ircmaxell
    ircmaxell over 13 years
    Isn't this exactly what the question specified that they didn't want?
  • NikiC
    NikiC over 13 years
    Can't this have any implications? Can one do this, because X denotes custom headers? Is this considered bad style?
  • ircmaxell
    ircmaxell over 13 years
    Are you really suggesting this as a valid and clean way of setting a status code?
  • Mike B
    Mike B over 13 years
    @ircmaxwell, As you said, there is no maintaining this list as it's already developed to spec.. and the spec isn't changing.
  • Brad
    Brad over 13 years
    @nikic, I don't believe so, because you aren't specifying the full header. See my latest edit.
  • Marc B
    Marc B over 13 years
    No, just a goofy way to show that the text of the header is irrelevant, as long as the status code is there.
  • Kyle Wild
    Kyle Wild over 13 years
    +1 because it's true, and because a comment like that is certainly going to make that apparent to any future developers :) @ircmaxell - hey, it's php!
  • Brad
    Brad over 13 years
    While this is certainly true, the message is provided for the user to read, and some user-agents (usually, not browsers but multimedia players for example) will display them.
  • Marc B
    Marc B over 13 years
    Sure, not saying to put something totally different, like "Access denied" for a 404, but "Not found" is just a simple suggested default. You could put a 500 page poem that boils down to the same thing if you so chose.
  • NikiC
    NikiC over 13 years
    Uhm, I'm not sure I understand this. Will PHP send a The goggles, they do nawtink! header (which obviously is not existent) or does it ignore it as an invalid header or what does it do?
  • ircmaxell
    ircmaxell over 13 years
    @nikic: PHP will pass it on, it's up to the webserver (Apache, etc) to throw it away or not...
  • NikiC
    NikiC over 13 years
    @ircmaxell: Thanks. I will use this variant then, assuming that any reasonable server will throw this header away.
  • hakre
    hakre about 11 years
    +1 for the whitespace at the beginning. The second parameter can be either true or false according to my experience.
  • hakre
    hakre about 11 years
    This suggestion provokes a "HTTP/1.1 500 Internal Server Error" per status-line and Apache offers a response body in HTML that is according to the status code (integer 404 in the answer). Even though PHP was sending a response body (Apache 2.2.22/mod_fcgid/2.3.6).
  • Pacerier
    Pacerier almost 11 years
    @hectorct, why do we need true as the second parameter?
  • hectorct
    hectorct almost 11 years
    It doesn't matter. The result is the same if the second parameter is set to true or false. In fact, it can be marginally faster with it set to false because php doesn't try to replace previous headers.
  • RileyE
    RileyE almost 11 years
    I love that the Mike and Mark B brothers decided to help us all out here. Also, @eyelidlessness, thanks for making an awkward situation at my office. Uncontrollable laughter is a curse.
  • Clamburger
    Clamburger about 9 years
    @MikeB Untrue; RFC 6585, for example, added more status codes.
  • Gregor Macgregor
    Gregor Macgregor about 8 years
    No, As stated by @hakre this gives me a server error which redirects to my 500 error page with the header "HTTP/1.1 500 Internal Server Error". The correct answer is there are two choices. 1) http_response_code(404); or for older PHP versions 2) header(' ', true, 404); with whitespace in the quotes.