分享一个PHP获取微信JS-SDK配置的操作类

本来是使用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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值