WeChat.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: kang www.lmlm.cn
  5. * Date: 2015/11/14
  6. * Time: 0:21
  7. */
  8. namespace common\library;
  9. use Yii;
  10. use yii\base\Object;
  11. use yii\web\Cookie;
  12. /**
  13. * 微信处理类
  14. * Class WeChat
  15. * @package common\libary
  16. */
  17. class WeChat extends Object{
  18. public function init(){
  19. // define("TOKEN",Yii::$app->params['wechat']['token']);
  20. }
  21. /**
  22. * 微信接口配置响,应ToKen验证
  23. * @throws Exception
  24. */
  25. public function checkToken(){
  26. //$echoStr = $_GET["echostr"];
  27. $echoStr = Yii::$app->request->get('echostr');
  28. if($this->checkSignature()){
  29. echo $echoStr;
  30. }
  31. }
  32. /**
  33. * 根据access_token. 获取用户信息。
  34. * @param $accessObj
  35. * @return jsonObj
  36. */
  37. public function getUserInfo($accessObj){
  38. // $accessObj = $this->getAccess_token($code);
  39. // var_dump(isset($accessObj));
  40. //https://api.weixin.qq.com/cgi-bin/user/info?access_token=$token&openid=$openid
  41. $url = "https://api.weixin.qq.com/sns/userinfo";
  42. $url .="?access_token=".$accessObj->access_token;
  43. $url .="&openid=".$accessObj->openid;
  44. $url .= "&lang=zh_CN";
  45. $userjson = $this->getHtml($url);
  46. $userObj = json_decode($userjson);
  47. // 设置cookie
  48. // $cookies = Yii::$app->response->cookies;
  49. // $cookies->add(new Cookie(['name'=>'personinfo','value'=>$userObj->openid]));
  50. return $userObj;
  51. }
  52. public function getUserInfo1(){
  53. // $accessObj = $this->getAccess_token($code);
  54. // var_dump(isset($accessObj));
  55. //https://api.weixin.qq.com/cgi-bin/user/info?access_token=$token&openid=$openid
  56. // $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=". Yii::$app->params['wechat']['appID'];
  57. $url ="https://open.weixin.qq.com/connect/qrconnect?appid=". Yii::$app->params['wechat']['appID']."&redirect_uri=http://www.baidu.com&response_type=code&scope=snsapi_login&state=2014#wechat_redirect";
  58. $userjson = $this->getHtml($url);
  59. $userObj = json_decode($userjson);
  60. // 设置cookie
  61. // $cookies = Yii::$app->response->cookies;
  62. // $cookies->add(new Cookie(['name'=>'personinfo','value'=>$userObj->openid]));
  63. return $userObj;
  64. }
  65. /**
  66. * $code获取小程序用户openid,unionid
  67. * @return mixed
  68. */
  69. public function getApiSns($code){
  70. $url = "https://api.weixin.qq.com/sns/jscode2session?appid=".Yii::$app->params['wechatapi']['appid']."&secret=".Yii::$app->params['wechatapi']['secret']."&js_code=".$code."&grant_type=authorization_code";
  71. $userjson = $this->getHtml($url);
  72. $userObj = json_decode($userjson);
  73. return $userObj;
  74. }
  75. /**
  76. * 未关注公众号时,返回关注状态和openid
  77. * 有关注公众号时,返回用户基本信息和关注状态
  78. * @param $token
  79. * @param $openid
  80. * @return mixed
  81. */
  82. public function getUser($token,$openid){
  83. $url = "https://api.weixin.qq.com/cgi-bin/user/info";
  84. $url .="?access_token=".$token;
  85. $url .="&openid=".$openid;
  86. $url .= "&lang=zh_CN";
  87. $userjson = $this->getHtml($url);
  88. $userObj = json_decode($userjson);
  89. return $userObj;
  90. }
  91. /**
  92. * 拉取关注用户列表
  93. * @param $token
  94. * @param $openid
  95. * @return mixed
  96. */
  97. public function Userlist($token,$openid){
  98. $url = 'https://api.weixin.qq.com/cgi-bin/user/get';
  99. $url .="?access_token=".$token;
  100. $url .="&next_openid=".$openid;
  101. $userjson = $this->getHtml($url);
  102. $userObj = json_decode($userjson);
  103. return $userObj;
  104. }
  105. /**
  106. * 验证ToKen
  107. * @return bool
  108. * @throws Exception
  109. */
  110. public function checkSignature()
  111. {
  112. $signature = Yii::$app->request->get("signature");
  113. $timestamp = Yii::$app->request->get("timestamp");
  114. $nonce = Yii::$app->request->get("nonce");
  115. $token = Yii::$app->params['wechat']['token'];
  116. $tmpArr = array($token, $timestamp, $nonce);
  117. sort($tmpArr, SORT_STRING);
  118. $tmpStr = implode( $tmpArr );
  119. $tmpStr = sha1( $tmpStr );
  120. if( $tmpStr == $signature ){
  121. return true;
  122. }else{
  123. return false;
  124. }
  125. }
  126. /**
  127. * 获取授权用户信息 第一步。
  128. * 生成授权URL.
  129. * 用户访问URL,授权后,跳转domain.com?code=CODE&state=100
  130. * 1.CODE可用于获取用户access_token 并获取用户信息
  131. * @param $redurl 跳转URL
  132. * @param bool $scope 授权作用域(默认snsapi_userinfo)
  133. * @param int $state 设置状态(默认100)
  134. * @return string
  135. */
  136. public function markUrl($redurl,$scope=false,$state=100){
  137. $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.Yii::$app->params['wechat']['appID'];
  138. $url .="&redirect_uri=".urlencode($redurl);
  139. $url .= "&response_type=code";
  140. $url .= "&scope=".($scope?'snsapi_base':'snsapi_userinfo');
  141. $url .= "&state=".$state;
  142. $url .= "#wechat_redirect";
  143. return $url;
  144. }
  145. /**
  146. * 获取授权用户信息。第二步,
  147. * 通过code换取网页授权access_token
  148. * @param $code 授权Code
  149. * @return string 返回
  150. */
  151. public function getAccess_token($code){
  152. $getUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".Yii::$app->params['wechat']['appID'];
  153. $getUrl .= "&secret=".Yii::$app->params['wechat']['appsecret'];
  154. $getUrl .= "&code=$code&grant_type=authorization_code";
  155. $resultJson = $this->getHtml($getUrl);
  156. $results = json_decode($resultJson);
  157. if(isset($results->openid) && isset($results->access_token)){
  158. $cookies = Yii::$app->response->cookies;
  159. $cookies->add(new Cookie(['name'=>'acc_openid','value'=>$results->openid]));
  160. // $cookies->add(new Cookie(['name'=>'accesstoken','value'=>$results->access_token]));
  161. // Yii::$app->cache->set('acc_openid',$results->openid,60*60);
  162. Yii::$app->cache->set('access_token',$results->openid,60*60);
  163. }else{
  164. return false;
  165. }
  166. return $results;
  167. }
  168. /**
  169. * 获取授权用户信息 刷新TOKEN
  170. * @param $refresh_token
  171. */
  172. private function refresh_Token($refresh_token){
  173. $url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid='.Yii::$app->params['wechat']['appID'];
  174. $url .= "&grant_type=refresh_token&refresh_token=$refresh_token";
  175. // Yii::$app->cache->set('token',$refresh_token);
  176. // Yii::$app->cache->set('refresh_time',time());
  177. }
  178. /**
  179. * 生成签名 JS 库中使用
  180. * @param $noncestr 随机数
  181. * @param $timestamp 时间戳
  182. * @param $url 当前页面的URL
  183. * @return signature 签名
  184. */
  185. public function getsignature($noncestr,$timestamp,$url){
  186. //$access_token = Yii::$app->request->cookies->getValue('access_token');
  187. $access_token = Yii::$app->cache->get('access_token');
  188. if(empty($access_token)){
  189. $access_token = $this->gzAccess_token();
  190. // $array_data = ['name'=>'access_token','expire'=>time()+3600,'value'=>$access_token];
  191. // Yii::$app->response->cookies->add(new Cookie($array_data));
  192. // Yii::$app->response->cookies->add(new Cookie(['name'=>'jsapi_ticket','value'=>'']));
  193. Yii::$app->cache->set('access_token',$access_token,60*60);
  194. Yii::$app->cache->set('jsapi_ticket',"");
  195. }
  196. $ticket = Yii::$app->request->cookies->getValue('jsapi_ticket');
  197. if(empty($ticket)){
  198. $ticket = $this->getjsapi_ticket($access_token);
  199. // $array_data = ['name'=>'jsapi_ticket','expire'=>time()+3600,'value'=>$ticket];
  200. // Yii::$app->response->cookies->add(new Cookie($array_data));
  201. Yii::$app->cache->set('jsapi_ticket',$ticket,60*60);
  202. }
  203. $string1 = "jsapi_ticket=$ticket&noncestr=$noncestr&timestamp=$timestamp&url=$url";
  204. $signature = sha1($string1);
  205. return $signature;
  206. }
  207. public function getTicket()
  208. {
  209. //$access_token = Yii::$app->request->cookies->getValue('access_token');
  210. $access_token = Yii::$app->cache->get('access_token');
  211. if(empty($access_token)){
  212. $access_token = $this->gzAccess_token();
  213. // $array_data = ['name'=>'access_token','expire'=>time()+3600,'value'=>$access_token];
  214. // Yii::$app->response->cookies->add(new Cookie($array_data));
  215. // Yii::$app->response->cookies->add(new Cookie(['name'=>'jsapi_ticket','value'=>'']));
  216. Yii::$app->cache->set('access_token',$access_token,60*60);
  217. Yii::$app->cache->set('jsapi_ticket',"");
  218. }
  219. //$ticket = Yii::$app->request->cookies->getValue('jsapi_ticket');
  220. $ticket = Yii::$app->cache->get('jsapi_ticket');
  221. if(empty($ticket)){
  222. $ticket = $this->getjsapi_ticket($access_token);
  223. // $array_data = ['name'=>'jsapi_ticket','expire'=>time()+3600,'value'=>$ticket];
  224. // Yii::$app->response->cookies->add(new Cookie($array_data));
  225. Yii::$app->cache->set('jsapi_ticket',$ticket,60*60);
  226. }
  227. return $ticket;
  228. }
  229. public function getsignature2($noncestr,$timestamp,$url){
  230. $access_token = Yii::$app->request->cookies->getValue('access_token');
  231. // Yii::$app->response->send();
  232. if(empty($access_token)){
  233. $access_token = $this->gzAccess_token();
  234. $array_data = ['name'=>'access_token','expire'=>time()+3600,'value'=>$access_token];
  235. Yii::$app->response->cookies->add(new Cookie($array_data));
  236. Yii::$app->response->cookies->add(new Cookie(['name'=>'jsapi_ticket','value'=>'']));
  237. // $ticket = $this->getjsapi_ticket($access_token);
  238. // $array_data = ['name'=>'jsapi_ticket','expire'=>time()+3600,'value'=>$ticket];
  239. // Yii::$app->response->cookies->add(new Cookie($array_data));
  240. }
  241. $ticket = Yii::$app->request->cookies->getValue('jsapi_ticket');
  242. if(empty($ticket)){
  243. $ticket = $this->getjsapi_ticket($access_token);
  244. $array_data = ['name'=>'jsapi_ticket','expire'=>time()+3600,'value'=>$ticket];
  245. Yii::$app->response->cookies->add(new Cookie($array_data));
  246. }
  247. $string1 = "jsapi_ticket=$ticket&noncestr=$noncestr&timestamp=$timestamp&url=$url";
  248. $signature = sha1($string1);
  249. return $signature;
  250. }
  251. /**
  252. * 获取Access_token
  253. * 有获取次数限制
  254. */
  255. public function gzAccess_token(){
  256. $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".Yii::$app->params['wechat']['appID']."&secret=".Yii::$app->params['wechat']['appsecret'];
  257. $resultJson = $this->https_request($url);
  258. $results = json_decode($resultJson);
  259. return $results->access_token;
  260. }
  261. /**
  262. * 获取jsapi_ticket
  263. */
  264. protected function getjsapi_ticket($access_token){
  265. $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$access_token&type=jsapi";
  266. $resultJson = $this->https_request($url);
  267. $results = json_decode($resultJson);
  268. if(!isset($results->ticket)){
  269. Yii::$app->cache->set('access_token','');
  270. return '';
  271. }
  272. return $results->ticket;
  273. }
  274. protected function getHtml($url){
  275. $ch = curl_init();
  276. $timeout = 5;
  277. curl_setopt($ch, CURLOPT_URL, $url);
  278. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  279. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  280. $result = curl_exec($ch);
  281. curl_close($ch);
  282. return $result;
  283. }
  284. /**
  285. * 判断返回值是为正确的。
  286. * @param $result 返回值转json
  287. * @return bool
  288. */
  289. public function isSuccess($result){
  290. if(isset($result->errors)){
  291. return false;
  292. }
  293. return true;
  294. }
  295. /**
  296. *
  297. * 是否微信浏览器
  298. */
  299. public function isWecha()
  300. {
  301. $user_agent = $_SERVER['HTTP_USER_AGENT'];
  302. if (strpos($user_agent, 'MicroMessenger') === false) {
  303. return false;
  304. }
  305. return true;
  306. }
  307. public function https_request($url, $data = NULL) {
  308. $curl = curl_init();
  309. curl_setopt($curl, CURLOPT_URL, $url);
  310. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  311. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  312. if (!empty($data)) {
  313. curl_setopt($curl, CURLOPT_POST, 1);
  314. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  315. }
  316. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  317. $output = curl_exec($curl);
  318. curl_close($curl);
  319. return $output;
  320. }
  321. }