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' => '文件格式錯誤'];
    }

 

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