官方文档入口
一、首先要先获取 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文件
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;
}
}
好了,到此整个流程就几乎可以了~