
封面
最近看卡券功能的時(shí)候,創(chuàng)建卡券的時(shí)候涉及到上傳圖片的操作,但官方文檔里面描述似乎有一點(diǎn)問(wèn)題,在這里做一個(gè)記錄。AccessToken的獲取和處理放后面。
開(kāi)發(fā)語(yǔ)言用的是PHP 7.0,使用CodeIgniter框架。
上傳圖片
請(qǐng)求地址說(shuō)明:
HTTP請(qǐng)求方式: POST/FROMURL:https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
文檔里參數(shù)是buffer和access_token,但實(shí)際測(cè)試下來(lái)是不行的,后來(lái)網(wǎng)上搜索和查看素材管理相關(guān)信息后,發(fā)現(xiàn)需要參數(shù)為media、access_token和type。
代碼如下:
// access_token和type參數(shù)
$params = [];
// getAccessToken獲取access_token的函數(shù),如何獲取查看官方文檔
$params['access_token'] = $this->getAccessToken();
$params['type'] = "image";
$url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg";
// 拼接后為 url?access_token=xxx&type=image
$url = $url.'?'.http_build_query($params);
// 相對(duì)于網(wǎng)站的圖片的絕對(duì)路徑
$filename = "/path/sample.png";
// 圖片在服務(wù)器上的真是路徑,如果是前端上傳的,可以另行獲取,這里使用的是網(wǎng)站上的圖片作為測(cè)試
$real_path = $_SERVER['DOCUMENT_ROOT'].$filename;
// 圖片data
$file_data = array("media"=> new \CURLFile($real_path));
// 發(fā)送請(qǐng)求
$res = $this->post($url, $file_data, false);
var_dump($res);
如果不出錯(cuò)最后返回的信息為:
array(1) {
["url"]=>
string(125) "xxxxx"
}
post函數(shù):
private function post($url, $data = [], $json_encode=true) {
$curl = curl_init(); // 啟動(dòng)一個(gè)CURL會(huì)話
curl_setopt($curl, CURLOPT_URL, $url); // 要訪問(wèn)的地址
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 對(duì)認(rèn)證證書來(lái)源的檢查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 從證書中檢查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模擬用戶使用的瀏覽器
if ($data != null) {
curl_setopt($curl, CURLOPT_POST, 1); // 發(fā)送一個(gè)常規(guī)的Post請(qǐng)求
// curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的數(shù)據(jù)包
if(gettype($data)==="string") {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
else {
if ($json_encode) {
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
} else {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
}
}
curl_setopt($curl, CURLOPT_TIMEOUT, 300); // 設(shè)置超時(shí)限制防止死循環(huán)
curl_setopt($curl, CURLOPT_HEADER, 0); // 顯示返回的Header區(qū)域內(nèi)容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 獲取的信息以文件流的形式返回
$res = curl_exec($curl); // 執(zhí)行操作
curl_close($curl);
$data = json_decode($res, true);
if($data==NULL) {
return $res;
}
else {
return $data;
}
}
json_encode為false的話,就不會(huì)進(jìn)行json_encode。比如上面上傳圖片傳入的是一個(gè)CURLFile,如果json_encode就會(huì)上傳失敗。
AccessToken的獲取和處理
官方文檔中建議建立一個(gè)刷新機(jī)制,不要每次使用access_token的時(shí)候都去重新獲取,詳情請(qǐng)仔細(xì)閱讀官方文檔。
請(qǐng)求地址說(shuō)明:
https請(qǐng)求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
參數(shù)為grant_type、appid和secret,具體信息可查看官方文檔。

accessToken處理示意圖
代碼:
設(shè)置cache和相關(guān)信息:
public function __construct() {
parent::__construct();
$this->load->driver(
'cache',
array('adapter' => 'apc', 'backup' => 'file', 'key_prefix' => 'wechat_')
);
// 公眾號(hào)appid 和 appsecrect
$this->appid = 'xxx';
$this->secret = 'xxx';
}
獲取accessToken:
private function getAccessToken() {
$appid = $this->appid;
$secret = $this->secret;
// 設(shè)置cache key,這里是 wechat_[appid]_access_token,保存成功可以到/webpath/application/cache查看
// 如果想用其他方式保存也可以做相應(yīng)更改
$key = $this->appid.'_access_token';
// 如果cache中沒(méi)有accessToken或者已過(guò)期,重新獲取或刷新
if (!$accessToken = $this->cache->get($key)) {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}";
$res = $this->post($url);
$accessToken = $res['access_token'];
// 保存accessToken
$this->cache->save($key, $accessToken, $res['expires_in']);
}
return $accessToken;
}