signaturer.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 2017/6/20
  6. * Time: 上午10:25
  7. */
  8. namespace thrid_author;
  9. use Log;
  10. class signaturer
  11. {
  12. const appid = 'wx6b42e00ecaade538';
  13. const appsecret ='ee64233b3144d76217161666f8cb4c86';
  14. const access_token_url = "https://api.weixin.qq.com/cgi-bin/token";
  15. const ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
  16. const prefix = 'signaturer';
  17. const try_sleep = 5;
  18. private $mData;
  19. private static $stInstance = null;
  20. public static function instance()
  21. {
  22. if(self::$stInstance == null) {
  23. self::$stInstance = new signaturer();
  24. }
  25. return self::$stInstance;
  26. }
  27. private function __construct()
  28. {
  29. $this->mData = [];
  30. }
  31. public function signurl($sign_url)
  32. {
  33. $ticket = $this->rjsapi_ticket();
  34. if($ticket == false) {
  35. Log::record(__METHOD__ . " sign error",Log::ERR);
  36. return false;
  37. }
  38. $timestamp = time();
  39. $nonceStr = $this->noncestr();
  40. $string = "jsapi_ticket={$ticket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$sign_url}";
  41. $signature = sha1($string);
  42. Log::record(__METHOD__ . " signurl={$sign_url} noncestr={$nonceStr} timestamp={$timestamp} ticket={$ticket} signature={$signature}",Log::DEBUG);
  43. return ["appid" => signaturer::appid,"noncestr" => $nonceStr,"timestamp" => $timestamp,"signature" => $signature];
  44. }
  45. private function noncestr($length = 16)
  46. {
  47. $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  48. $str = "";
  49. for ($i = 0; $i < $length; $i++) {
  50. $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
  51. }
  52. return $str;
  53. }
  54. private function rjsapi_ticket()
  55. {
  56. if(empty($this->mData) || empty($this->mData['jsapi_ticket'])) {
  57. $fReadCache = true;
  58. }
  59. else
  60. {
  61. $expires = $this->mData['jsapi_ticket']['expires'];
  62. if(time() >= $expires) {
  63. $fReadCache = true;
  64. } else {
  65. $fReadCache = false;
  66. }
  67. }
  68. if($fReadCache)
  69. {
  70. $items = rcache('jsapi_ticket',self::prefix);
  71. if(empty($items)) {
  72. $this->mData['jsapi_ticket'] = $this->request();
  73. }
  74. else
  75. {
  76. $expires = intval($items['expires']);
  77. if($expires <= time()) {
  78. $this->mData['jsapi_ticket'] = $this->request();
  79. } else {
  80. $this->mData['jsapi_ticket'] = $items;
  81. }
  82. }
  83. }
  84. return $this->mData['jsapi_ticket']['ticket'];
  85. }
  86. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87. public function request()
  88. {
  89. while (true)
  90. {
  91. $token = $this->access_token();
  92. if($token != false) {
  93. break;
  94. } else {
  95. sleep(signaturer::try_sleep);
  96. }
  97. }
  98. $accessToken = $token['token'];
  99. while (true)
  100. {
  101. $ticket = $this->jsapi_ticket($accessToken);
  102. if($ticket != false) {
  103. break;
  104. }
  105. else {
  106. sleep(signaturer::try_sleep);
  107. }
  108. }
  109. $ticket['expires'] = intval($ticket['expires'] / 2 + time());
  110. wcache('jsapi_ticket',$ticket,self::prefix);
  111. Log::record(__METHOD__ . " ticket={$ticket['ticket']}",Log::DEBUG);
  112. return $ticket;
  113. }
  114. private function jsapi_ticket($accessToken)
  115. {
  116. $params = ['type' => 'jsapi','access_token' => $accessToken];
  117. $res = http_request(self::ticket_url,$params);
  118. if($res == false) return false;
  119. $res = json_decode($res,true);
  120. if($res['errcode'] != 0) {
  121. Log::record("jsapi_ticket error : code={$res['errcode']} msg={$res['errmsg']}",Log::ERR);
  122. return false;
  123. }
  124. $ticket['expires'] = intval($res['expires_in']);
  125. $ticket['ticket'] = $res['ticket'];
  126. return $ticket;
  127. }
  128. private function access_token()
  129. {
  130. $params = ['grant_type' => 'client_credential','appid' => signaturer::appid,'secret' => signaturer::appsecret];
  131. $res = http_request(self::access_token_url,$params);
  132. if($res == false) return false;
  133. $res = json_decode($res,true);
  134. if(array_key_exists('errcode',$res)) {
  135. $code = $res['errcode'];
  136. $msg = $res['errmsg'];
  137. Log::record("signurl access_token error code={$code} msg={$msg}",Log::DEBUG);
  138. return false;
  139. }
  140. else {
  141. $token['expires'] = intval($res['expires_in']);
  142. $token['token'] = $res['access_token'];
  143. return $token;
  144. }
  145. }
  146. }