php 生成微信小程序码(可携带参数) 永久有效,数量暂无限制

17 篇文章 4 订阅
17 篇文章 0 订阅

官方文档入口 

一、首先要先获取 access_token,把拿到的token存放在redis中

 a.php文件

/**
 * 获取小程序全局唯一后台接口调用凭据  accessToken
 * access_token 的有效期目前为 2 个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效;
 * @param appid 小程序appid
 * @param appsecret 小程序公众号秘钥
 */
public static function getAccessToken($appid, $appsecret)
{
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);

    // 如果accessToken 不存在或者已过期,则重新去生成一个
    $token = $redis->get("jw_applet_accessToken");
    if (!$token) {
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $appsecret;
        $html = file_get_contents($url);
        $output = json_decode($html, true);
        $access_token = $output['access_token'];

        /**
         * 微信平台会保证 在5分钟内,新老 access_token 都可用,所以需要提前去刷新,这里设置提前4分钟进行刷新
         * 创建一个具有时间限制的键值,过期则删除,秒为单位,成功返回true
         */
        $redis->setex('jw_applet_accessToken', $output['expires_in'] - 240, $access_token);
        return $access_token;
    }
    return $token;
}

二、生成小程序码

 a.php文件

/**
 * 获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制
 * @param appid 小程序appid
 * @param appsecret 小程序公众号秘钥
 * @param scene 进入小程序时的参数 示例:a=1 最大32个可见字符 (必填参数 不能为空,不传会报错)
 * @param page 必须是已经发布的小程序存在的页面(否则报错) 根路径前不要加 /,如:pages/index/index  如果不填写这个字段,默认跳主页面
 * @param width 二维码的宽度,默认值:430  单位 px,最小 280px,最大 1280px
 * @param autoColor 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false
 * @param line_color auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
 * @param is_hyaline 是否需要透明底色,为 true 时,生成透明底色的小程序
 */
public static function createQRCode($appid, $appsecret, $scene = 'a=1', $page = '', $width = 430, $autoColor = false, $lineColor = [], $isHyaline = false)
{
    $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . self::getAccessToken($appid, $appsecret);
    $lineColor = $lineColor ?? ["r" => "0", "g" => "0", "b" => "0"];
    $params = [
        'scene' => $scene ?? 'NoParameters',
        'page' => $page,
        'width' => intval($width),
        'auto_color' => $autoColor,
        'is_hyaline' => $isHyaline
    ];

    $result = self::post($url, json_encode($params));

    // 判断是否是 json格式, 如果请求失败,会返回 JSON 格式的数据。
    if (is_null(json_decode($result))) {
        /**
         * 不是json格式的数据   说明有数据流  json_decode($result)返回值是为 null
         * 这里返回的图片 Buffer
         */
        return ['code' => 0, 'data' => $result, 'msg' => 'success'];
    } else {
        $res = json_decode($result, true);
        return $res;
    }
}


/**
 * 发送POST请求
 * @param url  请求的地址
 * @param data 请求的参数
 */
public static function post($url, $data)
{
    $curl = curl_init($url);

    $upload = false;
    if (is_array($data)) {
        foreach ($data as $key => $rs) {
            if (is_object($rs)) {
                $upload = true;
            }
        }
        if (!$upload) {
            $data = http_build_query($data);
        }
    }

    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_USERAGENT, self::$user_agent);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, self::$conn_time_out);
    curl_setopt($curl, CURLOPT_TIMEOUT, self::$time_out);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);

    if (!is_null(self::$referer_path)) {
        curl_setopt($curl, CURLOPT_REFERER, self::$referer_path);
    }

    if (!is_null(self::$cookie_str)) {
        curl_setopt($curl, CURLOPT_COOKIE, self::$cookie_str);
    }

    if (!is_null(self::$cookie_path)) {
        curl_setopt($curl, CURLOPT_COOKIEFILE, self::$cookie_path);
        if (self::$cookie_save) {
            curl_setopt($curl, CURLOPT_COOKIEJAR, self::$cookie_path);
        }
    }

    if (!empty(self::$header)) {
        $headers = array();
        foreach (self::$header as $key => $val) {
            $headers[] = $key . ': ' . $val;
        }
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    }

    $return = curl_exec($curl);
    curl_close($curl);
    return $return;
}

接下来贴一段我调用前面方法的代码片段,把图片保存到本地服务器上,这边只是给出具体的思路,不能完全照抄,要看清楚哈!!!

因为我需要生成带参数的小程序码,而且参数是很长的一大串字符,已经超过了微信限制的最大长度32位字符,所以这边给参数使用md5加密,让长度永远固定在32位

b.php文件

<?php

