1 <?php 2 class JSSDK { 3 private $appId; 4 private $appSecret; 5 6 public function __construct($appId, $appSecret) { 7 $this->appId = $appId; 8 $this->appSecret = $appSecret; 9 } 10 11 public function getSignPackage() { 12 $jsapiTicket = $this->getJsApiTicket(); 13 14 // 注意 URL 一定要动态获取,不能 hardcode. 15 $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; 16 $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; 17 18 $timestamp = time(); 19 $nonceStr = $this->createNonceStr(); 20 21 // 这里参数的顺序要按照 key 值 ASCII 码升序排序 22 $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; 23 24 $signature = sha1($string); 25 26 $signPackage = array( 27 "appId" => $this->appId, 28 "nonceStr" => $nonceStr, 29 "timestamp" => $timestamp, 30 "url" => $url, 31 "signature" => $signature, 32 "rawString" => $string 33 ); 34 return $signPackage; 35 } 36 37 private function createNonceStr($length = 16) { 38 $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 39 $str = ""; 40 for ($i = 0; $i < $length; $i++) { 41 $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 42 } 43 return $str; 44 } 45 46 private function getJsApiTicket() { 47 // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例 48 $data = json_decode(file_get_contents("jsapi_ticket.json")); 49 if ($data->expire_time < time()) { 50 $accessToken = $this->getAccessToken(); 51 // 如果是企业号用以下 URL 获取 ticket 52 // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken"; 53 $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken"; 54 $res = json_decode($this->httpGet($url)); 55 $ticket = $res->ticket; 56 if ($ticket) { 57 $data->expire_time = time() + 7000; 58 $data->jsapi_ticket = $ticket; 59 $fp = fopen("jsapi_ticket.json", "w"); 60 fwrite($fp, json_encode($data)); 61 fclose($fp); 62 } 63 } else { 64 $ticket = $data->jsapi_ticket; 65 } 66 67 return $ticket; 68 } 69 70 private function getAccessToken() { 71 // access_token 应该全局存储与更新,以下代码以写入到文件中做示例 72 $data = json_decode(file_get_contents("access_token.json")); 73 if ($data->expire_time < time()) { 74 // 如果是企业号用以下URL获取access_token 75 // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret"; 76 $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret"; 77 $res = json_decode($this->httpGet($url)); 78 $access_token = $res->access_token; 79 if ($access_token) { 80 $data->expire_time = time() + 7000; 81 $data->access_token = $access_token; 82 $fp = fopen("access_token.json", "w"); 83 fwrite($fp, json_encode($data)); 84 fclose($fp); 85 } 86 } else { 87 $access_token = $data->access_token; 88 } 89 return $access_token; 90 } 91 92 private function httpGet($url) { 93 $curl = curl_init(); 94 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 95 curl_setopt($curl, CURLOPT_TIMEOUT, 500); 96 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 97 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); 98 curl_setopt($curl, CURLOPT_URL, $url); 99 100 $res = curl_exec($curl); 101 curl_close($curl); 102 103 return $res; 104 } 105 }