php laravel 生成小程序二维码可自带参数并上传到oss 贴源码

 

微信小程序生成官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.createQRCode.html

 

流程分析:

1.第一步调用微信官放获取  access_token(不用管为什么,去获取就行,后面必须要用)

(大概逻辑:获取完access_token,存redis,小程序官方定的过期时间是2小时,存的时候注意过期时间的单位是分还是秒)

public static function getWxAccessToken()
    {
        $app_id     = config('wechat.mini_program.default.app_id');
        $app_secret = config('wechat.mini_program.default.secret');
        if (!$app_id || !$app_secret) {
            return [false, '获取小程序配置失败!'];
        }

        if (Cache::get('access_token_' . $app_id)) {
            return [true, Cache::get('access_token_' . $app_id)];
        } else {
            $third_api = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $app_id . "&secret=" . $app_secret;
            $result    = getHttpContent($third_api, 'GET');
            $json      = json_decode($result, true);
            if (!isset($json['access_token']) && !$json['access_token']) {
                return [false, '获取access_token失败'];
            }
            $access_token = $json['access_token'];
            Cache::put('access_token_' . $app_id, $access_token, 120);
            return [true, $access_token];
        }
    }

 

2.拿到token ,GET方式curl请求微信的生成二维码图片的api

//这个api有限制30万次
$url= "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=" .$access_token;

//这个api没有次数限制
$url       = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" . $access_token;

3.这里以第一个api为例,下面是示范代码,我自己完整实现过放心使用, (第二个没次数限制的api 传参方式不一样,请看官方文档)

$post_data = json_encode(array("path"=>"pages/index/index?spread_code=$spread_code","width"=> 150));
​​​​​​​$data      = WechatService::httpRequest($url, $post_data,'POST');
//自己建个服务类,把下面方法放到服务类里面静态去调用
public static function httpRequest($url, $post_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 ($post_data != '')
            {
                curl_setopt($curl, CURLOPT_POSTFIELDS, $post_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;
    }

通过打印可以发现,微信返回并不是图片链接,而是二进制流

需要对上面的返回结果进行如下处理:

$result = WechatService::data_uri($data, 'image/jpeg');

    /* 二进制转图片image/png*/
    public static function data_uri($contents, $mime)
    {
        $base64 = base64_encode($contents);
        return ('data:' . $mime . ';base64,' . $base64);
    }

得到完整的二进制流图片地址,调用自己封装的二进制图片上传到oss方法

        $res             = OssService::base64ToOss($result);
public static function base64ToOss($base64){
        // OSS处理
        $result = OssService::base64Upload($base64);//这个方法下面提供的有,根据代码封装位置是否静态调用,里面逻辑是先将二进制流上传到服务器本地,再通过下面的代码上传到oss,若成功上传到oss就删除刚才本地图片
        if ($result['code'] != 200) {
            return ['code' => $result['code'], 'msg' => $result['msg']];
        }

        $fileResult  = &$result['data'];
        $filePath    = $fileResult['path'] . $fileResult['name'];
        $ossFileName = implode('/', ['upload/image', date('Ymd'), $fileResult['name']]);
        try {
            $config = config('services.oss');
            //实例化对象 将配置传入
            $ossClient = new OssClient($config['access_key'], $config['secret_key'], $config['endpoint']);
            $result    = $ossClient->uploadFile($config['bucket'], $ossFileName, $filePath);

            $arr = [
                'oss_url'       => $result['info']['url'],  //上传资源地址
                'relative_path' => $ossFileName     //数据库保存名称(相对路径)
            ];
        } catch (OssException $e) {
            return ['code' => 400, 'msg' => $e->getMessage()];
        } finally {
            unlink($filePath);
        }

        return ['code' => 200, 'info' => $arr];
    }

 

public static function base64Upload($base64, $path = '')
    {
        $data = explode(',', $base64);
        unset($base64);
        if (count($data) !== 2) {
            return ['code' => 400, 'msg' => '文件格式错误'];
        }
        if (preg_match('/^(data:\s*image\/(\w+);base64)/', $data[0], $result)) {
            $type = $result[2];
            if (!in_array($type, array('jpeg', 'jpg', 'gif', 'bmp', 'png'))) {
                return ['code' => 400, 'msg' => '文件格式不在允许范围内'];
            }
            $image_name = md5(uniqid()) . '.' . $result[2];
            $image_path = "./upload/image/";
            $image_file = $image_path . $image_name;
            if (!file_exists($image_path)) {
                mkdir($image_path, 0777, true);
            }
            //服务器文件存储路径
            try {
                if (file_put_contents($image_file, base64_decode($data[1]))) {
                    return ['code' => 200, 'msg' => '成功', 'data' => ['name' => $image_name, 'path' => $image_path]];
                } else {
                    return ['code' => 400, 'msg' => '文件保存失败'];
                }
            } catch (\Exception $e) {
                return ['code' => 400, 'msg' => $e->getMessage()];
            }
        }
        return ['code' => 400, 'msg' => '文件格式错误'];
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章