Set Response Status Code [duplicate] - php

This question already has answers here:
PHP: How to send HTTP response code?
(8 answers)
Closed 6 years ago.
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' );
}

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

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:
Upgrade.
Use this http_response_code function implemented in PHP.

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.

I don't think you're setting the header correctly, try this:
header('HTTP/1.0 401 Unauthorized');

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.

As written before, but for beginner like me don't forget to include the return.
$this->response->statusCode(200);
return $this->response;

Related

Slim framework does not send http headers when http status is not 200

I am using the PHP Slim framework v4. I try to send an HTTP header and an HTTP error code. With HTTP status 200 it is working fine. When specifying 304, the response error code is fine, but the headers are missing in this case.
return $response->withHeader('Content-Type', 'text/plain')
->withHeader('X-Error-Message', $message)
->withHeader("Access-Control-Allow-Origin", $_SERVER['HTTP_ORIGIN'])
->withStatus(200);
This works, but the code as stated below does not submit the headers
return $response->withHeader('Content-Type', 'text/plain')
->withHeader('X-Error-Message', $message)
->withHeader("Access-Control-Allow-Origin", $_SERVER['HTTP_ORIGIN'])
->withStatus(304);
Any ideas why this isn't working?
As you see, I need a CORS header to avoid that the browsers throws an error.
I guess you get this internal warning in PHP:
Warning: Undefined array key "HTTP_ORIGIN"
This warning will be sent by PHP before the Slim $response is getting handled.
Please note that the HTTP_ORIGIN header is not always present, and it is not good practice to rely on this key. Instead it's better to check the domain and send a * when it's valid.
This prevent this warning try this:
$httpOrigin = $request->getServerParams()['HTTP_ORIGIN'] ?? '';
if($httpOrigin) {
$response = $response->withHeader('Access-Control-Allow-Origin', $httpOrigin);
}
return $response->withHeader('Content-Type', 'text/plain')
->withHeader('X-Error-Message', $message)
->withStatus(403);
The issue as reported in not caused by the slim framework. Our hosting provider is using apache as web server. Apache is causing this behaviour.
See https://bz.apache.org/bugzilla/show_bug.cgi?id=61820 for more details.

How to get HTTP status answer from GuzzleHttp response by php Laravel?

I develop at php Laravel.
I receiving GuzzleHttp response from Mailgun as Object and can't to get from it the status.
the Object is:
O:8:"stdClass":2:{s:18:"http_response_body";O:8:"stdClass":2:{s:6:"member";O:8:"stdClass":4:{s:7:"address";s:24:"test_of_json-4#zapara.fr";s:4:"name";s:10:"not filled";s:10:"subscribed";b:1;s:4:"vars";O:8:"stdClass":0:{}}s:7:"message";s:36:"Mailing list member has been created";}s:18:"http_response_code";i:200;}
I need just last data pair:
"http_response_code";i:200;
to get it into variable, like:
$http_response_code = 200;
or even just its value.
To get string as I cited above I use
$result_ser = serialize($result);
but yet can't to extract value of variable.
Also I tried this:
$this->resultString .= \GuzzleHttp\json_decode($result_ser, true);
and get error.
Please, explain me , How to get/extract value I needed?
To take the response status code you can use the function getStatusCode :
$response = $client->request();
$statusCode = $response->getStatusCode();
while to take the body of response you can use :
$contents = $response->getBody()->getContents();
let's consider your request is something like
$response = $client->get("https://example.com");
if ( $object_res->getStatusCode() == 200 ) { // here you are checking your http status code
}
$object_res->getStatusCode() is the method to get http status code.
refer docs, there is simple example in this page.
I found that 'mailgun/mailgun' package uses its own HTTP client which also uses 'RestClient' and these classes are return stdObject.
In that Object there is property 'http_response_code' containing HTTP response code like 200, 400, 401 etc.
This property accessible by standard way $object->property and it's a solution of my query in this case.
For anybody who will read this question and answers I should to explain one thing that I not cleared in question.
I made request to the Mailgun API for subscribing member to mailing list. The API returns stdObject, not JSON or XML data.
But also there is one more strange thing - stdObject returned when request is successful only. If request fails you'll get just Exception thrown with message and without code. This forced me, if fail, to parse message body instead of get and resolve error code.
$responseObj->getStatusCode();

How to not send a response body

I'm trying to send a header response back from our api with a http status code 201 Created and a Location:header.
No matter what I do I get a response body too, something that I don't want.
If I return an empty string (return "";), restler will put the string '""' in the response body. If I return null or do not return anything at all restler will put the string 'null' in the response body.
How do I tell Restler to not send anything but headers?
UPDATE :-
With the latest release of Restler 3 RC4. Returning null sends empty body for the response
This behaviour can be changed by setting
Defaults::$emptyBodyForNullResponse = false;
You can use #status comment to set the response code to 201
and #header comment for setting the location header
For older versions use the technique described below
From your api method, set both status and location header using header function followed by die or exit
header("HTTP/1.0 201 Created");
header('Location: http://api.example.com/item/45');
die();
This is a very valid use case that demands better way of doing this, We will soon update this answer with those solutions
Thanks for contributing to Restler :)

Return a HTTP 200 Code to the POST client?

I have a server sending POST to me. I need to reply with HTTP 200 OK.
Server needs kind of like a "Go Ahead!" prompt before it executes another action.
It requires a HTTP 200 response.
EDIT
I've tried the header(), but the server for some reason won't read it?
The 200 code is a standard response to a successful request... Even echoing out an empty json string would result in a 200 OK status.
echo json_encode(array());
If all you want to do is signal to your client that some process was completed, you can just echo back a custom status message or even a blank object like I demonstrated above.
If you want to actually manually send the 200 header you can do so like this -
header('Status: 200');
Make sure that this header is send before you have any output from the server.
This function call does the job:
http_response_code(200);
See: http://php.net/manual/en/function.http-response-code.php
This function call can be thrown anywhere in the server code -- the order of when this function is called does not seem to matter.

sending a response from a php script to iOS

I am creating an iPhone app which sends a username and password to a php script, the php script then looks in a mySQL database for the values and sets a boolean to either 0 or 1, depending on whether or not the user should be authenticated. I really have no idea where to start or even what I should Google to look into how to do this.
Is this feasible?
Is this the proper way to authenticate a user in an iOS app?
Thanks!
There are various types to achieve this.
a) Generate an XML or JSON file in PHP, and read the content back in iOS. (this method gives you the benefit of fetching any extra data if you want).
b) Send back HTTP header() from PHP, and read the HTTP response code. you can do something like this.
function checkLogin()
{
//Check login
if($login == true) {
header('HTTP/1.1 200 OK');
} else {
header('HTTP/1.1 401 Unauthorized');
}
}
c) You can output anything in PHP(plain text, JSON, HTML etc.), as the output generated by PHP will be received as HTTP response.
Anything the PHP script outputs will be returned as the HTTP response. Simply output something meaningful, and read it in the client.
The simplest solution would be to use HTTP status codes. Then you don't even have to care about the response body.
If authenticated: "HTTP 200 OK"
If unauthorized: "HTTP 401 Unauthorized"
Resource: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
You can write a php script like this:
<?php
// the authentication procedures memorized in the $authentication variable the result of authentication process. Supposed to be 1 if successful
echo $authentication;
?>
Call this script from your iOS by using an NSURLRequest object for example.
P.S.: However, for data exchange between the client and the server you should use the JSON format.

Categories