18
echo http_response_code('400');
return "error";

I have a page required to output http status

I set http_response_code(400) & try to use postman to post.

It always return 200.

why http_response_code is not working?

Ole Haugset
  • 3,709
  • 3
  • 23
  • 44
Benjamin W
  • 2,658
  • 7
  • 26
  • 48
  • Have you activated error reporting? Is it perhaps complaining that *headers are already sent*? Because you've `echo`d some other content before? – deceze Jan 24 '18 at 09:29
  • Do you use integer for the "http_response_code" ? – DiabloSteve Jan 24 '18 at 09:31
  • 1
    You should specify `It always return 200`. You mean in body or real HTTP status code? Code `echo http_response_code('400')` prints to body previous status code and do not have to be exact as finally sent real status code. – mikep Jan 24 '18 at 10:01
  • @deceze function http_response_code() does not emit that warning about headers are already sent. Se my answer bellow. – mikep Jan 24 '18 at 10:08
  • @mikep Hmm, okay; but it will fail to set the response code header if headers have already been output. – deceze Jan 24 '18 at 10:11
  • Terrible piece of code... we see there `return` but above it is `echo`. What function does? Prints status code or return string "error"? – mikep Jan 24 '18 at 14:09
  • Was the problem here that you were looking at the *response body*, which contained the textual output of this function, which as the documentation says will be the *previous* response code; instead of you checking the actual *response code*? – deceze Aug 10 '20 at 06:33

5 Answers5

22

Maybe you already sent some output before calling http_response_code(). It causes HTTP 200 silently with no warning (it does not emit well known headers are already sent). You can send some output but you can not exceed value of php directive output_buffering (see your phpinfo page). Usually it is set to 4096 bytes (4kB). Try to temporary increase output_buffering in php.ini to much higher value (do not forget to restart webserver). Note that output_buffering is type PHP_INI_PERDIR and can not be changed at runtime e.g. via ini_set().

PHP_INI_PERDIR: Entry can be set in php.ini, .htaccess, httpd.conf or .user.ini

I recommend to use integer instead of string: http_response_code(400) ... just to be consistent with PHP doc. But http_response_code() works well also with strings - I have tested it now, so string does not cause your problem as @DiabloSteve indicates in comments.

mikep
  • 5,880
  • 2
  • 30
  • 37
  • Thank you! I had `echo $error; http_response_code(500); die;` and couldn't work out why I got 200 OK! Really should be at least a warning there I think – Adam Feb 07 '19 at 11:50
  • This can also happen if you have called `header('HTTP/1.1 200 Ok')` earlier, a code base I recently worked on had that added early on in the code and it made `http_response_code` fail silently... – Linus Unnebäck Jul 19 '20 at 12:29
  • Note, sometimes they “already sent some output” issue can be very subtle. E.g., I had a PHP file that had a single space before the ` – Rob Jun 20 '21 at 01:54
  • Just in case, nowadays, PHP logs should indicate a warning like `Warning: Cannot modify header information - headers already sent by...` by default. Related: https://stackoverflow.com/a/8028987/5113030 (*How to fix "Headers already sent" error in PHP*...) – Artfaith Mar 29 '22 at 23:50
2

You need to not return Your function as You did:

return "error";

Answer

You need to exit Your function like this:

http_response_code(400);
exit;

Also echo and the error code like a string is redundant

Claudio Ferraro
  • 4,551
  • 6
  • 43
  • 78
0

The reason you get a persistent 200 ok response code, is because you have some enters (newlines) before you have your php tag :

line 1 line 2

and this can also be between php tags:

line 1 line 2

Make sure to remove these enters or else these newlines will be considered as output. This is why any http_response_code(xxx) you throw in after that has no impact because the newline output represent a '200 ok' response. I have simulated your problem with r-client (should be the same as postman on chrome).

  • This is just one case of the "some output sent" mentioned in @mikep's answer, but is a "gotcha" i guess. – Adam Feb 07 '19 at 11:51
0

In my case it was

<pre>
<?php
  http_response_code(404);
?>
</pre>

this code returns 200, because pre tag already sent, before php started

<?php
  http_response_code(404);

returns 404 successfully because no content sent yet.

even a space is not allowed before <?php otherwise will return 200

Vladimir Buskin
  • 614
  • 4
  • 8
-3

You need to call http_response_code twice like this

http_response_code(400); // this will get previous response code 200 and set a new one to 400
echo http_response_code(); // this will get previous response code which is now 400
return;
avpav
  • 452
  • 4
  • 7
  • Yes, and the http_response_code parameters should be integers. http://php.net/manual/en/function.http-response-code.php – DiabloSteve Jan 24 '18 at 09:33
  • 32
    This is utter nonsense. – deceze Jan 24 '18 at 09:34
  • 2
    the problem is i use postman to post and it shows status is 200 – Benjamin W Jan 24 '18 at 09:40
  • See this: https://stackoverflow.com/a/12018482/3102325. Don't return anything else before `http_response_code(405);` – Marian07 Feb 04 '19 at 21:36
  • @deceze Who are you responding to? If it's to the person who commented the "accepted answer", I believe he is correct when he states that you have to invoke the function twice. The first time to set, the second time it'll return the last set code when called upon without an argument given. – I try so hard but I cry harder Aug 08 '20 at 21:24
  • 4
    @Itry I'm saying this answer is nonsense. You most certainly do not need to invoke it twice for it to work. – deceze Aug 09 '20 at 08:45
  • @deceze care to show any sources stating this? The problem OP had, was that he got 200 returned (which was the last set HTTP code). If you wish to return another code, you need to set it and then retrieve it. So I doubt this answer is nonsense. "If response_code is provided, then the previous status code will be returned. If response_code is not provided, then the current status code will be returned. Both of these values will default to a 200 status code if used in a web server environment." Source: https://www.php.net/manual/en/function.http-response-code.php – I try so hard but I cry harder Aug 09 '20 at 18:05
  • 2
    @itry “Returned” means the function returns it to the caller (i.e. your code). It does not mean “return” as in the status code that will be output for the HTTP response. You can use this function to check and/or set the status code that will be used for the HTTP response. **You don’t _have to_ do both.** – deceze Aug 10 '20 at 04:52
  • @deceze So, if I understood you correctly, you say that he doesn't need to echo it the second time around? Setting it will be enough? – I try so hard but I cry harder Aug 10 '20 at 12:27
  • @deceze, it literally represents the official manual page example - sets and "visualizes" the change. How is that nonsense? Yes, the answer is pretty short and weak (not quite informative), but not nonsense. Please check the manal page mentioned in the current comment section by `DiabloSteve`: https://www.php.net/manual/en/function.http-response-code.php#refsect1-function.http-response-code-examples – Artfaith Jan 31 '22 at 17:57
  • @Angel In the context of this question, this answer is nonsense. It does not fix OP’s problem. You do not have to call this twice and `echo` it for it to be effective. OP’s problem is something else and requires a different solution. – deceze Jan 31 '22 at 18:10