PHP Call REST API

Get JSON response from REST API in PHP using cURL and using the json to perform serverside rendering.

Using Curl for calling APIs in PHP

PHP doesn't come built-in with an API client. We must install the php-curl extension. PHP has a library for curl. We need to install it before we can use it in PHP.

sudo apt-get install php5-curl
sudo service apache2 restart

After installing restart the apache server for curl to take effect.

Calling a JSON-based REST API in PHP

The below example is a simple GET request which returns a json response. The json response can be parsed into an object using json_decode for the program to use further.

$url = 'https://api.example.com/v1.0/details/customer';
  
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$response = json_decode($response);
curl_close($ch);

The CURLOPT_RETURNTRANSFER option is set to true to return the transfer as a string of the return value of curl_exec() instead of outputting it directly.

Before we head to the POST request, let us see how we can loop over the response object and perform server-side rendering.

$blogList = json_decode($response);
curl_close($ch);

foreach ($blogList->pages as $blog) {
    echo('<a href="/blog/'.$blog->link.'">'.$blog->title.'</a>');
}

POST request in PHP

POST requests are different from GET requests. In POST request, have a body so we need to send data using CURLOPT_POSTFIELDS. In the below example, we are sending a POST request using the CURLOPT_POST => TRUE option.

$ch = curl_init('https://api.example.com/v1.0/details/customer');
curl_setopt_array($ch, array(
  CURLOPT_POST => TRUE,
  CURLOPT_RETURNTRANSFER => TRUE,
  CURLOPT_HTTPHEADER => array(
      'Authorization: apikey '.$authToken,
      'Content-Type: application/json'
  ),
  CURLOPT_POSTFIELDS => json_encode($postData)
));
$response = curl_exec($ch);

Setting headers using CURLOPT_HTTPHEADER

If you have to set no headers, simply add the below line.

curl_setopt($ch, CURLOPT_HEADER, 0);

But if you wish to add headers, put them into an array and use the CURLOPT_HEADER option

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      'Authorization: apikey '.$authToken,
      'Content-Type: application/json'
));

Utility function to call APIs in PHP

Now we create a generic function that can send any method GET, POST, PUT, etc. request in PHP. This is useful in case we are calling APIs frequently in our code. Having a utility function saves us lines of code also we can improve this function in a single place.

function rest_call($method, $url, $data = false, $contentType= false, $token = false)
{
    $curl = curl_init();

    if($token){ //Add Bearer Token header in the request
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Authorization: '.$token
        ));
    }

    switch ($method)
    {
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);
            if ($data){
                if($contentType){
                    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
                        'Content-Type: '.$contentType
                    ));
                }
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_PUT, 1);
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
}

Sending URL Encoded FORM POST Request

$postData = array("name"=>"John Doe", "from"=>"New York");
$string = http_build_query($postData);
$url = 'https://api.example.com/v1.0/user';
$jsonResponse = rest_call("POST",$url, $string, 'application/x-www-form-urlencoded');
$response = json_decode($jsonResponse);

Sending JSON in PHP POST Request

When sending the request as JSON data, the Content-Type header needs to be set as application/json. Store the data in a PHP array and use the json_encode function to convert it into JSON String to be passed in the request body.


$postData = array("name"=>"John Doe", "from"=>"New York");
$jsonData = json_encode($postData);
// Send the request
$url = 'https://api.example.com/v1.0/user';
$jsonResponse = rest_call('POST',$url, $jsonData,'appplication/json');

//Decode JSON back to PHP object
$response = json_decode($jsonResponse);

The JSON returned in the response is converted back to a PHP object, using json_decode. The below example shows how to use JSON returned in the response.

Server-side rendering with JSON in PHP

So once we call our REST API, we want to use the JSON on the server side to render the HTML.

$covidJsonResponse = rest_call("GET","https://api.metamug.com/covid/v1.0/india");
$covidIndiaObject = json_decode($covidJsonResponse);
$lastCovidUpdateInfo = end($covidIndiaObject->historical_count);

As you can see the json_decode method gives us a PHP object, which will help in server-side rendering. If this REST API calls were made from the browser, we would require dom-manipulation to update a div with the JSON values.

<div class="card col-md-4">
  <div class="card-body">
    <h3><span class="badge badge-success" id="cured_count">
            <?php echo $lastCovidUpdateInfo->total_cured_count; ?>
        </span>
    </h3>
  </div>
</div>

After the DOM is rendered on the client side, we are required to change using javascript. In this case, we can have the same ease of accessing the json object and its attributes without the DOM manipulation.

Passing the JSON to Javascript from PHP

There are cases we would like to send this JSON down to the browser like charting and for the user of js libraries that php can't handle. We can make the JSON we retrieved using our REST call in PHP to the javascript. During the initial page load, this JSON will be passed in the DOM. Client-side rendering is faster as it can avoid the HTTP call to fetch the JSON.

<script>
    var covidJsonResponse = <?php echo $covidJsonResponse ?>;
</script>

Heavier payload is always better than more HTTP calls