44

A former developer wrote or client-server api in PHP. It simply sends messages as xml using post/response in a very simplistic fashion. The problem is that even when there is an error (ex: invalid arguments passed into the server side) we get a HTTP 200 response with a page like this

<h4>Unknown error!</h4>

In firebug I can see that the actually HTTP response is a 200. How can we send a different response (ie:503) when we programatically detect in our php code that it is appropriate to do so.

benstpierre
  • 32,833
  • 51
  • 177
  • 288

4 Answers4

94

Use PHP's header function to send the code (along with the HTTP version and any other headers you need). More complete info:

When to send HTTP status code?

http://php.net/manual/en/function.header.php

http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

header('HTTP/1.1 503 Service Temporarily Unavailable');
header('Status: 503 Service Temporarily Unavailable');
header('Retry-After: 300');//300 seconds
Community
  • 1
  • 1
ssube
  • 47,010
  • 7
  • 103
  • 140
  • 9
    Why do you hard code the HTTP/1.1 assumption in? What happens if the client is using HTTP 1.0 ? – Pacerier Jul 14 '13 at 14:08
  • 1
    @Pacerier so what would you do insead? How would I write this so that it covers both HTTP 1.0 and HTTP 1.1? All the examples show it as given in the answer – Inigo Mar 04 '15 at 20:49
  • 2
    I guess `header($_SERVER["SERVER_PROTOCOL"] . ' 503 Service Temporarily Unavailable');` ? – Inigo Mar 04 '15 at 20:49
  • 3
    I guess in PHP you could write it like this: `$protocol = "HTTP/1.0"; if ( "HTTP/1.1" == $_SERVER["SERVER_PROTOCOL"] ) $protocol = "HTTP/1.1"; header( "$protocol 503 Service Unavailable", true, 503 ); header( "Retry-After: 3600" );` source: https://yoast.com/http-503-site-maintenance-seo/ – Axel Mar 06 '15 at 20:11
  • "The difference between HTTP 1.0 and HTTP 1.1 is that In To signify successful requests and to identify transmission problems, HTTP 1.0 Status codes were utilized. HTTP/1.1 supports chunk transfers, which enabled material to be streamed in chunks and extra headers to be delivered after the message body." – Avatar Feb 01 '22 at 13:27
5

I worked on a site that had been hacked and had to use HTACCESS to do this.

<IfModule mod_rewrite.c>

 RewriteEngine on

 # let this (iescaped) IP address see the real site:
 # RewriteCond %{REMOTE_ADDR} !^123.45.67.89

 RewriteCond %{REQUEST_URI} !/maintenance.php$ [NC]

 RewriteCond %{REQUEST_URI} !.(jpe?g?|png|gif|css|js) [NC]

 RewriteRule .* /maintenance.php [R=503,L]

</IfModule>
Ben Racicot
  • 5,332
  • 12
  • 66
  • 130
2

On top of your script (or really, before any output is sent as a response):

<?php header("HTTP/1.0 404 Not Found"); or any other HTTP status code.

chelmertz
  • 20,399
  • 5
  • 40
  • 46
  • 5
    This relies on PHP's ability to map the status code from the header type (special-case handling) - it really should be header("HTTP/1.0 404 Not Found", true, 404) – symcbean May 05 '10 at 13:18
  • @symcbean Nice, I've never noticed that. Thanks! – chelmertz May 05 '10 at 17:39
0

A good class for achieving this can be found here: http://www.krisjordan.com/php-class-for-http-response-status-codes/ - use it like this (before any other output):

<?php header(StatusCodes::httpHeaderFor(503)); ?>
Chris
  • 6,568
  • 3
  • 22
  • 21
  • 2
    It is better to use something like `symfony/http-foundation` https://symfony.com/doc/current/components/http_foundation.html – LONGMAN Feb 24 '18 at 19:35