V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
TANKING
V2EX  ›  微信

PHP 生成微信小程序二维码,可生成带参数二维码。

  •  
  •   TANKING · 2018-07-14 10:16:33 +08:00 · 1598 次点击
    这是一个创建于 2084 天前的主题,其中的信息可能已经有所发展或是发生改变。

    微信小程序官方开放了 3 个创建二维码的接口,其中有一个是生成二维码的,还有一个是葵花状的小程序码,我这里就用 php 生成二维码。

    首先要获取 Access_token

    这个请求起来也是很容易的,微信开发文档有请求接口: 要把自己的小程序的 APPID 和 APPSECRET 获取到

    https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    

    access_token 只有 2 小时有效期,所以要缓存最好,避免重复请求

    构建请求参数

    这里写图片描述

    可以构建一个数组,然后转成 json 数据赋给一个变量

    $param = json_encode(array("path"=>"pages/index/index?id=123","width"=> 150));
    

    然后 POST 数据发送到微信服务器换取二维码

    完整代码

    <?php
    header('content-type:text/html;charset=utf-8');
    //配置 APPID、APPSECRET
    $APPID = "APPID"; 
    $APPSECRET =  "APPSECRET"; 
    //获取 access_token
    $access_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$APPID&secret=$APPSECRET";
    
    //缓存 access_token
     session_start();
     $_SESSION['access_token'] = "";
     $_SESSION['expires_in'] = 0;
    
     $ACCESS_TOKEN = "";
     if(!isset($_SESSION['access_token']) || (isset($_SESSION['expires_in']) && time() > $_SESSION['expires_in']))
     {
    
         $json = httpRequest( $access_token );
         $json = json_decode($json,true); 
         // var_dump($json);
         $_SESSION['access_token'] = $json['access_token'];
         $_SESSION['expires_in'] = time()+7200;
         $ACCESS_TOKEN = $json["access_token"]; 
     } 
     else{
    
         $ACCESS_TOKEN =  $_SESSION["access_token"]; 
     }
    
    //构建请求二维码参数
    //path 是扫描二维码跳转的小程序路径,可以带参数?id=xxx
    //width 是二维码宽度
    $qcode ="https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=$ACCESS_TOKEN";
    $param = json_encode(array("path"=>"pages/index/index?id=123","width"=> 150));
    
    //POST 参数
    $result = httpRequest( $qcode, $param,"POST");
    //生成二维码
    file_put_contents("qrcode.png", $result);
    $base64_image ="data:image/jpeg;base64,".base64_encode( $result );
    
    //把请求发送到微信服务器换取二维码
      function httpRequest($url, $data='', $method='GET'){
        $curl = curl_init();  
        curl_setopt($curl, CURLOPT_URL, $url);  
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);  
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);  
        curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);  
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);  
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);  
        if($method=='POST')
        {
            curl_setopt($curl, CURLOPT_POST, 1); 
            if ($data != '')
            {
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);  
            }
        }
    
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);  
        curl_setopt($curl, CURLOPT_HEADER, 0);  
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);  
        $result = curl_exec($curl);  
        curl_close($curl);  
        return $result;
      } 
    
    ?>
    

    使用方法:

    1、新建 qrcode.php
    2、拷贝上面代码进去
    3、修改 APPID 和 APPSECRET
    4、访问 qrcode.php

    即可生成一个带参数的小程序二维码

    这里写图片描述

    但是这个接口生成的是有 LOGO 的小程序二维码。 我们想要生成一个简简单单的,无 LOGO 的小程序二维码可以吗? 官方的是没有办法的,但是我们可以用第三方的接口生成普通的二维码的方式。

    生成无 LOGO 二维码步骤

    1、先解码,把刚才生成的小程序二维码解码,获得 URL
    2、把获得的 URL 用普通的二维码生成接口生成普通的无 LOGO 的二维码

    解码

    解码其实有很多的库我这里直接用了第三方的 JSSDK 解码,免费的,需要申请接口和 appid 和 appkey

    <h2>生成无 LOGO 二维码</h2>
    <!DOCTYPE html>
    <html>
      <head>
        <title>PHP 生成微信小程序二维码</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://cdn.bootcss.com/zepto/1.0rc1/zepto.min.js"></script>
        <script src="hprose.min.js"></script>
        <script src="md5.min.js"></script>
      </head>
      <body>
        <!--显示二维码-->
        <div id="show_test"></div>
        <div id="select_img" style="display:none;">
            <input type="file" id="imgTest" type="file"  accept=".gif,.jpg,.jpeg,.png">
            <br/>
            <img src="" id="showImage" alt="">
        </div>
        <a href="javascript:;" id="qrdecode">点击生成无 LOGO 二维码</a>
        <script>
    
        var get_timestamp = function(){
            var timestamp =0;
            timestamp = Date.parse(new Date());// 获取当前时间戳(以 s 为单位)
            timestamp = timestamp / 1000;
            return timestamp;
        };
    
        //config,申请解码接口: http://www.wwei.cn/ ,免费
        var api_id = 'xxxxxxx';//改为您自己的
        var api_key = 'xxxxxxxxx';//改为您自己的
        var timestamp = get_timestamp();
        var client = hprose.Client.create('http://hprose.wwei.cn/qrcode.html', ['qrencode','qrdecode']);
    
        //解码
        $("#qrdecode").click(function(){
                var timestamp = get_timestamp();
                var imgurl = '';//远程图片
                var imgdata ='<?php echo $base64_image;?>';//本地图片,直接调用生成的官方小程序二维码,用于解码
                var signature = md5(api_key + timestamp + imgurl +  imgdata);
                client.ready(function(qrcode) {
                    qrcode.qrdecode(api_id,signature,timestamp,imgurl,imgdata)
                    .then(function(result) {
                        if(result.status !=1){
                            alert(result.msg);
                            return ;
                        }
    
                        //生成无 LOGO 二维码 api 接口
                        var qrcodeapi = "http://qr.liantu.com/api.php?text=";
                        //拼接接口+解码 url 并输出为图片
                        $("#show_test").html('<img src="'+qrcodeapi+result.data.raw_text+'"/>');
                    },function(e) {
                        console.error(e);
                    });
                },
                function(e) {
                    console.error(e);
                });
        });
        </script>
      </body>
    </html>
    

    上面是通过 js 来实现的解码,解码还是调用了 php 生成的二维码的一个图片地址的

    <?php echo $base64_image;?>
    

    上面是调用本地图片,所以需要结合 php 生成小程序二维码的代码使用这个解码程序。

    解码后需要生成无 LOGO 的二维码,这个我只需要调用一个接口就行。

    接口: http://qr.liantu.com/api.php?text=

    然后拼接解码后的 url 就可以生成一个二维码了。

    这里写图片描述

    那么生成小程序码和生成无 LOGO 二维码的代码结合起来就是:

    <?php
    header('content-type:text/html;charset=utf-8');
    //配置 APPID、APPSECRET
    $APPID = "APPID"; 
    $APPSECRET =  "APPSECRET"; 
    //获取 access_token
    $access_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$APPID&secret=$APPSECRET";
    
    //缓存 access_token
     session_start();
     $_SESSION['access_token'] = "";
     $_SESSION['expires_in'] = 0;
    
     $ACCESS_TOKEN = "";
     if(!isset($_SESSION['access_token']) || (isset($_SESSION['expires_in']) && time() > $_SESSION['expires_in']))
     {
    
         $json = httpRequest( $access_token );
         $json = json_decode($json,true); 
         // var_dump($json);
         $_SESSION['access_token'] = $json['access_token'];
         $_SESSION['expires_in'] = time()+7200;
         $ACCESS_TOKEN = $json["access_token"]; 
     } 
     else{
    
         $ACCESS_TOKEN =  $_SESSION["access_token"]; 
     }
    
    //构建请求二维码参数
    //path 是扫描二维码跳转的小程序路径,可以带参数?id=xxx
    //width 是二维码宽度
    $qcode ="https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=$ACCESS_TOKEN";
    $param = json_encode(array("path"=>"pages/index/index?id=123","width"=> 150));
    
    //POST 参数
    $result = httpRequest( $qcode, $param,"POST");
    //生成二维码
    file_put_contents("qrcode.png", $result);
    $base64_image ="data:image/jpeg;base64,".base64_encode( $result );
    
    //把请求发送到微信服务器换取二维码
      function httpRequest($url, $data='', $method='GET'){
        $curl = curl_init();  
        curl_setopt($curl, CURLOPT_URL, $url);  
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);  
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);  
        curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);  
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);  
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);  
        if($method=='POST')
        {
            curl_setopt($curl, CURLOPT_POST, 1); 
            if ($data != '')
            {
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);  
            }
        }
    
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);  
        curl_setopt($curl, CURLOPT_HEADER, 0);  
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);  
        $result = curl_exec($curl);  
        curl_close($curl);  
        return $result;
      } 
    
    ?>
    
    <h2>生成小程序官方二维码</h2>
    <!-- 生成小程序官方二维码 -->
    <img src="<?php echo $base64_image;?>"/>
    
    <br/>
    <h2>生成无 LOGO 二维码</h2>
    <!-- 生成无 LOGO 二维码 -->
    <!DOCTYPE html>
    <html>
      <head>
        <title>PHP 生成微信小程序二维码</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://cdn.bootcss.com/zepto/1.0rc1/zepto.min.js"></script>
        <script src="hprose.min.js"></script>
        <script src="md5.min.js"></script>
      </head>
      <body>
        <div id="show_test"><!--显示信息--></div>
        <div id="select_img" style="display:none;">
            <input type="file" id="imgTest" type="file"  accept=".gif,.jpg,.jpeg,.png">
            <br/>
            <img src="" id="showImage" alt="">
        </div>
        <a href="javascript:;" id="qrdecode">点击生成无 LOGO 二维码</a>
        <script>
    
        var get_timestamp = function(){
            var timestamp =0;
            timestamp = Date.parse(new Date());// 获取当前时间戳(以 s 为单位)
            timestamp = timestamp / 1000;
            return timestamp;
        };
    
        //config,申请解码接口: http://www.wwei.cn/ ,免费
        var api_id = 'xxx';//改为您自己的
        var api_key = 'xxx';//改为您自己的 (实际使用,建议在后台完成 signature 签名,以防暴露 api_key,或定期更改)
        var timestamp = get_timestamp();
        var client = hprose.Client.create('http://hprose.wwei.cn/qrcode.html', ['qrencode','qrdecode']);
    
        //解码
        $("#qrdecode").click(function(){
                var timestamp = get_timestamp();
                var imgurl = '';//远程图片
                var imgdata ='<?php echo $base64_image;?>';//本地图片,直接调用生成的官方小程序二维码,用于解码
                var signature = md5(api_key + timestamp + imgurl +  imgdata);
                client.ready(function(qrcode) {
                    qrcode.qrdecode(api_id,signature,timestamp,imgurl,imgdata)
                    .then(function(result) {
                        if(result.status !=1){
                            alert(result.msg);
                            return ;
                        }
    
                        //生成无 LOGO 二维码 api 接口
                        var qrcodeapi = "http://qr.liantu.com/api.php?text=";
                        //拼接接口+解码 url 并输出为图片
                        $("#show_test").html('<img src="'+qrcodeapi+result.data.raw_text+'"/>');
                    },function(e) {
                        console.error(e);
                    });
                },
                function(e) {
                    console.error(e);
                });
        });
        </script>
      </body>
    </html>
    

    但是解码需要用到的两个 js 库

    这里直接提供下载地址: https://pan.baidu.com/s/1UYDj_WbmCG21VPd8XtpaXA

    作者:TANKING
    2018-7-13

    1 条回复    2018-07-14 14:16:09 +08:00
    mingyun
        1
    mingyun  
       2018-07-14 14:16:09 +08:00
    CURLOPT_TIMEOUT 设的有点长

    放百度网盘多麻烦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   998 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:06 · PVG 06:06 · LAX 15:06 · JFK 18:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.