欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

简洁的PHP QQ Oauth 2.0 SDK类,基于EaglePHP框架封装整理

程序员文章站 2022-06-16 19:24:17
...
此类可以用来做什么?

QQ用户oauth验证登陆

获取用户信息

添加分享

获取相册列表

创建相册

上传相片

发表日志

发表说说

发表微博

检查是否是认证空间的粉丝

发图片消息到微博

获取微博用户信息

获取用户的听众列表

获取用户的收听列表

收听腾讯微博上的用户

获取财付通用户的收货地址
  1. /**
  2. *
  3. * QQ开放平台API
  4. * @author maojianlw@139.com
  5. * @since 2013-06-20
  6. * @link http://www.eaglephp.com
  7. *
  8. */
  9. class QQ
  10. {
  11. private $appid = null;
  12. private $appkey = null;
  13. private $callbcak = null;
  14. private $APIMap = array();
  15. private $keysArr = array();
  16. const VERSION = '2.0';
  17. const AUTH_CODE_URL = 'https://graph.qq.com/oauth2.0/authorize';
  18. const ACCESS_TOKEN_URL = 'https://graph.qq.com/oauth2.0/token';
  19. const OPENID_URL = 'https://graph.qq.com/oauth2.0/me';
  20. const SCOPE = 'get_user_info,add_share,list_album,add_album,upload_pic,add_topic,add_one_blog,add_weibo,check_page_fans,add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,get_idolist,add_idol,del_idol,get_tenpay_addr';
  21. public function __construct($appid, $appkey, $callbcak)
  22. {
  23. $this->appid = $appid;
  24. $this->appkey = $appkey;
  25. $this->callbcak = $callbcak;
  26. }
  27. /**
  28. * 登录
  29. */
  30. public function login()
  31. {
  32. $state = md5(uniqid(rand(), true)); // 生成唯一随机串防CSRF攻击
  33. Session::set('state', $state);
  34. $keysArr = array(
  35. 'response_type' => 'code',
  36. 'client_id' => $this->appid,
  37. 'redirect_uri' => $this->callbcak,
  38. 'scope' => self::SCOPE,
  39. 'state' => $state
  40. );
  41. header('Location:'.self::AUTH_CODE_URL.'?'.http_build_query($keysArr));
  42. }
  43. /**
  44. *
  45. * 回调函数返回access_token和open_id
  46. *
  47. */
  48. public function callback()
  49. {
  50. $state = Session::get('state');
  51. // 验证state防止CSRF攻击
  52. if(HttpRequest::getGet('state') != $state) throw_exception('The state does not match. You may be a victim of CSRF.');
  53. Session::set('state', null);
  54. $keysArr = array(
  55. 'grant_type' => 'authorization_code',
  56. 'client_id' => $this->appid,
  57. 'redirect_uri' => $this->callbcak,
  58. 'client_secret' => $this->appkey,
  59. 'code' => HttpRequest::getGet('code')
  60. );
  61. $response = curlRequest(self::ACCESS_TOKEN_URL.'?'.http_build_query($keysArr));
  62. if(strpos($response, 'callback') !== false)
  63. {
  64. $lpos = strpos($response, '(');
  65. $rpos = strrpos($response, ')');
  66. $response = substr($response, $lpos + 1, $rpos - $lpos -1);
  67. $msg = json_decode($response);
  68. if(isset($msg->error)) throw_exception($msg->error.' '.$msg->error_description);
  69. }
  70. $params = array();
  71. parse_str($response, $params);
  72. Session::set('access_token', $params['access_token']);
  73. // 根据token请求获取openid
  74. $response = curlRequest(self::OPENID_URL.'?access_token='.$params['access_token']);
  75. if(strpos($response, 'callback') !== false){
  76. $lpos = strpos($response, '(');
  77. $rpos = strrpos($response, ')');
  78. $response = substr($response, $lpos + 1, $rpos - $lpos -1);
  79. }
  80. $user = json_decode($response);
  81. if(isset($user->error)) throw_exception($msg->error.' '.$msg->error_description);
  82. Session::set('open_id', $user->openid);
  83. return array('access_token' => $params['access_token'], 'open_id' => $user->openid);
  84. }
  85. /**
  86. *
  87. * 初始化数据
  88. *
  89. */
  90. protected function _initAPI()
  91. {
  92. $this->keysArr = array(
  93. 'oauth_consumer_key' => (int)$this->appid,
  94. 'access_token' => Session::get('access_token'),
  95. 'openid' => Session::get('open_id')
  96. );
  97. /**
  98. *
  99. * 初始化APIMap
  100. * 加#表示非必须,无则不传入url(url中不会出现该参数), 'key' => 'val' 表示key如果没有定义则使用默认值val
  101. * 规则 array( baseUrl, argListArr, method)
  102. *
  103. * @var array
  104. */
  105. $this->APIMap = array(
  106. /* qzone */
  107. 'add_blog' => array(
  108. 'https://graph.qq.com/blog/add_one_blog',
  109. array('title', 'format' => 'json', 'content' => null),
  110. 'POST'
  111. ),
  112. 'add_topic' => array(
  113. 'https://graph.qq.com/shuoshuo/add_topic',
  114. array('richtype','richval','con','#lbs_nm','#lbs_x','#lbs_y','format' => 'json', '#third_source'),
  115. 'POST'
  116. ),
  117. 'get_user_info' => array(
  118. 'https://graph.qq.com/user/get_user_info',
  119. array('format' => 'json'),
  120. 'GET'
  121. ),
  122. 'add_one_blog' => array(
  123. 'https://graph.qq.com/blog/add_one_blog',
  124. array('title', 'content', 'format' => 'json'),
  125. 'GET'
  126. ),
  127. 'add_album' => array(
  128. 'https://graph.qq.com/photo/add_album',
  129. array('albumname', '#albumdesc', '#priv', 'format' => 'json'),
  130. 'POST'
  131. ),
  132. 'upload_pic' => array(
  133. 'https://graph.qq.com/photo/upload_pic',
  134. array('picture', '#photodesc', '#title', '#albumid', '#mobile', '#x', '#y', '#needfeed', '#successnum', '#picnum', 'format' => 'json'),
  135. 'POST'
  136. ),
  137. 'list_album' => array(
  138. 'https://graph.qq.com/photo/list_album',
  139. array('format' => 'json')
  140. ),
  141. 'add_share' => array(
  142. 'https://graph.qq.com/share/add_share',
  143. array('title', 'url', '#comment','#summary','#images','format' => 'json','#type','#playurl','#nswb','site','fromurl'),
  144. 'POST'
  145. ),
  146. 'check_page_fans' => array(
  147. 'https://graph.qq.com/user/check_page_fans',
  148. array('page_id' => '314416946','format' => 'json')
  149. ),
  150. /* wblog */
  151. 'add_t' => array(
  152. 'https://graph.qq.com/t/add_t',
  153. array('format' => 'json', 'content','#clientip','#longitude','#compatibleflag'),
  154. 'POST'
  155. ),
  156. 'add_pic_t' => array(
  157. 'https://graph.qq.com/t/add_pic_t',
  158. array('content', 'pic', 'format' => 'json', '#clientip', '#longitude', '#latitude', '#syncflag', '#compatiblefalg'),
  159. 'POST'
  160. ),
  161. 'del_t' => array(
  162. 'https://graph.qq.com/t/del_t',
  163. array('id', 'format' => 'json'),
  164. 'POST'
  165. ),
  166. 'get_repost_list' => array(
  167. 'https://graph.qq.com/t/get_repost_list',
  168. array('flag', 'rootid', 'pageflag', 'pagetime', 'reqnum', 'twitterid', 'format' => 'json')
  169. ),
  170. 'get_info' => array(
  171. 'https://graph.qq.com/user/get_info',
  172. array('format' => 'json')
  173. ),
  174. 'get_other_info' => array(
  175. 'https://graph.qq.com/user/get_other_info',
  176. array('format' => 'json', '#name', 'fopenid')
  177. ),
  178. 'get_fanslist' => array(
  179. 'https://graph.qq.com/relation/get_fanslist',
  180. array('format' => 'json', 'reqnum', 'startindex', '#mode', '#install', '#sex')
  181. ),
  182. 'get_idollist' => array(
  183. 'https://graph.qq.com/relation/get_idollist',
  184. array('format' => 'json', 'reqnum', 'startindex', '#mode', '#install')
  185. ),
  186. 'add_idol' => array(
  187. 'https://graph.qq.com/relation/add_idol',
  188. array('format' => 'json', '#name-1', '#fopenids-1'),
  189. 'POST'
  190. ),
  191. 'del_idol' => array(
  192. 'https://graph.qq.com/relation/del_idol',
  193. array('format' => 'json', '#name-1', '#fopenid-1'),
  194. 'POST'
  195. ),
  196. /* pay */
  197. 'get_tenpay_addr' => array(
  198. 'https://graph.qq.com/cft_info/get_tenpay_addr',
  199. array('ver' => 1,'limit' => 5,'offset' => 0,'format' => 'json')
  200. )
  201. );
  202. }
  203. protected function _applyAPI($baseUrl, $argsList, $method)
  204. {
  205. $params = HttpRequest::getPost();
  206. $optionArgList = '';
  207. $keysArr = $this->keysArr;
  208. $pre = '#';
  209. foreach ($argsList as $k=>$v)
  210. {
  211. if(!is_string($k))
  212. {
  213. $k = $v;
  214. if(strpos($v, $pre) === 0)
  215. {
  216. $v = $pre;
  217. $k = substr($k, 1);
  218. if(preg_match('/-(\d$)/', $k, $matchs))
  219. {
  220. $k = str_replace($matchs[0], '', $k);
  221. $optionArgList[$matchs[1]][] = $k;
  222. }
  223. }
  224. else $v = null;
  225. }
  226. if(!isset($params[$k]) || $params[$k] === '')
  227. {
  228. if($v == $pre) continue;
  229. elseif($v) $params[$k] = $v;
  230. else
  231. {
  232. if(isset($_FILES[$k]) && $_FILES[$k]['name']!='')
  233. {
  234. $uploadDir = getUploadAddr().'QQ'.__DS__;
  235. mk_dir($uploadDir);
  236. $uploadObj = new Upload();
  237. $fileInfo = $uploadObj->uploadOne($_FILES[$k], $uploadDir);
  238. $img = $uploadDir.$fileInfo[0]['savename'];
  239. $params[$k] = "@{$img}";
  240. }
  241. else throw_exception("param {$k} not pass value.");
  242. }
  243. }
  244. $keysArr[$k] = $params[$k];
  245. }
  246. // 检查选填参数必填一的情形
  247. $i = 0;
  248. if(isset($optionArgList[1]))
  249. {
  250. foreach ($optionArgList[1] as $k=>$v) if(array_key_exists($v, $keysArr)) $i++;
  251. if(!$i) throw_exception('QQ_api_param_error,['.implode(',', $optionArgList[1]).'] must hava one value.');
  252. }
  253. $baseUrl .= ($method == 'GET') ? '?'.http_build_query($keysArr) : '';
  254. $response = curlRequest($baseUrl, $keysArr, $method);
  255. return json_decode($response, true);
  256. }
  257. public function __call($name, $args)
  258. {
  259. $this->_initAPI();
  260. if(!array_key_exists($name, $this->APIMap)) throw_exception("QQ_api_{$name} not exists.");
  261. //从APIMap获取api相应参数
  262. $baseUrl = $this->APIMap[$name][0];
  263. $argsList = $this->APIMap[$name][1];
  264. $method = isset($this->APIMap[$name][2]) ? $this->APIMap[$name][2] : 'GET';
  265. $responseArr = $this->_applyAPI($baseUrl, $argsList, $method);
  266. //检查返回ret判断api是否成功调用
  267. if($responseArr['ret'] == 0) return $responseArr;
  268. else throw_exception('QQ_API_'.$name.' [ret:'.$responseArr['ret'].'] [errcode:'.$responseArr['errcode'].'] '.$responseArr['msg']);
  269. }
  270. }
复制代码