99

I have an API call for which I need to be able to run some checks and potentially return various status codes. I don't need custom views or anything, I just need to return the proper code. If the user hasn't passed proper credentials, I need to return a 401 status. If they haven't sent a supported request format, I need to return a 400 status.

Because it's an API, all I really want to do is set the response status and exit with a simple, stupid message about why the request failed (probably using a exit). Just enough to get the job done, but I haven't been able to get this to work right. I've tried using PHP's header() and Cake's $this->header() (this is all in the controller), but although I get the exit message, the header shows a 200 OK status.

Using the code below, I get the message, but the header isn't set. What am I missing?

  if( !$this->auth_api() ) {
    header( '401 Not Authorized' );
    exit( 'Not authorized' );
  }
Wesley Murch
  • 101,186
  • 37
  • 194
  • 228
Rob Wilkerson
  • 40,476
  • 42
  • 137
  • 192

6 Answers6

139

PHP <=5.3

The header() function has a parameter for status code. If you specify it, the server will take care of it from there.

header('HTTP/1.1 401 Unauthorized', true, 401);

PHP >=5.4

See Gajus' answer: https://stackoverflow.com/a/14223222/362536

Community
  • 1
  • 1
Brad
  • 159,648
  • 54
  • 349
  • 530
  • 1
    Interesting. I've never seen this in use, but the manual certainly agrees with you. This feels like a better method to me. – Wesley Murch May 28 '11 at 21:07
  • Worthy of a punitive head slap. I totally missed the obvious in my haste to knock this out. Thanks for setting me straight, guys. – Rob Wilkerson May 28 '11 at 21:19
  • I found you need to put the status description into the first parameter to get this one working... – Stephen RC Aug 21 '11 at 23:20
  • @Valorin, you shouldn't need to. The server will fill it in for you. In any case, the status description doesn't matter anyway... only the status code. Just out of curiosity, what server are you running? – Brad Aug 21 '11 at 23:26
  • 1
    @Brad, Apache on Ubuntu. The PHP help docs actually say: "Note that this parameter only has an effect if the string is not empty.", and the only way I got it working was to put the desc in. I am using an AJAX call, so that might have something to do with it. Eitherway, it's working for me now. – Stephen RC Aug 21 '11 at 23:50
  • Yes, only the string was not empty, it worked fine for me. Thanks ! – Prakash Raman Feb 02 '12 at 22:11
  • @Brad, my web server intercepts all output to automatically enable transfer encoding if output exceeds 8k bytes. In other words, I can simply *force* the response to be HTTP/1.0 or HTTP/1.1. Is there any way to simply set the response code and message without modifying the HTTP version? – Pacerier Jun 06 '13 at 23:40
  • 5
    You should use `HTTP/1.1`. Now, as of PHP 5.4, you can use `http_response_code()` to set the code. That's the best method. Otherwise, you have to attach it to some header. You could always do something like `header('X-Ignore-This: something', true, 401)` – Brad Jun 07 '13 at 02:05
131

Since PHP 5.4 you can use http_response_code.

http_response_code(404);

This will take care of setting the proper HTTP headers.

If you are running PHP < 5.4 then you have two options:

  1. Upgrade.
  2. Use this http_response_code function implemented in PHP.
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
Gajus
  • 69,002
  • 70
  • 275
  • 438
12

Why not using Cakes Response Class? You can set the status code of the response simply by this:

$this->response->statusCode(200);

Then just render a file with the error message, which suits best with JSON.

adriaroca
  • 172
  • 11
rookian
  • 1,045
  • 14
  • 38
12

I don't think you're setting the header correctly, try this:

header('HTTP/1.0 401 Unauthorized');
Wesley Murch
  • 101,186
  • 37
  • 194
  • 228
5

I had the same issue with CakePHP 2.0.1

I tried using

header( 'HTTP/1.1 400 BAD REQUEST' );

and

$this->header( 'HTTP/1.1 400 BAD REQUEST' );

However, neither of these solved my issue.

I did eventually resolve it by using

$this->header( 'HTTP/1.1 400: BAD REQUEST' );

After that, no errors or warning from php / CakePHP.

*edit: In the last $this->header function call, I put a colon (:) between the 400 and the description text of the error.

stealthyninja
  • 10,343
  • 11
  • 51
  • 59
-2

As written before, but for beginner like me don't forget to include the return.

$this->response->statusCode(200);
return $this->response;
Opal
  • 81,889
  • 28
  • 189
  • 210
coder
  • 23
  • 8