Wechat.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. /*
  3. |--------------------------------------------------------------------------
  4. | core.php 微信平台核心类
  5. |--------------------------------------------------------------------------
  6. */
  7. namespace Main\Lib;
  8. use Dever;
  9. class Wechat
  10. {
  11. /**
  12. * config
  13. *
  14. * @var array
  15. */
  16. private $config;
  17. /**
  18. * config
  19. *
  20. * @var array
  21. */
  22. private $token;
  23. /**
  24. * project
  25. *
  26. * @var string
  27. */
  28. private $project;
  29. /**
  30. * 构造函数 初始化
  31. *
  32. * @return mixed
  33. */
  34. public function __construct($type = 'component', $project = false)
  35. {
  36. $this->config = Dever::config('sign')->cAll;
  37. if (!$project) {
  38. $project = Dever::input('project', 1);
  39. }
  40. if (!$project) {
  41. Dever::alert('project is not exits!');
  42. }
  43. $this->project = $project;
  44. }
  45. /**
  46. * 获取当前站点的配置
  47. *
  48. * @return mixed
  49. */
  50. public function project()
  51. {
  52. return $this->project;
  53. }
  54. /**
  55. * 获取当前站点的配置
  56. *
  57. * @return mixed
  58. */
  59. public function config()
  60. {
  61. return $this->config['accessToken'][$this->project];
  62. }
  63. /**
  64. * 获取签名信息
  65. *
  66. * @return mixed
  67. */
  68. public function get($url)
  69. {
  70. $ticket = $this->ticket($this->token());
  71. if (!$ticket) {
  72. $return['status'] = 0;
  73. $return['msg'] = 'error';
  74. } else {
  75. $timestamp = time();
  76. $nonce = $this->nonce();
  77. $signature = $this->signature($ticket, $url, $timestamp, $nonce);
  78. $return = array
  79. (
  80. 'appId' => $this->config['accessToken'][$this->project]['appid'],
  81. 'timestamp' => $timestamp,
  82. 'nonceStr' => $nonce,
  83. 'signature' => $signature,
  84. 'status' => 1,
  85. 'msg' => '成功',
  86. );
  87. }
  88. Dever::out($return);
  89. }
  90. /**
  91. * 获取nonce
  92. *
  93. * @return mixed
  94. */
  95. private function nonce()
  96. {
  97. return substr(md5(microtime()), rand(10, 15));
  98. }
  99. /**
  100. * 获取accessToken
  101. *
  102. * @return mixed
  103. */
  104. public function token($state = 1)
  105. {
  106. $url = $this->config['accessToken']['url'] . '&' . http_build_query($this->config['accessToken'][$this->project]);
  107. $where['where_project'] = $this->project;
  108. $info = Dever::load('main/token-info', $where);
  109. $request = $update = false;
  110. if ($info && ((time() - $info['mdate'] >= $info['expires_in']) || $state == 2)) {
  111. $request = $update = true;
  112. } elseif ($info) {
  113. return $info['token'];
  114. }
  115. if (!$info) {
  116. $request = true;
  117. $update = false;
  118. }
  119. if ($request == true) {
  120. $data = json_decode(Dever::curl($url), true);
  121. if ($data && isset($data['access_token'])) {
  122. $data['expires_in'] = $data['expires_in'] - 2000;
  123. if ($update == true) {
  124. $set['set_project'] = $this->project;
  125. $set['set_token'] = $data['access_token'];
  126. $set['set_expires_in'] = $data['expires_in'];
  127. $set['where_id'] = $info['id'];
  128. Dever::load('main/token-update', $set);
  129. } else {
  130. $insert['add_project'] = $this->project;
  131. $insert['add_token'] = $data['access_token'];
  132. $insert['add_expires_in'] = $data['expires_in'];
  133. Dever::load('main/token-insert', $insert);
  134. }
  135. return $data['access_token'];
  136. }
  137. }
  138. }
  139. /**
  140. * 获取ticket
  141. *
  142. * @return mixed
  143. */
  144. private function ticket($token)
  145. {
  146. $url = $this->config['ticket'] . $token;
  147. $where['where_project'] = $this->project;
  148. $info = Dever::load('main/ticket-info', $where);
  149. $request = $update = false;
  150. if ($info && time() - $info['mdate'] >= $info['expires_in']) {
  151. $request = $update = true;
  152. } elseif($info) {
  153. return $info['ticket'];
  154. }
  155. if (!$info) {
  156. $request = true;
  157. $update = false;
  158. }
  159. if ($request == true) {
  160. $data = json_decode(Dever::curl($url), true);
  161. if ($data && isset($data['ticket'])) {
  162. $data['expires_in'] = $data['expires_in'] - 2000;
  163. if ($update == true) {
  164. $set['set_project'] = $this->project;
  165. $set['set_ticket'] = $data['ticket'];
  166. $set['set_expires_in'] = $data['expires_in'];
  167. $set['where_name'] = $this->project;
  168. Dever::load('main/ticket-update', $set);
  169. } else {
  170. $insert['add_project'] = $this->project;
  171. $insert['add_ticket'] = $data['ticket'];
  172. $insert['add_expires_in'] = $data['expires_in'];
  173. Dever::load('main/ticket-insert', $insert);
  174. }
  175. return $data['ticket'];
  176. }
  177. }
  178. }
  179. /**
  180. * 获取signature
  181. *
  182. * @return mixed
  183. */
  184. private function signature($ticket, $url, $timestamp, $noncestr)
  185. {
  186. $info = array();
  187. $info['jsapi_ticket'] = $ticket;
  188. $info['url'] = $url;
  189. $info['timestamp'] = $timestamp;
  190. $info['noncestr'] = $noncestr;
  191. ksort($info);
  192. $signature_string = substr(http_build_query($info), 0, -1);
  193. /*
  194. foreach($info as $k => $v)
  195. {
  196. $signature_string .= $k . '=' . $v . '&';
  197. }
  198. $signature_string = substr($signature_string, 0, -1);
  199. */
  200. return sha1($signature_string);
  201. }
  202. }