358 lines
14 KiB
PHP
358 lines
14 KiB
PHP
<?php
|
||
namespace app\common;
|
||
use think\Cache;
|
||
use think\Db;
|
||
|
||
class Wechat
|
||
{
|
||
protected $sAppID; //= 'wx03cb871b66e34e10';
|
||
protected $sAppSecret; //= 'f59ccaf00383dcfab489292c4697620a';
|
||
protected $sWechatAccessToken = 'wechat_access_token';
|
||
protected $timeout;
|
||
protected $proxy;
|
||
|
||
|
||
public function __construct(\think\Request $request = null) {
|
||
|
||
}
|
||
|
||
/**
|
||
* CURL 发送请求获取Token
|
||
* @param $appid AppID(小程序ID)
|
||
* @param $secret AppSecret(小程序密钥)
|
||
*/
|
||
|
||
private function getAccessToken() {
|
||
//Token缓存值
|
||
$sToken = Cache::get($this->sWechatAccessToken.'_'.$this->sAppID);
|
||
//判断缓存是否存在
|
||
if (!$sToken) { //不存在
|
||
//组装接口地址
|
||
$sUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
|
||
. $this->sAppID . "&secret=" . $this->sAppSecret;
|
||
|
||
$curl = curl_init();
|
||
curl_setopt($curl, CURLOPT_URL, $sUrl);
|
||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||
curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
|
||
$result = curl_exec($curl);
|
||
//请求失败
|
||
if (curl_errno($curl)){
|
||
$this->sError = curl_errno($curl);
|
||
curl_close($curl);
|
||
return FALSE;
|
||
}
|
||
$result = json_decode($result, true);
|
||
if (!empty($result['access_token'])) {
|
||
$sToken = $result['access_token'];
|
||
Cache::set($this->sWechatAccessToken.'_'.$this->sAppID, $sToken, 7000); // 有效期7200秒
|
||
}
|
||
curl_close($curl);
|
||
}
|
||
return $sToken;
|
||
}
|
||
|
||
/**
|
||
* CURL 发送请求上传永久素材
|
||
* @param $sToken Token
|
||
* @param $sPath 图片地址
|
||
*/
|
||
public function uploadMaterial($aParam = []) {
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
//图片地址
|
||
$sPath = empty($aParam['image_url']) ? '' : $aParam['image_url'];
|
||
if(empty($sPath)){
|
||
return json_encode(['status' => 2,'msg' => 'Please choose to upload materials']);
|
||
}
|
||
|
||
// 获取微信公众号APPID和APPKEY
|
||
$this->sAppID = empty($aParam['wechat_app_id']) ? '' : $aParam['wechat_app_id'];
|
||
$this->sAppSecret = empty($aParam['wechat_app_secret']) ? '' : $aParam['wechat_app_secret'];
|
||
if(empty($this->sAppID) || empty($this->sAppSecret)){
|
||
return json_encode(['status' => 2,'msg' => 'Please configure the AppID and AppSecret']);
|
||
}
|
||
|
||
$sType = empty($aParam['type']) ? 'image' : $aParam['type'];//文件类型
|
||
|
||
// 验证文件有效性
|
||
if (!file_exists($sPath)) {
|
||
return json_encode(['status' => 3,'msg' => 'The material does not exist'.$sPath]);
|
||
}
|
||
if (!is_readable($sPath)) {
|
||
return json_encode(['status' => 3,'msg' => 'The material is unreadable']);
|
||
}
|
||
if (filesize($sPath) > 10 * 1024 * 1024) {
|
||
return json_encode(['status' => 4,'msg' => 'The material cannot exceed 10MB']);
|
||
}
|
||
|
||
//获取Token
|
||
$sToken = $this->getAccessToken();
|
||
if (empty($sToken)) {
|
||
return json_encode(['status' => 5, 'msg' => 'Failed to obtain access_token']);
|
||
}
|
||
|
||
//CURL 请求接口
|
||
//文件参数
|
||
$data = [
|
||
'media' => new \CURLFile(
|
||
realpath($sPath),
|
||
mime_content_type($sPath), // 自动检测MIME类型
|
||
basename($sPath) // 上传后的文件名
|
||
), // 关键:使用CURLFile对象
|
||
];
|
||
$sUrl = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={$sToken}&type={$sType}";
|
||
$curl = curl_init();
|
||
curl_setopt($curl, CURLOPT_URL, $sUrl);
|
||
curl_setopt($curl, CURLOPT_POST, true); //设置为POST方式
|
||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE) ; // 获取数据返回
|
||
curl_setopt($curl, CURLOPT_PROXY,$this->proxy);
|
||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,true);
|
||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,false);
|
||
//执行
|
||
$response = curl_exec($curl);
|
||
|
||
//请求失败
|
||
if (curl_errno($curl)){
|
||
curl_close($curl);
|
||
return json_encode(['status' => 6,'msg' => "Network request failed: " . curl_errno($curl)]);
|
||
}
|
||
curl_close($curl);//关闭请求
|
||
|
||
//获取返回结果
|
||
$response = json_decode($response, true);
|
||
if (!empty($response['errcode']) && $response['errcode'] != 0) {
|
||
return json_encode(['status' => 7,'msg' => "WeChat interface error: [{$response['errcode']}] {$response['errmsg']}"]);
|
||
}
|
||
|
||
//插入数据库
|
||
if(empty($response['media_id'])){
|
||
return json_encode(['status' => 8,'msg' => "Unable to obtain uploaded materials"]);
|
||
}
|
||
return json_encode(['status' => 1,'msg' => 'success','data' => $response]);
|
||
}
|
||
|
||
/**
|
||
* CURL 发送请求到 微信公众号
|
||
* @param $messages 内容
|
||
* @param $model 模型类型
|
||
*/
|
||
private function curlWechatApi($sUrl = '',$sJsonData = ''){
|
||
|
||
//发送CURL请求
|
||
$curl = curl_init();
|
||
curl_setopt($curl, CURLOPT_URL, $sUrl);
|
||
curl_setopt($curl, CURLOPT_POST, true);
|
||
curl_setopt($curl, CURLOPT_POSTFIELDS, $sJsonData);
|
||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||
'Content-Type: application/json',
|
||
'Content-Length: ' . strlen($sJsonData)
|
||
]);
|
||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); // 关闭SSL验证(生产环境建议开启)
|
||
$response = curl_exec($curl);
|
||
//请求失败
|
||
if (curl_errno($curl)){
|
||
curl_close($curl);
|
||
return ['status' => 2,'msg' => "Network request failed: " . curl_errno($curl)];
|
||
}
|
||
curl_close($curl);//关闭请求
|
||
|
||
// 数据处理
|
||
$response = json_decode($response, true);
|
||
if (!empty($response['errcode'])) {
|
||
return ['status' => 3, 'msg' => 'WeChat interface error:'.$response['errmsg'] ?? $response['errcode']];
|
||
}
|
||
|
||
return ['status' => 1,'msg' => 'success','data' => $response];
|
||
}
|
||
|
||
/**
|
||
* CURL 添加文章到草稿箱
|
||
* @param $sToken Token
|
||
* @param $sPath 图片地址
|
||
*/
|
||
public function addDraft($aParam = []){
|
||
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
//文章ID
|
||
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
|
||
if(empty($iArticleId)){
|
||
return json_encode(['status' => 2,'msg' => 'article_id is empty']);
|
||
}
|
||
|
||
//生成模版内容
|
||
$sContent = empty($aParam['content']) ? '' : $aParam['content'];
|
||
if(empty($sContent)){
|
||
return json_encode(['status' => 2,'msg' => 'The published content is empty']);
|
||
}
|
||
|
||
// 获取微信公众号APPID和APPKEY
|
||
$this->sAppID = empty($aParam['wechat_app_id']) ? '' : $aParam['wechat_app_id'];
|
||
$this->sAppSecret = empty($aParam['wechat_app_secret']) ? '' : $aParam['wechat_app_secret'];
|
||
if(empty($this->sAppID) || empty($this->sAppSecret)){
|
||
return json_encode(['status' => 2,'msg' => 'Please configure the AppID and AppSecret']);
|
||
}
|
||
|
||
//获取Token
|
||
$sToken = $this->getAccessToken();
|
||
if (empty($sToken)) {
|
||
return json_encode(['status' => 5, 'msg' => 'Failed to obtain access_token']);
|
||
}
|
||
//发送CURL请求
|
||
$sUrl = "https://api.weixin.qq.com/cgi-bin/draft/add?access_token={$sToken}";
|
||
//参数组装
|
||
$sJsonData = json_encode([
|
||
'articles' => [$aParam]
|
||
], JSON_UNESCAPED_UNICODE);
|
||
$aCurlResult = $this->curlWechatApi($sUrl,$sJsonData);
|
||
$response = empty($aCurlResult['data']) ? [] : $aCurlResult['data'];
|
||
//判断是否推送成功
|
||
if(empty($response['media_id'])){
|
||
return json_encode(['status' => 5,'msg' => "Unable to obtain the uploaded draft"]);
|
||
}
|
||
return json_encode(['status' => 1,'msg' => 'Upload draft box successfully','data' => $response]);
|
||
}
|
||
|
||
/**
|
||
* CURL 获取草稿箱的文章
|
||
* @param $sToken Token
|
||
* @param media_id string 微信公众号media_id
|
||
*/
|
||
public function getDraft($aParam = []){
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
$sMediaId = empty($sMediaId) ? $aParam['media_id'] : $sMediaId;
|
||
if(empty($sMediaId)){
|
||
return json_encode(['status' => 2, 'msg' => 'Parameter: media_id cannot be empty']);
|
||
}
|
||
|
||
//获取微信公众号APPID和APPKEY
|
||
$this->sAppID = empty($aParam['wechat_app_id']) ? '' : $aParam['wechat_app_id'];
|
||
$this->sAppSecret = empty($aParam['wechat_app_secret']) ? '' : $aParam['wechat_app_secret'];
|
||
if(empty($this->sAppID) || empty($this->sAppSecret)){
|
||
return json_encode(['status' => 2,'msg' => 'Please configure the AppID and AppSecret']);
|
||
}
|
||
|
||
//获取Token
|
||
$sToken = $this->getAccessToken();
|
||
if (empty($sToken)) {
|
||
return json_encode(['status' => 4, 'msg' => 'Failed to obtain access_token']);
|
||
}
|
||
|
||
//CURL请求
|
||
$sUrl = "https://api.weixin.qq.com/cgi-bin/draft/get?access_token={$sToken}";
|
||
//参数组装
|
||
$sJsonData = json_encode([
|
||
'media_id' => $sMediaId
|
||
], JSON_UNESCAPED_UNICODE);
|
||
//发送CURL请求
|
||
$aCurlResult = $this->curlWechatApi($sUrl,$sJsonData);
|
||
$iStatus = empty($aCurlResult['status']) ? 0 : $aCurlResult['status'];
|
||
$sMsg = empty($aCurlResult['msg']) ? 'Acquisition failed': $aCurlResult['msg'];
|
||
if($iStatus != 1){
|
||
return json_encode(['status' => 5,'msg' => $sMsg]);
|
||
}
|
||
$response = empty($aCurlResult['data']) ? [] : $aCurlResult['data'];
|
||
return json_encode(['status' => 1,'msg' => 'Successfully obtained draft','data' => $response['news_item'] ?? []]);
|
||
}
|
||
|
||
/**
|
||
* CURL 发布草稿箱的文章
|
||
* @param $sToken Token
|
||
* @param article_id int 文章ID
|
||
*/
|
||
public function publishDraft($aParam = []){
|
||
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
//必填参数验证
|
||
$sMediaId = empty($aParam['media_id']) ? '' : $aParam['media_id'];
|
||
if(empty($sMediaId)){
|
||
return json_encode(['status' => 2, 'msg' => 'Please select the WeChat official account to push']);
|
||
}
|
||
//获取微信公众号APPID和APPKEY
|
||
$this->sAppID = empty($aParam['wechat_app_id']) ? '' : $aParam['wechat_app_id'];
|
||
$this->sAppSecret = empty($aParam['wechat_app_secret']) ? '' : $aParam['wechat_app_secret'];
|
||
if(empty($this->sAppID) || empty($this->sAppSecret)){
|
||
return json_encode(['status' => 2,'msg' => 'Please configure the AppID and AppSecret']);
|
||
}
|
||
|
||
//获取Token
|
||
$sToken = $this->getAccessToken();
|
||
if (empty($sToken)) {
|
||
return json_encode(['status' => 6, 'msg' => 'Failed to obtain access_token']);
|
||
}
|
||
//验证公众号是否存在该文章
|
||
$aInfo = json_decode($this->getDraft($aParam),true);
|
||
$iStatus = empty($aInfo['status']) ? 0 : $aInfo['status'];
|
||
if($iStatus != 1){
|
||
return json_encode($aInfo);
|
||
}
|
||
|
||
//CURL请求
|
||
$sUrl = "https://api.weixin.qq.com/cgi-bin/freepublish/submit?access_token={$sToken}";
|
||
//参数组装
|
||
$sJsonData = json_encode([
|
||
'media_id' => $sMediaId
|
||
], JSON_UNESCAPED_UNICODE);
|
||
//发送CURL请求
|
||
$aCurlResult = $this->curlWechatApi($sUrl,$sJsonData);
|
||
if($aCurlResult['status'] != 1){
|
||
return $aCurlResult;
|
||
}
|
||
$response = empty($aCurlResult['data']) ? [] : $aCurlResult['data'];
|
||
//判断是否推送成功
|
||
if(empty($response['publish_id'])){
|
||
return json_encode(['status' => 9,'msg' => "The publish_id of the published draft was not obtained"]);
|
||
}
|
||
return json_encode(['status' => 1,'msg' => 'Draft box article successfully published','data' => $response]);
|
||
}
|
||
|
||
/**
|
||
* CURL 查询文章的发布状态
|
||
* @param $sToken Token
|
||
* @param article_id array 文章ID
|
||
*/
|
||
public function queryStatus($aParam =[]){
|
||
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
$sPublishId = empty($aParam['publish_id']) ? '' : $aParam['publish_id'];
|
||
if(empty($sPublishId)){
|
||
return json_encode(['status' => 2, 'msg' => 'Publish_id cannot be empty']);
|
||
}
|
||
//获取微信公众号APPID和APPKEY
|
||
$this->sAppID = empty($aParam['wechat_app_id']) ? '' : $aParam['wechat_app_id'];
|
||
$this->sAppSecret = empty($aParam['wechat_app_secret']) ? '' : $aParam['wechat_app_secret'];
|
||
if(empty($this->sAppID) || empty($this->sAppSecret)){
|
||
return json_encode(['status' => 2,'msg' => 'Please configure the AppID and AppSecret']);
|
||
}
|
||
|
||
//获取Token
|
||
$sToken = $this->getAccessToken();
|
||
if (empty($sToken)) {
|
||
return json_encode(['status' => 3, 'msg' => 'Failed to obtain access_token']);
|
||
}
|
||
|
||
//CURL请求
|
||
$sUrl = "https://api.weixin.qq.com/cgi-bin/freepublish/get?access_token={$sToken}";
|
||
//参数组装
|
||
$sJsonData = json_encode([
|
||
'publish_id' => $sPublishId
|
||
], JSON_UNESCAPED_UNICODE);
|
||
//发送CURL请求
|
||
$aCurlResult = $this->curlWechatApi($sUrl,$sJsonData);
|
||
$response = empty($aCurlResult['data']) ? [] : $aCurlResult['data'];
|
||
if(empty($response)){
|
||
return json_encode(['status' => 4,'msg' => 'Query failed']);
|
||
}
|
||
return json_encode(['status' => 1,'msg' => 'query was successful','data' => $response]);
|
||
}
|
||
}
|