wechat = new Hdwechat($config); $this->cf_app = $config['cf_app']; if($config){ $this->log_file = "wechat_msg_{$config['appid']}.log"; } } function init_wechat($config){ $this->wechat->init($config); } /** * 初始化服务号消息模板 * @param $id (模板ID) * @param $appage (小程序跳转页) * @param $appid (小程序appid, 默认当前小程序) * @param $url (跳转外链) */ function init_template($id, $appage = '', $appid = '', $url = ''){ $this->temp_id = $id; $this->temp_appage = $appage; $this->temp_appid = $appid; $this->temp_url = $url; } /** * 发送服务号消息 * @param $openid * @param $data (消息主体) * @return mixed */ function send_oa($openid, $data){ $access_token = $this->wechat->access_token(); if(!$access_token){ debug_log("[error] ". __FUNCTION__ . ": not access_token; openid={$openid}", $this->log_file); return false; } $pre_url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='; $url = $pre_url . $access_token; $post = array( 'touser' => $openid, 'template_id' => $this->temp_id, 'url' => $this->temp_url ? $this->temp_url : '', 'data' => $data ); if($this->temp_appage){ $post['miniprogram'] =array( 'appid' => $this->temp_appid, 'pagepath' => $this->temp_appage ); } list($code, $res) = $this->curl_json($url, $post); $ret = json_decode($res, true); if(40001 == $ret['errcode']){//token过期,重置后请求 $url = $pre_url . $this->wechat->access_token(true); list($code, $res) = $this->curl_json($url, $post); $ret = json_decode($res, true); } if($ret['errcode'] != 0){ debug_log("[error] ". __FUNCTION__ . ": openid={$openid}", $this->log_file); return false; } return true; } /** * 发送小程序消息 * @param $openid * @param $data * @return bool */ function send_app($openid, $data){ $access_token = $this->wechat->access_token(); if(!$access_token){ debug_log("[error] ". __FUNCTION__ . ": not access_token; openid={$openid}", $this->log_file); return false; } $pre_url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token="; $url = $pre_url.$access_token; $form_id = $this->pop_formid($openid); if(!$form_id){ debug_log("[error] ". __FUNCTION__ . ": not form_id; openid={$openid}", $this->log_file); return false; } $post = array( 'touser' => $openid, 'template_id' => $this->temp_id, 'form_id' => $form_id, 'page' => $this->temp_appage, 'data' => $data ); list($code, $res) = $this->curl_json($url, $post); $ret = json_decode($res, true); if(40001 == $ret['errcode']){//token过期,重置后请求 $url = $pre_url . $this->wechat->access_token(true); list($code, $res) = $this->curl_json($url, $post); $ret = json_decode($res, true); } if($ret['errcode'] != 0){ debug_log("[error] ". __FUNCTION__ . ": from_id={$form_id}, openid={$openid}", $this->log_file); return false; } return true; } /** * 发送小程序订阅通知 * @param $openid * @param $data * @return bool */ function send_appsub($openid, $data){ $access_token = $this->wechat->access_token(); if(!$access_token){ debug_log("[error] ". __FUNCTION__ . ":not access_token; openid={$openid}", $this->log_file); return false; } $pre_url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="; $url = $pre_url.$access_token; $post = array( 'touser' => $openid, 'template_id' => $this->temp_id, 'page' => $this->temp_appage, 'data' => $data ); list($code, $res) = $this->curl_json($url, $post); $ret = json_decode($res, true); if(40001 == $ret['errcode']){//token过期,重置后请求 $url = $pre_url . $this->wechat->access_token(true); list($code, $res) = $this->curl_json($url, $post); $ret = json_decode($res, true); } if($ret['errcode'] != 0){ debug_log("[error] ". __FUNCTION__ . ":openid={$openid}", $this->log_file); return false; } return true; } /** * 收集新的form_id * @param $openid (用户ID) * @param $form_id * @param $expire (到期时间戳) * @return bool */ public function push_formid($openid, $form_id, $expire = 0){ //从redis获取 $r = &load_cache('redis'); $redis = $r->redis(); $key = "wechat_formid_{$this->wechat->appid}_{$openid}"; $long = 7 * 24 * 3600; !$expire && $expire = time() + $long; $form = array('id' => $form_id, 'expire' => $expire); $ret = $redis->lPush($key, json_encode($form)); $len = $redis->lLen($key); //限制redis列表长度,去掉旧的 $ret && $len > self::$max_form && $redis->rPop($key); //更新redis有效期 $redis->expire($key, $long); return false; } /** * 获取formid数量 * @param $openid * @return mixed */ function count_formid($openid){ $key = "wechat_formid_{$this->wechat->appid}_{$openid}"; $r = &load_cache('redis'); $redis = $r->redis(); return $redis->lLen($key); } /** * 查看 * @param $openid * @return mixed */ function view_formid($openid){ $key = "wechat_formid_{$this->wechat->appid}_{$openid}"; $r = &load_cache('redis'); $redis = $r->redis(); return $redis->lRange($key, 0, -1); } /** * 弹出fromid * @param $openid * @return string */ public function pop_formid($openid){ //从redis获取 $r = &load_cache('redis'); $redis = $r->redis(); $key = "wechat_formid_{$this->wechat->appid}_{$openid}"; $now = time(); while(1) {//循环获取fromid $form = $redis->rPop($key); $form && $form = json_decode($form, true); if(!$form){break;} if($form['expire'] >= $now){ return $form['id']; } } return ''; } /** * @param $url * @param $data * @return array */ private function curl_json($url, $data){ $data = urldecode(json_encode($data)); debug_log("[info] ". __FUNCTION__ . ":url={$url}, data={$data}", $this->log_file); $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //https if (strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); } curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen($data) ) ); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); debug_log("[info] ". __FUNCTION__ . ":httpcode={$httpCode}, response={$response}", $this->log_file); return array($httpCode, $response); } }