WxBase.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace app\common\library\wechat;
  13. use think\facade\Cache;
  14. use app\common\library\helper;
  15. use app\common\exception\BaseException;
  16. /**
  17. * 微信api基类
  18. * Class wechat
  19. * @package app\library
  20. */
  21. class WxBase
  22. {
  23. protected $appId;
  24. protected $appSecret;
  25. protected $error;
  26. /**
  27. * 构造函数
  28. * WxBase constructor.
  29. * @param $appId
  30. * @param $appSecret
  31. */
  32. public function __construct($appId = null, $appSecret = null)
  33. {
  34. $this->setConfig($appId, $appSecret);
  35. }
  36. protected function setConfig($appId = null, $appSecret = null)
  37. {
  38. !empty($appId) && $this->appId = $appId;
  39. !empty($appSecret) && $this->appSecret = $appSecret;
  40. }
  41. /**
  42. * 获取access_token
  43. * @return mixed
  44. * @throws BaseException
  45. */
  46. protected function getAccessToken()
  47. {
  48. $cacheKey = $this->appId . '@access_token';
  49. if (!Cache::instance()->get($cacheKey)) {
  50. // 请求API获取 access_token
  51. $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}";
  52. $result = $this->get($url);
  53. $response = $this->jsonDecode($result);
  54. if (array_key_exists('errcode', $response)) {
  55. throwError("access_token获取失败,错误信息:{$result}");
  56. }
  57. // 记录日志
  58. log_record([
  59. 'name' => '获取access_token',
  60. 'url' => $url,
  61. 'appId' => $this->appId,
  62. 'result' => $result
  63. ]);
  64. // 写入缓存
  65. Cache::instance()->set($cacheKey, $response['access_token'], 6000);
  66. }
  67. return Cache::instance()->get($cacheKey);
  68. }
  69. /**
  70. * 模拟GET请求 HTTPS的页面
  71. * @param string $url 请求地址
  72. * @param array $data
  73. * @return string $result
  74. */
  75. protected function get(string $url, array $data = [])
  76. {
  77. // 处理query参数
  78. if (!empty($data)) {
  79. $url = $url . '?' . http_build_query($data);
  80. }
  81. $curl = curl_init();
  82. curl_setopt($curl, CURLOPT_URL, $url);
  83. curl_setopt($curl, CURLOPT_HEADER, 0);
  84. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  85. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
  86. $result = curl_exec($curl);
  87. curl_close($curl);
  88. return $result;
  89. }
  90. /**
  91. * 模拟POST请求
  92. * @param $url
  93. * @param array|string $data
  94. * @param bool $useCert
  95. * @param array $sslCert
  96. * @return mixed
  97. */
  98. protected function post(string $url, $data = [], $useCert = false, $sslCert = [])
  99. {
  100. $header = [
  101. 'Content-type: application/json;'
  102. ];
  103. $curl = curl_init();
  104. curl_setopt($curl, CURLOPT_URL, $url);
  105. curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
  106. curl_setopt($curl, CURLOPT_HEADER, false);
  107. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  108. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  109. curl_setopt($curl, CURLOPT_POST, TRUE);
  110. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  111. if ($useCert == true) {
  112. // 设置证书:cert 与 key 分别属于两个.pem文件
  113. curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
  114. curl_setopt($curl, CURLOPT_SSLCERT, $sslCert['certPem']);
  115. curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
  116. curl_setopt($curl, CURLOPT_SSLKEY, $sslCert['keyPem']);
  117. }
  118. $result = curl_exec($curl);
  119. curl_close($curl);
  120. return $result;
  121. }
  122. /**
  123. * 模拟POST请求 [第二种方式, 用于兼容微信api]
  124. * @param $url
  125. * @param array $data
  126. * @return mixed
  127. */
  128. protected function post2($url, $data = [])
  129. {
  130. $header = [
  131. 'Content-Type: application/x-www-form-urlencoded'
  132. ];
  133. $ch = curl_init();
  134. curl_setopt($ch, CURLOPT_URL, $url);
  135. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  136. curl_setopt($ch, CURLOPT_POST, true);
  137. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  138. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  139. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//这个是重点。
  140. $result = curl_exec($ch);
  141. curl_close($ch);
  142. return $result;
  143. }
  144. /**
  145. * 数组转json
  146. * @param $data
  147. * @return string
  148. */
  149. protected function jsonEncode($data)
  150. {
  151. return helper::jsonEncode($data, JSON_UNESCAPED_UNICODE);
  152. }
  153. /**
  154. * json转数组
  155. * @param $json
  156. * @return mixed
  157. */
  158. protected function jsonDecode($json)
  159. {
  160. return helper::jsonDecode($json);
  161. }
  162. /**
  163. * 返回错误信息
  164. * @return mixed
  165. */
  166. public function getError()
  167. {
  168. return $this->error;
  169. }
  170. }