In this session, you will write a web service which updates the database by adding new data, namely a review for a given song.
So far we have only looked at GET requests, however to create new data we need to use POST. How do we handle POST data in Slim? Firstly, we set up a 'post' rather than a 'get' route, and then we use the request's getParsedBody() method to extract the POST data. For example, this sets up a POST route /student/create:
// Include all the Slim dependencies. Composer creates an 'autoload.php' inside // the 'vendor' folder which will, in turn, include all required dependencies. require 'vendor/autoload.php'; // Create a new Slim App object. $app = new \Slim\App; $app->post('/student/create', function ($req, $res, array $args) { $post = $req->getParsedBody(); $res->getBody()->write("Student details : Name: ". $post['name']. " Username: ". $post['username']. " Course: " . $post['course']); return $res; }); $app->run();
In this example, we could set up a form with an action of "/student/create" and fields with names of name, username and course, and the Slim application would read, and display, this data.
This exercise will involve creating a review for a song, so we will use POST, as per the principles of REST.
So far we have seen how to connect to a web service using cURL to send a GET request, however what about a POST request?
Rather than adding the data to the end of the URL using a query string, you set the CURLOPT_POSTFIELDS option with the data you want to POST. See the example below, in which $dataToPost is an associative array describing a new flight. It is sent to the REST URL http://www.solentairways.com/flight/create:
$connection = curl_init(); curl_setopt($connection, CURLOPT_URL, "http://www.solentairways.com/flight/create"); $dataToPost = ["origin" => "London" , "dep" => "0900", "arr" => "1600", "destination" => "New York", "aircraft" => "Boeing 777", "flightnumber" => "SA123"]; curl_setopt($connection,CURLOPT_RETURNTRANSFER,1); curl_setopt($connection,CURLOPT_POSTFIELDS,$dataToPost); $response = curl_exec($connection); curl_close($connection);would send the specified data describing a new flight to the /flight/create route. /flight/create could then read the various fields with with $req->getParsedBody(). For example:
$app->post("/flight/create", function($req, $res, array $args) { $postData = $req->getParsedBody(); // $postData["origin"] is the origin, $postData["dep"] is the departure time, etc. });
Return to your "fan" website from last time. On the "fan" website, allow the user the ability to review each song from HT-Tracks. This should be done by writing a new page on your fan site which connects to the HT-Tracks download web service, which you wrote above.
Do this as follows:
echo "<form method='post' action='clientreview.php'>"; echo "<input name='review' />"; echo "<input name='id' type='hidden' value='(the ID from your JSON - fill this in!)' />"; echo "<input type='submit' value='review' />"; echo "</form>";Or, alternatively, for each song on your fan page, write a link to a separate page which should contain a review form containing a review field, a hidden field for the ID, and an action of clientreview.php.
In the last question of the exercise, you were asked to send back an HTTP status code to the client if the review was blank. However, we have not yet looked at how you can test for an HTTP code sent back from a remote script. Luckily, if you are using cURL it's fairly straightforward. Once you have done your cURL request you query the CURLINFO_HTTP_CODE property to obtain the HTTP code returned by the web service, for example:
$connection = curl_init(); curl_setopt($connection, CURLOPT_URL, "http://remoteserver/script.php"); curl_setopt($connection,CURLOPT_RETURNTRANSFER,1); curl_setopt($connection,CURLOPT_HEADER,0); $response = curl_exec($connection); $httpCode = curl_getinfo($connection,CURLINFO_HTTP_CODE); echo "The script returned the HTTP status code: $httpCode <br />"; curl_close($connection);
Note how the line:
curl_setopt($connection,CURLOPT_HEADER, 0);is still present. We can get the status code without having to include the full HTTP header in the output.