I'm writing an API and want to follow the REST approach. As I understand it, if I want to let API users update specific records a PUT http://server/specific_resource type request should be supported. Of course, they're not doing a GET and they'll need to pass along the new data and my question is how to do this (in my specific case only updating some of the fields of the specified record, but that's not so relevant here). There are two approaches I can think of: including the data in the request body (using curl: curl -X PUT -d "key=value" http://server/specific_resource) or in a query string (using curl: curl -X PUT http://server/specific_resource?key=value).
Unfortunately, regardless of the approach I take, it seems very hard to get the provided data. The problem seems to be that PHP only really completely understands two HTTP methods, GET and POST, with PUT considered to be for file uploads. If I include the data in the body then the only way to access it seems to be via an fopen('php://input') call. For instance, http_get_request_body() doesn't provide the data. Likewise, the information can't be found in the $_REQUEST superglobal. If I don't want to have to process the raw request body with fopen('php://input') then it appears that I must send the data as query string parameters, as the data will appear as elements of the $_GET superglobal (and so also $_REQUEST).
I'm specifically using CakePHP and it seems to only populate the form array of the params array in my controller method if the request was a POST. Query string parameters are put in params' url array regardless of the request method if used in the request URL. Not surprisingly, I'm not the only one who has run into this.
What is the solution that you'd suggest? Process the input stream? Use query string parameters? Just forget the PUT verb and use POST instead?
Try this blog entry about parsing PUT data for a REST interface in PHP.
Use the server http method variable to check if its a PUT.
I sugget you to take a look at SLIM source code to check how they handle it
cheer!
Related
It took me a while to understand this, being that it was a little obvious. I will answer myself, so other can benefit of the answer and ofcourse to see if there's a better way to do this. The problem was based on Axios/Yii2 but I guess this will apply equally to other frontend libraries/frameworks sending data to Yii2.
I needed to post data from a small form made on Vuejs, sending the request Axios to a Action/Controller on Yii2, so data is sent on a simple POST request and the post is getting to the controller, but I was not able to receive the data on the action, $_POST | $post arrives empty (checked using xdebug).
As much as I remember, this had something to do with security. But I already tried by disabling public $enableCsrfValidation, so that was not the problem.
public $enableCsrfValidation = false;
But no matter what, data was not being added to the request/post data inside Yii2.
The following Image, explains the problem you will find there:
The Axisos method that sends the post with test data.
The Yii2 Action stpoed at the place, I should be able to see data.
The capture of the xdebug variables and data for the request.
The capture of Chrome where you can check the payload is sent.
The answer is as I said "kind of obvious", but I could not see that, and I am sure some other devs will probably fall on this.
After searching like crazy and asking everyone, I tried sending the request by using Postman app, yup the best thing I know to test apis.
Dont forgue to add the xdebug cookie to be able to debug your PHP Endpoint.
There I found the first clue «the obvious part», I was not sending data as a form-data, Axios and other libraries, send the data as a raw (application/json) payload.
This means that Yii2 will no be able to find the data inside the post request, yes its there but Yii2 magic will not work, neither you will find this data inside $GLOBALS or in $_POST.
So reading the Yii2 documentation I found that inside request I can use a function that will help me recovering the Raw data, so to do this use the following line:
$raw_data = Yii::$app->request->getRawBody();
Now, that data gets to you as a simple, raw json string, so use the power of PHP to parse it to an object.
$object= json_decode($raw_data );
And finally use the data inside by calling the properties you look for, sent on the pay load:
Json Payload:
{
"msg":"This is my payload",
"id":"11"
}
To use it:
echo $object->{'msg'}; // prints: This is my payload
So that's the way to handle that, now I would like some other points of view to see if there's a better way or cleaner way to do this. Hope it helps.
I have created some code to make calls to an external API (that I did not create). However, it has been described as 'Service-centric', while REST APIs are 'Resource-centric'.
What exactly needs changed to turn this into a service based call? I don't understand what the difference is. I understand I need to use HTTP verbs but I thought I was doing that already with cURL. Is this possible with cURL?
The API I have been passed contains a bunch of resource URLs as an example;
GET http://api.privateservice.com/Person?ID=123
POST http://api.privateservice.com/Person/SaveDetails/123
Think of resources as nouns, ie objects or records in your database. Think of actions as verbs, ie function calls.
The first example is indeed resource-centric. It's GETting a resource of type Person identified by 123.
The second example is not resource-centric because it's essentially a function call. REST and HTTP already establish conventions for saving a resource. In this case you simply need to PUT to the resource's URL, ie the same URL you retrieved with GET.
So upload the JSON (or whatever format) using:
PUT http://api.privateservice.com/Person?ID=123
If you are only passing in a few attributes, not the whole resource, there's another standard for that, PATCH:
PATCH http://api.privateservice.com/Person?ID=123
BTW It's a bit cleaner to use http://api.privateservice.com/people/123 as the URL.
I am writing a PHP application that has a few forms. Often when a form is submitted I want to 1) update the database, then 2) forward to an URL. Usually the URL is dynamically constructed using parameters that were supplied as part of the last request.
My question is this: if a parameter is supplied in a request, solely for the purpose of constructing the 'forward to' url, should it be passed in the $_POST array or the $_GET array?
At the moment any parameters that need to be persisted as passed in $_POST, and those used solely for redirection are passed in $_GET.
This response, https://stackoverflow.com/a/1993498/356282, suggests that I should choose one method or the other...
I don't know the logic of your application but consider if your redirection is about users accessing some resources and it's about a authorizing users it's better parameters related to forward be in post global var.
here's good tutorial on POST and GET.
http://blog.teamtreehouse.com/the-definitive-guide-to-get-vs-post
and also here's a question I think which can help you.
When should I use GET or POST method? What's the difference between them?
I have a web application which I wrote in PHP. Each of my forms do an HTTP POST to a PHP file which processes the data and returns a result.
Now I want to use RAD Studio's Delphi XE4 to create an application which can be used on phones to perform basic functions on the site.
For example...
I have a function in my PHP file called F.
F Does some calculations with parameters passed using the $_REQUEST[''] directive.
So my question is: is there a way that I can use Delphi to post to my website and return the result.
I've searched for similar requests but no-one seems to have done this before.
I would even use a JavaScript file if someone can tell me how I can incorporate it?
I know jQuery has a $.ajax method, is there maybe a way to implement that?
I can assure you that you're not the first person to do an HTTP request via Delphi :)
You state that you're fetching the request data via $_REQUEST, so you'll get both POST and GET data, so perhaps these links might be of interest:
What's the simplest way to call Http GET url using Delphi?
What’s the simplest way to call Http POST url using Delphi?
I been learning php and ajax from w3schools but I have come across a simply question for which I cant find an answer to.
To request something from a php file I use a xmlhttpRequest object and specify the url (of that php file). Does this mean one php file for one request only? Let's say on a webpage there are a user log-in box and a comment box, I would need two php files to take the requests? I always thought the server side will have one main file that handle all the requests, each request from client will have a ID to specify what the request is and send back the necessary data to client. So what is the right?
I read a lot of material online, but everything is just basic example with just one request and one response.
You can use the same file for multiple requests. You can supply parameters along with the AJAX request, either by including them in the URL after ? (they'll be available in $_GET and $_REQUEST) or by using the POST method and sending them as form data (they'll be available in $_POST and $_REQUEST). You can use the Javascript FormData API to encode this properly; see the documentation here. Using the jQuery library can simplify all of this.
One of the parameters can then be a command or operation code, and the script can take different actions based on this.