2017-06-13 147 views
8

我开始使用Yelp API v3(Fusion)。我创建了一个应用程序,获得了客户端ID和客户端密钥。在PHP中访问Yelp API

我知道我需要从Yelp API获取一个令牌,然后使用业务ID检索json数据。

我发现下面的PHP代码:

$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; 
} 

我输入我的ID和秘密,但得到了一个空白页。我还有什么遗漏?

+0

是'的var_dump($结果)'空? – brianforan

+0

@brianforan它输出:bool(false) – santa

+0

我会先在邮递员上测试它,并确保请求本身正在工作,然后当我确信我会切换到PHP或任何我使用的语言试试看。不幸的是,我没有太多的帮助。 – brianforan

回答

4

有3个版本的API,您没有指定您要定向的版本,V1,V2或Yelp Fusion(V3?),但是看到V2正在退役过程中(例如,他们不会允许新程序员注册V2的访问令牌),我想你的意思是融合。

根据文档,这一切都开始通过向https://api.yelp.com/oauth2/token 的请求,使用您的CLIENT_ID和client_secret(您获得注册一个新的应用程序时),和一个硬编码grant_type = client_credentials - 和你的代码确实做到这一点,但它没有正确的URL编码client_id和client_secret,这可能是为什么你得到一个空白页面(这本身就意味着你不使用CURLOPT_VERBOSE调试 - 调试curl请求时,总是使用CURLOPT_VERBOSE - 我们不会知道它是否连接并获得了http 204 OK No Content或500 Internal Server Error,或者如果您的连接完全被阻止,但CURLOPT_VERBOSE会告诉您。),当您从oauth2/token url获取access_token时,以JSON格式编码,使用json_decode对其进行解码。

当您获得该令牌时,对于进一步的API调用,请设置http标头Authorization: Bearer TOKEN进行验证。

这里是我的代码,玩API,登录(获取授权令牌),然后获取dentistry-for-kids-and-adults-canyon-country的商业信息。不幸的是,商业搜索API似乎打破了,因为它只为我尝试的所有内容返回500个内部服务器错误。我也使用https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php的hhb_curl作为curl的一个便捷包装(照顾CURLOPT_VERBOSE并给它一个文件来放置调试信息,设置CURLOPT_ENCODING以加快传输速度,检查每个curl_setopt的返回值,如果有的话抛出异常的卷曲选项无法设置,并告诉我究竟哪个选项未能设置,等等) - 如果你想测试这个代码,请确保替换client_id和client_secret,因为我在这里发布的是假的(但有相同的长度和总体结构,通过该代码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); 
*/ 

也产生注意,对于hhb_curl所述第二参数:: __构建体被称为$insecureAndComfortableByDefault - 即禁用SSL证书验证(),和ENABL es压缩传输(至于为什么这可能是一个问题,谷歌“SSL犯罪的脆弱性”),并默认情况下被禁用(试图成为“默认安全”),但我通常保持开放以便于开发

+0

很酷,感谢这个例子。我收到一些错误。首先它给了我警告:不支持声明'strict_types'...并且在我将它注释掉之后它说:解析错误:语法错误,意外的':',期待第4行/mypath/hhb_.inc.php中的'{'我的PHP版本5.3.6 – santa

+0

@santa这段代码是用PHP7编写的。在https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php5.php有一个PHP5版本,但今天使用5.3的人都很疯狂。 5.3中有几个已知的漏洞永远不会被修复(我的头顶,unserialize()具有代码执行漏洞,并且通过发送很多小的POST参数,这些php会在100%cpu上挂几个小时来存在DoS漏洞),你真的应该升级到PHP 5.6。向后兼容性问题是微乎其微的(需要替换ereg/eregi函数) – hanshenrik

+0

5.6支持安全性直到2018年12月31日,并且有很多性能改进和语法糖(如短阵列语法[] ,可变参数函数,$ v = function(){};) - 我还没有测试5.3版本的php5版本,只有5.5 – hanshenrik

0

不知道为什么,但我得到有关hhb_.inc.php的不同错误,所以我最终结束了自己的事情。这似乎工作,以防其他新手在那里挣扎。只需使用您自己的值更新client_id和client_secret即可。当你以Yelp身份作为开发者注册你的应用程序时,你会得到这些信息

$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; 
 
}