0
\$\begingroup\$
    $spotify_track = '1HbcclMpw0q2WDWpdGCKdS';
    $client_id = '[my_id]'; 
    $client_secret = '[my_secret]'; 

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL,            'https://accounts.spotify.com/api/token' );
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt($curl, CURLOPT_POST,           1 );
    curl_setopt($curl, CURLOPT_POSTFIELDS,     'grant_type=client_credentials' ); 
    curl_setopt($curl, CURLOPT_HTTPHEADER,     array('Authorization: Basic '.base64_encode($client_id.':'.$client_secret))); 

    $response = curl_exec($curl);
    $token = json_decode($response)->access_token;
    $err = curl_error($curl);
    curl_close($curl);

    if ($err) {
      echo "cURL Error #:" . $err;
      curl_close($curl);
    } else {
          $curl = curl_init();
          curl_setopt_array($curl, array(
          CURLOPT_URL => "https://api.spotify.com/v1/audio-features/".$spotify_track,
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_FOLLOWLOCATION => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => "GET",
          CURLOPT_HTTPHEADER => array(
            "Content-Type: application/json",
            "Authorization: Bearer ".$token,
          ),
        ));
          $track_info = curl_exec($curl);
          var_dump($track_info);
          curl_close($curl);
    }

I've modified the code suggested on stackoverflow and came up with my own solution. I successfully fetch the song information. However, I wonder if this is the proper way in handling API using curl in php. I also noticed the page reloads a little bit slower compared to without the code aforementioned.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

There's not much you can do wrong here. It works. I don't want to go into details of how to handle Spotify's API, but I would like to comment on your code.

One thing I noticed is that, if there's an error, you call curl_close() twice. That looks like a bug.

You're using curl two times, and in quite a different way. The first time you set individual options with curl_setopt(), the second time you combine all options and call curl_setopt_array(). Your code would be more consistent if you used the same method both times.

Better still, why not make a simple function to do the curl call for you? Something like this:

function callSpotifyApi($options) 
{
    $curl  = curl_init();
    curl_setopt_array($curl, $options); 
    $json  = curl_exec($curl);
    $error = curl_error($curl);
    curl_close($curl);
    if ($error) {
        return ['error'   => TRUE,
                'message' => $error];
    }
    $data  = json_decode($json);
    if (is_null($data)) {
        return ['error'   => TRUE,
                'message' => json_last_error_msg()];
    }
    return $data; 
}

This function combines all the things that are common between the two curl calls, and therefore saves you writing code twice, and the reader reading it twice. This function also checks if the returned json code was valid and tells you what was wrong. You would normally use json_last_error() to detect json errors, but if a Spotify call returns null then there's surely an error.

Given the above function, the first curl call would now become:

$headers  = ['Authorization: Basic '.base64_encode($client_id.':'.$client_secret)];
$url      = 'https://accounts.spotify.com/api/token';
$options  = [CURLOPT_URL            => $url,
             CURLOPT_RETURNTRANSFER => TRUE,
             CURLOPT_POST           => TRUE,
             CURLOPT_POSTFIELDS     => 'grant_type=client_credentials',
             CURLOPT_HTTPHEADER     => $headers];
$credentials = callSpotifyApi($options); 
$token = $credentials->access_token;

I haven't tested this code, so there might be errors. The second call will now be very similar:

$headers  = ['Content-Type: application/json',
             'Authorization: Bearer '.$token];
$url      = 'https://api.spotify.com/v1/audio-features/'.$spotify_track;
$options  = [CURLOPT_URL            => $url,
             CURLOPT_RETURNTRANSFER => TRUE,
             CURLOPT_FOLLOWLOCATION => TRUE,
             CURLOPT_ENCODING       => '',
             CURLOPT_MAXREDIRS      => 10,
             CURLOPT_TIMEOUT        => 30,
             CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
             CURLOPT_CUSTOMREQUEST  => 'GET',
             CURLOPT_HTTPHEADER     => $headers];
$features = callSpotifyApi($options); 
var_dump($features);

Writing calls to Spotify consistently this way makes it easier to read the code, and find and correct bugs.

I didn't really review how you use the curl options, or whether this is the best way to use the Spotify API. Others may have more experience with this.

\$\endgroup\$
6
  • \$\begingroup\$ Thanks for that knowledge, sir. I'll give it a try \$\endgroup\$
    – enrique
    Jan 6, 2021 at 1:54
  • \$\begingroup\$ I modified it a little bit and surprisingly it's much better compared to what I did before. WOW! Thanks again. \$\endgroup\$
    – enrique
    Jan 6, 2021 at 2:18
  • \$\begingroup\$ Why did you suggest the change from if ($err) to yhe more verbose if ($error != '')? Why are you not using curly braces for condition blocks? Please recommend PSR-12 compliance in all php reviews. php-fig.org/psr/psr-12/#5-control-structures and spacing when concatenating and newlines in array declarations. \$\endgroup\$ Jan 6, 2021 at 3:46
  • \$\begingroup\$ @mickmackusa I adopted your first two suggestions. \$\endgroup\$ Jan 6, 2021 at 9:30
  • \$\begingroup\$ is_null($json) or is_null($data)? \$\endgroup\$ Jan 6, 2021 at 9:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.