send custom HTTP response with PHP - php

I want to send a custom HTTP response back to an application requesting a GET to a php script. The body is will be in binary format (octet-streams). I'm wondering if there is a simple way to do this? I am looking into the HttpResponse class in PECL but is having trouble installing it right now. I do not really need all the other functionalities that goes with it so I'm looking for something simpler.
Any help would be appreciated.

PHP has a header() function built in, so you can customise your response without requiring extra libraries:
<?php
header('Content-Type: application/octet-stream');
header('X-Powered-By: l3utterfly');
echo $binary_data;
?>

You can always set HTTP Headers using header() function, and then simply output binary data using print, echo or any other usual way. Send Content-Type http header to octet stream and it should work all right.

You can use the header function to send back whatever response you want. If you want to send back custome response codes, you could use:
<?
$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
//change the code and message to whatever. But I would keep it valid codes so browsers can handle it.
//see http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
header($protocol . ' 404 Not Found');
exit();
?>
And if you want to send binary data, change the header to the correct content-type and echo the binary data.

Related

When to use header('Content-Type: application/json') in PHP

I've been trying to figure out what's really the usage of header('Content-Type: application/json') in php scripts and I've found different questions and answers on stackoverflow about this subject but I still don't completely get it...
So here's the question : I've seen in some php projects this line of code, and I'm trying to understand
if this is used when another web page is calling this actual script (with ajax for example) so that the calling page can get a json from the php page
OR
if this script means that the php page is going to deal with json sent from another web page. Or maybe something else ???
Another thing that could help me if answered, lately I've been retrieving json from a resource (external url) with cURL and I had to put this header (Content-type:application/json) in the request. Did I send this header to the exertnal resource or was this MY header so that I can deal with the returned json ?
thanks
Ok for those who are interested, I finally figured out that header('Content-Type: application/json') is used when another page is calling the php script, so that the other page can automatically parse the result as json.
For instance i have in my test.php :
header('Content-type: application/json; charset=utf-8');
$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
echo json_encode($arr); // {"a":1,"b":2,"c":3,"d":4,"e":5}
and in my main.js
function test() {
$.ajax({
url: 'test.php',
type: 'GET',
//dataType: 'html',
success: function (response) {
alert(response);
}
});
};
When I dont have dataType set to "json" or when I don't have the header in my test.php, the alert gives {"a":1,"b":2,"c":3,"d":4,"e":5} which is a string (tried with typeof(response), and when I have this header, or dataType:"json", I get [object Object] from the alert. So this header function is there to indicate to the calling pages which type of data it gives back, so that you can know how to deal with it. In my script, if I didn't have header('Content-Type: application/json'), I would have to parse the response in the javascript like this : JSON.parse(response) in order to make it a json, but with that header, I already have a json object, and I can parse it to html with jSON.stringify(response).
You should always set the Content-Type for any HTTP response to describe what you're serving in that response.
Whether it's JSON or something else, and whether it's for an AJAX request or any other kind of request.
You should also set the Content-Type for any request to describe your POST payload.
In PHP, if you don't specify the Content-Type header in the script, it will default to whatever you've configured default-mimetype to be in your php.ini file which is usually text/html.
Calling header('Content-Type: application/json') will override that default setting so that the script will respond with that Content-Type when requested.
Also, when calling curl with a Content-type:application/json header, you're specifying the content type for your request body and not for the expected reponse.
W3 Description For the Content-Type
The purpose of the Content-Type field is to describe the data contained in the body fully enough that the receiving user agent can pick an appropriate agent or mechanism to present the data to the user, or otherwise deal with the data in an appropriate manner.
Shortly speaking, just to inform the receiver what kind of data he received and consume it accordingly.

PHP post server - how does posttestserver.com work?

