分享一個PHP獲取微信JS-SDK配置的操作類
阿新 • • 發佈:2018-12-17
本來是使用easywechat的函式直接生成JS配置的,可是不知為何老是提示簽名是非法的,無奈只有自己寫一個操作類來獲取簽名了…..
但是不得不說easywechat是真的好用,特別是支付,簡直不能更簡單了,強行安利一波:https://www.easywechat.com/
正文內容
一些微信文件的細節:
1.字典排序的四個引數是按引數名排序,不是按值排序
2.加密的url是呼叫微信JS-SDK頁面的url且包含引數部分
特別說明
實際的呼叫中強烈建議要快取獲取的access_token,因為獲取access_token的介面微信是做了呼叫限制的,在下面的程式碼中給出提示的。
操作類
<?php
/**
* Created by PhpStorm.
* User: zheng
* Date: 2018/2/8
* Time: 11:03
*/
class WxJsConfig
{
static $count=5; //用於控制重複呼叫微信介面的次數,確保一定能調取成功
private $wxAppId = 'XXXXXXXXXXXXXXX'; //公眾號的appid
private $wxAppSecret = 'XXXXXXXXXXXXXXXXXX'; //公眾號的app_secret
/** 傳送curl請求
* @param $url
* @param string $method
* @param array $requestData
* @return mixed
*/
public function curlRequest($url,$method='get',$requestData=[])
{
try {
$curlHandle = curl_init();
curl_setopt($curlHandle, CURLOPT_URL, $url);
curl_setopt($curlHandle , CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
if ($method == 'post') {
curl_setopt($curlHandle, CURLOPT_POST, true);
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $requestData);
}
$response = curl_exec($curlHandle);
curl_close($curlHandle);
return $response;
} catch (\Exception $e) {
exit('請求失敗:' . $e->getMessage());
}
}
public function getJsConfig()
{
try{
//此URL是需要呼叫微信JS-SDK頁面的url,由前端頁面傳過來的且包含請求引數部分
$url = $_GET['url'];
if(!$url){
exit('缺少必要引數');
}
$acc_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='
.$this->wxAppId .'&secret='.$this->wxAppSecret;
//TODO 實際開發中獲取access_token要進行快取,執行curlRequest前判斷是否存在快取,不存在才進行呼叫,建議快取7200秒
$accToken = json_decode($this->curlRequest($acc_url),true) ;
if(!isset($accToken['access_token'])){
exit($accToken['errmsg']);
}
$accToken = $accToken['access_token'];
$ticket_url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$accToken.'&type=jsapi';
$ticket = json_decode($this->curlRequest($ticket_url),true);
if(!isset($ticket['ticket'])){
return exit('微信伺服器異常');
}
$ticket = $ticket['ticket'];
//生成隨機字串
$randStr = '';
$str = $ticket.$accToken;
$strLength = strlen($str);
for ($i=0;$i<15;$i++){
if($i%3==0){
$randStr.=rand();
}
$randStr.=$str[rand(0,$strLength)];
}
$randStr.=rand();
$time = time();
$tempSort = [
'noncestr'=>$randStr,
'jsapi_ticket'=>$ticket,
'timestamp'=>$time,
'url'=>$url
];
$keyStr = array_flip($tempSort);
//加密引數是按引數名排序,不是按值排序
ksort($tempSort,SORT_STRING);
$params = $tempSort;
$shaString = '';
foreach ($params as $key=>$val){
if($shaString==''){
$shaString = $keyStr[$val].'='.$val;
}else{
$shaString.='&'.$keyStr[$val].'='.$val;
}
}
$signature = sha1($shaString);
$jsConfig = [
'appId'=>$this->wxAppId,
'timestamp'=>$time,
'nonceStr'=>$randStr,
'signature'=>$signature,
//此處填寫你需要呼叫的JS列表,比如這裡是呼叫的微信獲取地理位置
'jsApiList'=>['checkJsApi', 'openLocation','getLocation'],
'test'=>[
'ticket'=>$ticket,
'url'=>$url
]
];
return json_encode($jsConfig,true);
}catch (\Exception $e){
if(self::$count>0){ //重複呼叫,儘量請求成功
self::$count-=1;
$this->getJsConfig();
}else{
exit('微信伺服器異常');
}
}
}
}
//測試程式碼
$obj = new WxJsConfig();
$config = $obj->getJsConfig();
var_dump(json_decode($config,true));
比如我這裡是呼叫的請求地理位置的介面,獲取到JS配置就可以去呼叫了。
最後的返回值還把,加密需要的引數返回了,欄位名是test,根據這個test裡面的引數就可以使用 微信的除錯工具 檢查簽名是否正確
測試程式碼返回示例:
JS-SDK調取微信地理位置
注意:記得修改程式碼TODO部分,快取access_token