Making a REST Request

Our Web application will need data, which it gets by making a REST
request to the Yahoo! Image Search Web Service. For those unfamiliar with
Representational State Transfer (REST), which is a style of software
architecture, please see the REST Wikipedia page.

The REST request is made to an endpoint, a URI in our case, where
data can be accessed from an information source called a resource. The
resource can return data from the Yahoo! Web Service in different formats.
We will be working with the default format XML, but please look at the
code examples that use JSON or serialized PHP after you have finished the
tutorial.

PHP offers two primary ways to make REST requests to Yahoo! Web
services. The first way uses the Client URL Library (cURL),
which is a PHP extension, and the second way calls the PHP function
file_get_contents. We will be using cURL in this
tutorial because it offers more control and flexibility when making
requests.

The list below describes the differences in greater detail between
the two methods.

cURL is a PHP extension that is used for making network
requests. It is a popular choice to make HTTP or HTTPS requests
because of the ease of making HTTP POST requests and the large number
of network transport options available. Although cURL offers greater
control and flexibility, it is also more complicated to use.

file_get_contents is the simplest method and
is especially good for very short scripts. Its drawbacks are that it
is difficult to make HTTP POST calls and does not offer the same
degree of control over network transport.

Anatomy of a REST Call

One way to better understand REST calls is to examine the URI. By
dividing the URI into discrete parts, we can see that the REST call will
use HTTP to request the resource to return five data results. In the
example below, we ask the Yahoo! Image Search Web Service (resource) to
return data for five images of water bears.

The variables in the code below are building blocks that
together form the request.

Making REST Request with cURL

Before we make our request, let's set up the php tags and
enable error_reporting for debugging. All the
code that follows in this tutorial should be placed win the php
tags. In production, you should always disable
display_errors to keep end users from seeing
error messages.

Assign the application ID obtained from Yahoo! to a
variable. You will append this variable to URL that is used for
the REST request.

With cURL installed and enabled, we are ready to make our
request. The URI we examined earlier will now be passed to the
function curl_init to begin a session.

Remember how cURL allows for more control over network
transport? This control is mostly due to the function
curl_setopt, which can be used to fine-tune our
request. For example, we would like the response data to include
the HTTP header and the response data. This is done using
curl_setopt to set the options
CURLOPT_RETURNTRANSFER and
CULTOPT_HEADER to true. Setting
CURLOPT_RETURN option to true is particularly
important because the default is false, which sends response data
to the browser and not your program. By setting the option
CURLOPT_HEADER to true, we can check the HTTP
status codes in the HTTP header for errors later.

The options CURL_RETURNTRANSFER and
CULTOPT_HEADER in the code are integer
constants.

The curl_exec function does the work of
making the request. The default return value for
curl_exec is true for success or false for a
failed request, but because we specified
curl_setopt to return the response data,
curl_exec returns the response data from the
resource or false if the request fails. We can now close the curl
session and check for errors.

The cURL session is completed with the functions
curl_exec and curl_close in
the code below.

Error Checking

Before looking at the HTTP status code, we need to verify whether
curl_exec was able to transmit the request to the
Yahoo! Image Search Service. If the request failed, we display an error
message and exit the program. In a real-life application, you might
display a more user-friendly error message and log the error.

A simple if clause can confirm if the request was
successful.

If the response returned from curl_exec was not false, we know
that the request was transmitted to the Yahoo! Image Search Service,
but we still do not know if the request was made. By checking the
HTTP status code, which is included within the HTTP header, we now
check for errors. A simple regular expression can extract the status
code from the HTTP header, and then the status code can be checked
with a switch statement.

The code below uses the function preg_match
to search $response for the given regular
expression and then stores the matches in the array
$status_code. The first match will be the HTTP
status code, which can then be checked.

Troubleshooting

Although setting error_reporting to E_ALL will
allow you to view syntax and runtime fatal errors in a browser, you can
also use php -l to check the syntax of your script or
use php -e to generate more debugging
information.

PHP does not have an internal debugger, but many IDEs come
with debuggers or you can install an external debugger such as
DBG or the
Advanced PHP Debugger (APD).

One common error that will not show up with a debugger or
error reporting is using a single "=" when you are checking
equality.

If all went well, we now have our response data about the
resilient and lovable water bug. The response data, however, still
needs to be extracted from the XML, which brings us to Parsing the Response. If you are still unable to complete this step,
please repeat Making a Request and review the documentation for
cURL.

Exploring (Optional)

Using the PHP function file_get_contents is
even easier than cURL to make REST requests, but you cannot make HTTP
POST calls as easily nor do you have the same fine-grain control over
network transport. For these reasons,
file_get_contents is very good for testing and quick
scripting, but you will want to use cURL for production.

For security reasons, in order for
file_get_contents to access a URI, you will need to
enable fopen wrappers in the PHP configuration file, php.ini. Once
again, look at the output from phpinfo to see if the
local and master values for the directive
allow_url_include are on. If this directive is off,
you will need to either uncomment the line allow_url_open = On or add this line to the file. Now try making the same
request we just did with file_get_contents using this
code sample.