2

I was reading this question and as a result I can successfully test for headers of the form:

header('X-Something: value');
header('Content-Type: text/html');

However, I have code that sets the response code, and I'd like to verify this is working correctly in my units tests too, but they don't come back in the xdebug_get_headers return value. The calls look like:

header('HTTP/1.1 201 Created');
header('HTTP/1.1 422 Unprocessable Entity');

Is there anyway to check for this header as well? Or do I just have to rely on the rest of the return values to prove my controller is working

Community
  • 1
  • 1
Derokorian
  • 1,260
  • 1
  • 10
  • 16

2 Answers2

3

You can use the http_response_code() function to return the values you set:

print_r("Response Code: " . http_response_code());

Result:

Response Code: 422

Documentation: http_response_code() - PHP 5.4.0+

l'L'l
  • 44,951
  • 10
  • 95
  • 146
  • 1
    Thank you! I could not find this for some reason. Is there anyway to get the text, ie 'Unprocessable Entity' – Derokorian Oct 12 '14 at 18:26
  • You're welcome! There are several ways to get the full response code. The quickest way is to use another obscure php function ( ***[$http_response_headers](http://php.net/manual/en/reserved.variables.httpresponseheader.php)*** ) — here's a quick ***[example](https://gist.github.com/anonymous/7d483f25787adf87746b)*** – l'L'l Oct 12 '14 at 20:05
  • It doesn't seem there is a way to do this. The `$http_response_headers` does a completely different thing and has nothing to do with the "outgoing" headers. – Ian Bytchek Oct 12 '14 at 20:09
  • @l'L'l, No it's not. :) – Ian Bytchek Oct 12 '14 at 20:14
  • You are. It returns response headers when you get something from the script, in your example those are the response headers of request sent by `file_get_contents("http://example.com/")`. If you do `http_response_code(404)` and then check `$http_response_headers` you'll be getting `null`. According to the documentation. – Ian Bytchek Oct 12 '14 at 20:18
  • `header('HTTP/1.1 403 You shall not pass.'); var_export($http_response_headers);` gives me Undefined variable: http_response_headers, tho if i remove the s and make it singular (like the manual page you linked to), I get the same error! Further more the manual states "When using the HTTP wrapper, $http_response_header will be populated with the HTTP response headers." So Ian is correct, you would have to open a stream to get this to work. Not sure the code your using to produce the output in your links. Try using codepad to share/show results :) – Derokorian Oct 12 '14 at 21:43
  • Also you're quick example in your first comment, uses a stream. :) – Derokorian Oct 12 '14 at 21:45
  • Depending on your environment you could also use `header_register_callback`, which from your last comment sounds like what you want. – l'L'l Oct 12 '14 at 22:05
  • @Derokorian, [Try this if you're interested](https://gist.github.com/anonymous/56191ddd70c12e23966a); I only spent a couple minutes on it, but potentially could be made into a class for unit testing and it doesn't use a stream. – l'L'l Oct 13 '14 at 03:16
  • 1
    @IanBytchek, Apologies for misunderstanding your comment earlier. The stream method using `$http_response_headers` does work for requests, but not outgoing responses directly. There really should be a function or method for getting the full response in my opinion — so hopefully a class will show up sooner or later. – l'L'l Oct 13 '14 at 03:36
  • @l'L'l, Yeah, it seems rather strange it's not there. There are a few functions that keep coming up here and there that are undocumented. I think raising the questions on bugs.php.net is the way to go. – Ian Bytchek Oct 13 '14 at 03:39
  • @l'L'l, that gist above would be the only solution afaik, given only default states are used, though you can set the message to anything you want. Which makes this situation so strange. There must be a proper way of doing that. – Ian Bytchek Oct 13 '14 at 03:42
  • Eh, looks like I'm using all standard message texts, so as long as the code is right the text should match. Just trying to test the different branches of the function. This isn't an integration test tho, as its not dependent on any code not in the function under test itself. There should definitely be a way to get the text too, but I'll just validate that in the integration tests. – Derokorian Oct 13 '14 at 17:23
  • @Derokorian, I setup the array `$t` in the code example so you could add whatever response codes you wanted. Then all you need to do is use `setHeader();`, so for example if you wanted to test 404 you'd do `setHeader(404);` and that's it. It's definitely odd that there doesn't seem to be any implementation on the local side for getting that info easily. As Ian mentioned, it might be best to file a bug with the PHP developers. – l'L'l Oct 13 '14 at 17:40
0

If I understand everything correctly, then you are looking for headers_list(), which returns the list of response headers sent (or ready to send), see the docs. Doing the following:

header("X-Sample-Test: foo");
header('Content-type: text/plain');

var_dump(headers_list());

Will output this:

array(3) {
    [0]=>
    string(23) "X-Powered-By: PHP/5.1.3"
    [1]=>
    string(18) "X-Sample-Test: foo"
    [2]=>
    string(24) "Content-type: text/plain"
}
Ian Bytchek
  • 8,804
  • 6
  • 46
  • 72
  • I tried headers_list but it produces the same problem where it only returns headers of the format `header('Key: Value');` – Derokorian Oct 12 '14 at 18:26
  • Sorry, I see what you mean now. Really weird though, if I were you I'd file an issue at [bugs.php.net](http://bugs.php.net), to get this clarified. On the other side, this is somewhat similar to [this answer](http://stackoverflow.com/a/25772868/458356) – you are interested in the part about Behat. Testing your controllers with PHPUnit is not the best idea… – Ian Bytchek Oct 12 '14 at 20:07