Working with php cURL

If you are developing a web applications in PHP like I sometimes do, chances are that you will have to use php cURL.

This library enables you to connect and communicate to many different types of servers with many different types of protocols. For instance, you could use php curl to talk to your own or some web service API via standard HTTP protocol.

In this article, I have put together a reusable function which makes GET, POST, DELETE and PUT HTTP requests to any API end-point via PHP cURL. But I want to show how to install the library and debug curl requests too.

Installing php cURL library

This is fairly simple if you are running on Linux systems. For Ubuntu, you can install php-curl from the official debian repository using apt-get;
sudo apt-get install php-curl

This will install the default PHP curl library. If you want for specific version of php, don't forget to specify that with php version such as php7.0-curl.

Confirm that indeed you have the library installed via the commandline like

~ ยป php -m | grep curl                                                                                                
curl  

Alternatively you can use the phpinfo() function to check if curl is installed. You see "cURL support enabled" in the output.
php curl enabled

Skip ssl verification

Most APIs these days have https end-points. However, not everyone configures their SSL certificates very well. Or sometimes the SSL certificate for domain expires and the provider forgets to renew it. If that happens cURL is going to return an error.

The temporal solution is turn off SSL verification by setting CURLOPTSSLVERIFYPEER and optionally CURLOPTSSLVERIFYHOST to false.

        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
debugging php cURL

Sometimes when things are not working, you want to see what is being sent to remote server/api via cURL. Thankfully you can call curlgetinfo function and vardump whatever it returns to your browser. If you want see what request headers are being set, then you can set CURLINFOHEADEROUT to true.

Here's a sample output for a GET request to Godaddy API that searches for available domains.

curl_setopt($curl, CURLINFO_HEADER_OUT, true);  
$curl_info = curl_getinfo($curl);

vardump($curlinfo); gives

array (size=27)  
  'url' => string 'https://api.ote-godaddy.com/v1/domains/available?domain=oqui2.com&checkType=FAST&forTransfer=false' (length=98)
  'content_type' => string 'application/json; charset=utf-8' (length=31)
  'http_code' => int 200
  'header_size' => int 729
  'request_size' => int 241
  'filetime' => int -1
  'ssl_verify_result' => int 0
  'redirect_count' => int 0
  'total_time' => float 1.522169
  'namelookup_time' => float 0.060422
  'connect_time' => float 0.376815
  'pretransfer_time' => float 1.043052
  'size_upload' => float 0
  'size_download' => float 103
  'speed_download' => float 67
  'speed_upload' => float 0
  'download_content_length' => float -1
  'upload_content_length' => float -1
  'starttransfer_time' => float 1.522154
  'redirect_time' => float 0
  'redirect_url' => string '' (length=0)
  'primary_ip' => string '173.201.194.82' (length=14)
  'certinfo' => 
    array (size=0)
      empty
  'primary_port' => int 443
  'local_ip' => string '192.168.0.100' (length=13)
  'local_port' => int 32908
  'request_header' => string 'GET /v1/domains/available?domain=oqui2.com&checkType=FAST&forTransfer=false HTTP/1.1
Host: api.ote-godaddy.com  
Accept: */*  
authorization: sso-key XXXXXXXXXXXXXXXXXXXXXX 88  
content-type: application/json

' (length=241)  
Wrapping it up

Now I wanted to write a function that handles all GET/POST/DELETE requests. You can pass http request headers as an associative array and the same goes for post data or get parameters.

Here's my complete working function you can call from anywhere.

/**
     * @param string $method http method to use
     * @param string $url API url end-point
     * @param array $data post data or get parameters 
     * @return response data |boolean false if there's a problem
     */
public function curl_req($method, $url, $headers, $data = false){  
        $curl = curl_init();

        switch ($method){
            case "POST":
                curl_setopt($curl, CURLOPT_POST, 1);

                if ($data)
                    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
                    break;
            case "PUT":
                curl_setopt($curl, CURLOPT_PUT, 1);
                break;
            case "DELETE":
                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
                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);
        curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
        curl_setopt($curl, CURLINFO_HEADER_OUT, true);
        curl_setopt($curl, CURLOPT_VERBOSE, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

        $result = curl_exec($curl);
        $info = curl_getinfo($curl);
        $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);

        if ($httpcode >= 200 && $httpcode < 300):
            return $result;
        else:
            return false;
        endif;
    }

You can learn more about PHP cURL here

David Okwii

David Okwii is a Ugandan-based Technology writer and System's Engineer.

Kampala Uganda http://www.davidokwii.com

Subscribe to oquidave@geek:~ #

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!