Home » Php » curl – Accessing Yelp API in PHP

curl – Accessing Yelp API in PHP

Posted by: admin July 12, 2020 Leave a comment

Questions:

I’m getting started with Yelp API v3 (Fusion). I have created an app, got Client ID and Client Secret.

I understand that I need to get a token from Yelp API and then using business ID retrieve json data.

I’ve found the following PHP code:

$postData = "grant_type=client_credentials&".
            "client_id=YOURCLIENTID&".
            "client_secret=SECRET";
$ch = curl_init();

//set the url
curl_setopt($ch,CURLOPT_URL, "https://api.yelp.com/oauth2/token");
//tell curl we are doing a post
curl_setopt($ch,CURLOPT_POST, TRUE);
//set post fields
curl_setopt($ch,CURLOPT_POSTFIELDS, $postData);
//tell curl we want the returned data
curl_setopt($ch,CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);

//close connection
curl_close($ch);

if($result){
   $data = json_decode($result);
   echo "Token: ".$data->access_token;
}

I’ve entered my ID and SECRET but got a blank page. What else am I missing?

How to&Answers:

there’s 3 versions of the API, you don’t specify which version you’re targeting, V1, V2, or Yelp Fusion (V3?) , but seeing as V2 is in the process of being retired (for example, they wont allow new programmers to sign up for an access token for V2), i guess you mean Fusion.

according to the docs, it all starts by making a request to https://api.yelp.com/oauth2/token
, using your client_id and client_secret (that you get when registering a new app), and a hardcoded grant_type = client_credentials – and your code does do that, but it doesn’t properly url encode the client_id and client_secret, that may be why you’re getting a blank page (and that in itself means that you’re not debugging using CURLOPT_VERBOSE – when debugging curl requests, always use CURLOPT_VERBOSE – we dont know if it connected and got a http 204 OK No Content, or a 500 Internal Server Error, or if your connection was outright blocked, but CURLOPT_VERBOSE would tell you.), when you get the access_token from the oauth2/token url, it comes encoded in JSON format, use json_decode to decode it.

when you got that token, for further API calls, set the http header Authorization: Bearer TOKEN for autentication.

here’s my code, playing around with the API, logging in (getting an authorization_token), then getting business information on dentistry-for-kids-and-adults-canyon-country. unfortunately, the business search API seems broken, as it only returns 500 Internal Server Errors for everything i try. also i’m using the hhb_curl from https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php as a convenience wrapper around curl (takes care of CURLOPT_VERBOSE and giving it a file to put debug info in, setting CURLOPT_ENCODING for faster transfers, checking the return value of each curl_setopt, throwing an exception if any of the curl options could not be set and telling me exactly which option failed to be set, etc) – and if you want to testrun this code, make sure to replace client_id and client_secret, as the ones i posted here are fake (but have the same length and general structure, generated by this code https://gist.github.com/divinity76/c43e8ceb803969def0c0369b8ec6de4b )

<?php
declare(strict_types = 1);
// hhb_.inc.php from https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php
require_once ('hhb_.inc.php');
$hc = new hhb_curl ( 'https://api.yelp.com/oauth2/token', true );
$hc->setopt_array ( array (
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query ( array (
                'grant_type' => 'client_credentials', // << hardcoded
                'client_id' => 'Q3sE0uuprHlZx3UbjPlnXX',
                'client_secret' => 'Q3sE0uuprHlZx3UbjPlnXXQ3sE0uuprHlZx3UbjPlnXXQ3sE0uuprHlZx3UbjPln' 
        ) ) 
) );
$hc->exec ();
hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () );
$json = $hc->getResponseBody ();
$parsed = json_decode ( $json, true );
if (! isset ( $parsed ['access_token'] )) {
    throw new \RuntimeException ( 'failed to get access token!' );
}
$access_token = $parsed ['access_token'];
$hc->setopt_array ( array (
        CURLOPT_HTTPGET => true,
        CURLOPT_URL => 'https://api.yelp.com/v3/businesses/' . urlencode ( 'dentistry-for-kids-and-adults-canyon-country' ),
        CURLOPT_HTTPHEADER => array (
                'Authorization: Bearer ' . $access_token 
        ) 
) );
$hc->exec ();
hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () );
$json = $hc->getResponseBody ();
$parsed = json_decode ( $json, true );
hhb_var_dump ( $parsed );

/*
 * the business search api seems to be severly broken, giving me 500 Internal Server Errors all the time...
 * $hc->setopt_array ( array (
 * CURLOPT_POST => true,
 * CURLOPT_POSTFIELDS => http_build_query ( array (
 * //'location' => "375 Valencia St, San Francisco"
 * //somewhere in San Francisco.
 * 'latitude'=>'37.7670169511878',
 * 'longitude'=>'-122.42184275'
 *
 * ) ),
 * CURLOPT_URL => 'https://api.yelp.com/v3/businesses/search',
 * CURLOPT_HTTPHEADER => array (
 * 'Authorization: Bearer ' . $access_token
 * )
 * ) );
 * $hc->exec ();
 * hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () );
 * $json = $hc->getResponseBody ();
 * $parsed = json_decode ( $json, true );
 * hhb_var_dump ( $parsed );
 */

also be aware that the 2nd parameter for hhb_curl::__construct is called $insecureAndComfortableByDefault – which disables SSL certificate validation (), and enables compressed transfers (as for why that may be a problem, google “ssl crime vulnerability”), and is disabled by default (in an attempt to be “secure by default”), but i generally keep it on for ease of development

Answer:

Not sure why but I was getting different errors about hhb_.inc.php so I ended-up cobbling something together myself. It seems to work, in case there are other novices struggling out there. Just update client_id and client_secret with your own values. You get those when you register your app with Yelp as developer.

$postData = "grant_type=client_credentials&".
    "client_id=MyClientIDl94gqHAg&".
    "client_secret=SomEcoDehIW09e6BGuBi4NlJ43HnnHl4S7W5eoXUkB";


// GET TOKEN
$curl = curl_init();

//set the url
curl_setopt($curl,CURLOPT_URL, "https://api.yelp.com/oauth2/token");
//tell curl we are doing a post
curl_setopt($curl,CURLOPT_POST, TRUE);
//set post fields
curl_setopt($curl,CURLOPT_POSTFIELDS, $postData);
//tell curl we want the returned data
curl_setopt($curl,CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($curl);

if($result){
    $data = json_decode($result);
}

// GET RESTAURANT INFO
curl_setopt_array($curl, array(
    CURLOPT_URL => "https://api.yelp.com/v3/businesses/north-india-restaurant-san-francisco",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => array(
        "authorization: Bearer ".$data->access_token
    ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

//close connection
curl_close($curl);

if ($err) {
    echo "cURL Error #:" . $err;
} else {
    echo $response;
}