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]); } }