前言
目前項目中有這樣一下需求,通過傳入的不同的參數生成不同渠道的微信小程序二維碼,從而統計各大平臺從小程序引流的數據。而舊系統是先通過接口生成二維碼後先是保存至當前服務器上後,拿到圖片路徑和文件信息然後再使用OSS的SDK上傳到存儲桶。可能是因爲生成的二維碼是文件流,所以以前的人是通過file_put_contents函數做的保存再使用SDK的文件上傳接口。
思路
爲了去掉保存至服務器這一步,所以就不能使用文件上傳。而目前大平臺的存儲服務一般都不止提供一種方式的上傳,所以找到了文檔發現了一個“字符串上傳”。也就是當調用微信接口返回的二維碼文件流(一堆字符串),然後通過該SDK配置路徑和文件就可以實現小程序碼的上傳了。
流程
1. 下載OSS的SDK,可以去其官網也可以composer require aliyuncs/oss-sdk-php
2. 配置參數封裝其字符串上傳方法等
3. 封裝二維碼生成方法
4. 實現上傳後執行業務操作
編碼
1. 文件流上傳部分
/*
*@title 單文件流上傳
*@param string $content 文件流字符串
*@param string $file_name 存儲位置/文件名(包括文件後綴)
*@return object
*/
public function objectUpload($content, $file_name='')
{
$config = $this->config;
$res['code'] = 1;
$res['message'] = '';
try{
$ossClient = new OssClient($config['AccessKeyID'], $config['AccessKeySecret'], $config['EndPoint']);
$result = $ossClient->putObject($config['Bucket'], $file_name, $content);
$res['data']['url'] = $result['info']['url'];
$res['data']['path'] = explode("/",$file_name)[1];
} catch(OssException $e) {
$res['code'] = 0;
$res['message'] = $e->getMessage();
}
return $res;
}
2. 公用文件流上傳函數部分
error_reporting(E_ALL ^ E_NOTICE);
if (!function_exists('oss_object_upload')) {
function oss_object_upload($content,$file_name)
{
$oss = oss\OssFactory::factory("AliOss");
$result = $oss->objectUpload($content,$file_name);
return $result;
}
}
3. 二維碼生成部分
<?php
namespace app\common\library;
use Firebase\JWT\JWT as FirebaseJWT;
use oss\OssFactory;
use think\Db;
use think\Session;
use think\Request;
use think\Loader;
use think\facade\Config;
use GuzzleHttp\Client;
class Wechat{
protected static $instance = null;
protected $_error = "";
protected $_errorMsg = "";
protected $config;
public function __construct($type){
$this->config = Config::pull($type); // 獲取配置參數
}
/*
* @title 獲取對象
* @author beiqiaosu
* @param string $type (mini:小程序配置)
* @return null| object
* */
public static function getInstance($type='mini')
{
if (!self::$instance) {
self::$instance = new self($type);
}
return self::$instance;
}
// 請求微信接口憑證access_token
public function getAccessToken()
{
$res = false;
if(!$this->config) {
$this->_error = '請求配置不存在';
$this->_errorMsg = '接口錯誤';
}
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->config['appId']}&secret={$this->config['appSecret']}";
$client = new Client();
$response = $client->request('GET', $url, ['verify' => false]);
$res = $response->getBody()->getContents();
$result = json_decode(stripcslashes($res), true);
if (!isset($result['errcode']) || $result['errcode'] == 0) {
// 獲取成功
$res = $result['access_token'];
} else {
$this->_error = $result['errmsg'];
$this->_errorMsg = '接口錯誤';
}
return $res;
}
// 生成小程序自定義二維碼
public function getQrcode($scene)
{
$res = false;
if(empty($scene)) {
$this->_error = 'scene參數不存在';
$this->_errorMsg = '接口出錯';
}
$accrssToken = $this->getAccessToken();
// if(!$accrssToken) return $res;
$data = array(
"scene" => "{$scene}"
);
$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$accrssToken}";
// $client = new Client(array(
// 'content-type' => 'application/json'
// ));
// $paramArr = json_encode($data);
// $response = $client->post($url, [
// \GuzzleHttp\RequestOptions::JSON => $data
// ]);
// $response = $client->request('POST', $url, ['json'=>$paramArr]);
// $res = $response->getBody()->getContents();
// $result = json_decode(stripcslashes($res), true);
$returnData = self::httpsRequest($url, $data, 'json');
if (!isset($returnData['errcode']) || $returnData['errcode'] == 0) {
$res = $returnData;
}else {
$this->_error = $returnData['errmsg'];
$this->_errorMsg = '接口出錯';
}
return $res;
}
// cURL POST請求方法(暫放)
public static function httpsRequest($url, $data, $type)
{
if ($type == 'json') {
$headers = array("Content-type: application/json;charset=UTF-8", "Accept: application/json", "Cache-Control: no-cache", "Pragma: no-cache");
$data = json_encode($data);
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
public function getError()
{
return $this->_error;
}
public function getErrorMsg()
{
return $this->_errorMsg;
}
final protected function __clone()
{
}
public function __call($name, $arguments)
{
// TODO: Implement __call() method.
}
}
4. 開始上傳的業務實現部分。
// 獲取二維碼文件流
$ret = \app\common\library\Wechat::getInstance()->getQrcode("activty".$activtyId);
if(!$ret) {
$res['code'] = 400;
$res['msg'] = \app\common\library\Wechat::getInstance()->getError();
return $res;
}
$path = "qrcode/"; // 二維碼文件流存放位置
$fileName = time() . rand(1000,9999) . ".png";
$result = oss_object_upload($ret,$path.$fileName);
// 文件流上傳失敗
if(!$result['code']) {
$res['code'] = 400;
$res['msg'] = $result['message'];
return $res;
}
// 將二維碼圖片放入到引流配置中
$data = [
"id" => $activtyId,
"img" => $result['data']['url']
];
$upRes = Db::name("activity")->update($data);
說明
以上代碼是部分,所以需要自己根據業務整理修改合理的採取,需要封裝的類也可以在公衆號回覆 "文件流OSS" 獲取。