class B
{
    /**
     * 生成小程序码
     * 因为我需要生成带参数的小程序码,而且参数是很长的一大串字符,已经超过了微信限制的最大长度32位字符,所以这边给参数使用md5加密,让长度永远固定在32位
     */
    public function createQRCode($parameter = '')
    {
        // 获取前端传来的参数,具体你们可以按照你项目框架获取参数的方法,这段不用参考哈~~~~~        
        $bh = $parameter->bh;
        $pagePath = $parameter->pagePath;
        $isShare = $parameter->isShare;
        $sharerPhone = $parameter->sharerPhone;
        $openid = $parameter->openid;
        $fangtype = $parameter->fangtype;

        // 小程序码上页面路径的参数 如:bh=123asd45sd812
        $scene = 'bh=' . $bh . '&isShare=' . $isShare . '&sharerPhone=' . $sharerPhone . '&openid=' . $openid . '&fangtype=' . $fangtype;
        // 因受微信限制 scene 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符, 所以需要加密处理
        $code_key = md5($scene);

        /**
         * 这边可以把加密后的值存放在数据库中
         * code_key就是加密后的值,code_value是完整的参数,在我这边这个demo中也就是这个scene
         * 还可以把生成后的小程序码的图片地址也存放到表中
         * 这样通过小程序码进入后的拿到参数的就是这个code_key,可以把这个code_key和数据库中的存放的code_key进行比对,有找到的话,就可以解码出当前扫码进入小程序页面的完这整参数了
         */
       
        // 这是查询数据库的方法,具体你们可以按照你项目框架查询数据库的方法,这段不用参考哈~~~~~
        // 判断之前是否已经生成过 当前用户分享过当前详情页的小程序码
        $sql = "select code_value, imgUrl from wxqrcode where code_key = '$code_key'";
        $resultObj = JW_DBHelper::getDataEx($dbInfo, $sql);

        // 已生成过,直接返回小程序码的图片地址
        if (count($resultObj['result']) > 0) {
            return self::send(0, '已生成过当前编号的小程序码', $resultObj['result'][0]['imgUrl']);
        } else {
            // 还未生成过
            require_once 'a.php';

            $res = a::createQRCode('这里填你的小程序的appid', '这里填你的小程序密钥secret', $code_key, '这里填你的小程序的页面路径,不传默认是跳转到首页');
            if (isset($res['code']) && $res['msg'] == 'success') {
                /**
                 * 得到图片的 Buffer: $res['data']
                 * 创建文件准备写入
                 * 这时可以把图片存放在本地服务器上 或者 阿里云OSS等第三方的平台上
                 */
                // 这是小程序码的图片 保存在服务器上的具体路径地址
                $filePath = 'D:/wwwroot/appweb/upload/wxQRcode/' . $bh . '.png';
                $file = fopen($filePath, 'w');
                fwrite($file, $res['data']);
                fclose($file);
                
                // 这是小程序码外网可访问的地址
                $imgUrl = 'https://www.xxx.com/upload/wxQRcode/' . $bh . '.png';

                // 插入到表中,保存起来
                $sql = "INSERT INTO wxqrcode(code_key, code_value, 'imgUrl') value('$code_key', '$scene', '$imgUrl')";
                $resultObj = JW_DBHelper::executeSql($dbInfo, $sql);

                return self::send(0, '生成小程序码成功', $imgUrl);
            }

            // 调用微信api接口 生成小程序码失败
            return self::send($res['errcode'], $res['errmsg']);
        }
    }
    
    /**
     * 这方法是扫码进入小程序页面后,调用的(可供你们参考用~)
     * 根据 加密后的key 读取小程序码参数加密表中的值
     * @param code_key 小程序码scene参数的值(md5后加密的值)
     */
    public function getWxqrcodeValue($parameter = '')
    {
        // 获取前端传来的参数
        $code_key = $parameter->code_key;
        if (!isset($code_key) || strlen($code_key) == 0) return self::send(4000, 'scene参数不能为空');

        $sql = "select code_value from wxqrcode where code_key = '$code_key'";
        $resultObj = JW_DBHelper::getDataEx($dbInfo, $sql);

        // 有查询到
        if (count($resultObj['result']) > 0) {
            $code_value = $resultObj['result'][0]['code_value'];
            return self::send(0, '获取成功', $code_value);
        } else {
            return self::send(400, 'code_key匹配不到scene参数');
        }
    }

    /**
     * 接口返回数据
     * @param $code  int     0:表示成功,非0表示失败
     * @param $msg   string  返回的提示消息
     * @param $data  string/array  返回的数据
     */
    public static function send($code = 0, $msg = '', $data = null)
    {
        $resultObj['code'] = $code;
        $resultObj['msg'] = $msg;
        $resultObj['data'] = $data;
        return $resultObj;
    }
}

好了,到此整个流程就几乎可以了~

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值