I am trying to build a post server similar to posttestserver.com and have been runnning into lots of trouble.
The following returns nothing -
do {
$data = file_get_contents('php://input');
} while (empty($data));
header('HTTP/1.0 200 OK');
header('Content-Type: text/html');
var_dump($data);
I have also had a look into the use of sockets but the client should be directed to a URL rather than an ip/port for the clients ease. I suspect that this is what i need to use but am not sure where to start.
For what its worth, the client expects an HTTP 2XX response code from its HTTP POST request, and the client will not attempt submitting the next HTTP POST request while a previous request is still in flight.
Any ideas?
It would seem that you cannot capture and view the POST data in the one browser window.
For what its worth, here is the code that worked in the end -
$data = file_get_contents('php://input');
//do something with the data such as write to file or database
Then you could use the data in another PHP script.

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.

PHP HTTP header REST

I am developing an UI for a REST repository using PHP and the PEAR HTTP REQUEST package (http://pear.php.net/package/HTTP_Request/).
I created a HTTP GET request and it delivers the requested rdf/xml file as expected. But I want to extend this request and I can't get this working.
The repository allows sending zip files which are attached to an id. So I have to call the same URL which delivers the rdf/xml data, but I have to change the HTTP GET header from xml to accept: application/zip, before executing my request. This should deliver the zip instead of the rdf/xml file.
$req =& new HTTP_Request();
$req->setMethod(HTTP_REQUEST_METHOD_GET);
$req->setURL($url);
$req->clearPostData();
if (!PEAR::isError($req->sendRequest())) {
$response2 = $req->getResponseBody();
} else {
$response2 = "";
}
echo $response2;
Does anyone know how to modify the GET call to get this done? I really need help!
Furthermore I want to create a HTTP PUT request which uses multipart/form-data. Does anyone know how to make this?
Please help me! Thanks!
For your first question, you can set the Accept field of your GET request header by:
$req->addHeader('Accept', 'application/zip');
# assuming that this will trigger the server to respond with the zip and not xml
Question number 2:
# Set method to PUT
$req->setMethod(HTTP_REQUEST_METHOD_PUT);
# Attach file to request
$req->addFile('file_upload_field', '/path/to/file.ext', 'application/zip');
Read up more on file uploads using HTTP_Request.
To modify the request headers, take a look at the addHeader() method of the HTTP_Request object: http://pear.php.net/manual/en/package.http.http-request.headers.php
To change the method, use the setMethod(): http://pear.php.net/package/HTTP_Request/docs/latest/HTTP_Request/HTTP_Request.html#methodsetMethod

Determine REST POST/PUT request format

I'm developing a REST CodeIgniter Controller and need to POST and PUT to a URL in multiple formats.
The main formats I can think of would be:
XML
JSON
HTML Form data
There will be a response format defined in the URI e.g. /format/xml or /format/csv.
I don't want to have to define the request format in the URI as well.
I was wondering if anyone has any suggestions on finding out the request format so my script can complete the request.
I'm thinking it may be possible to get this data from the request headers "content-type"?
"content-type: text/xml" = XML
"content-type: application/json" = JSON
"content-type: text/plain" = HTLM Form data **i think!*
Would this method be robust or are there better approaches out there?
Thanks.
The content-type is the correct way to get the information you want.
Just make sure to throw an exception with some feedback and the correct http error code if the client calls it on the wrong format or do not pass the content-type header (you could also assume one content-type as default)
Also, you don't really have to use format/format_of_the_response . A better way would be to use the header Accept on the same way you use the header content-type
That method is robust as long as you know the your REST client will follow your content-type rule. If you control the client then this is fine. If you don't control the client then how acceptable is failure of the call when an unusual (or no) content-type is passed in?
Oh and for reference HTML form data has a content type of 'application/x-www-form-urlencoded'
I know this has been answered, but Phil Sturgeon wrote a REST Client and REST Server Library for codeigniter, might help you out a little bit.
http://github.com/philsturgeon/codeigniter-restclient

Categories