完整的微信介面類 (轉)
阿新 • • 發佈:2018-11-23
本類包含了微信官方公佈的所有可使用的介面,包括了普通介面及高階介面,具體哪些介面可用還是要看您的賬號級別。 具體介面如下: 基礎支援 接收訊息 傳送訊息 使用者管理 自定義選單 推廣支援 Weixin JS介面 程式碼如下: <?php class WeiXin { const MSG_TYPE_TEXT = 'text'; const MSG_TYPE_IMAGE = 'image'; const MSG_TYPE_VOICE = 'voice'; const MSG_TYPE_VIDEO = 'video';const MSG_TYPE_LOCATION = 'location'; const MSG_TYPE_LINK = 'link'; const MSG_TYPE_EVENT = 'event'; const MSG_EVENT_SUBSCRIBE = 'subscribe'; const MSG_EVENT_UNSUBSCRIBE = 'unsubscribe'; const MSG_EVENT_SCAN = 'scan'; const MSG_EVENT_LOCATION = 'LOCATION'; const MSG_EVENT_CLICK = 'CLICK';const REPLY_TYPE_TEXT = 'text'; const REPLY_TYPE_IMAGE = 'image'; const REPLY_TYPE_VOICE = 'voice'; const REPLY_TYPE_VIDEO = 'video'; const REPLY_TYPE_MUSIC = 'music'; const REPLY_TYPE_NEWS = 'news'; const MEDIA_TYPE_IMAGE = "image"; const MEDIA_TYPE_VOICE = 'voice'; const MEDIA_TYPE_VIDEO = 'video';const MEDIA_TYPE_THUMB = 'thumb'; const SCOPE_REDIRECT = "snsapi_base"; const SCOPE_POP = "snsapi_userinfo"; private static $links = array( 'message' => "https://api.weixin.qq.com/cgi-bin/message/custom/send", 'group_create' => "https://api.weixin.qq.com/cgi-bin/groups/create", 'group_get' => "https://api.weixin.qq.com/cgi-bin/groups/get", 'group_getid' => "https://api.weixin.qq.com/cgi-bin/groups/getid", 'group_rename' => "https://api.weixin.qq.com/cgi-bin/groups/update", 'group_move' => "https://api.weixin.qq.com/cgi-bin/groups/members/update", 'user_info' => "https://api.weixin.qq.com/cgi-bin/user/info", 'user_get' => 'https://api.weixin.qq.com/cgi-bin/user/get', 'menu_create' => 'https://api.weixin.qq.com/cgi-bin/menu/create', 'menu_get' => 'https://api.weixin.qq.com/cgi-bin/menu/get', 'menu_delete' => 'https://api.weixin.qq.com/cgi-bin/menu/delete', 'qrcode' => 'https://api.weixin.qq.com/cgi-bin/qrcode/create', 'showqrcode' => 'https://mp.weixin.qq.com/cgi-bin/showqrcode', 'media_download' => 'http://file.api.weixin.qq.com/cgi-bin/media/get', 'media_upload' => 'http://file.api.weixin.qq.com/cgi-bin/media/upload', 'oauth_code' => 'https://open.weixin.qq.com/connect/oauth2/authorize', 'oauth_access_token' => 'https://api.weixin.qq.com/sns/oauth2/access_token', 'oauth_refresh' => 'https://api.weixin.qq.com/sns/oauth2/refresh_token', 'oauth_userinfo' => 'https://api.weixin.qq.com/sns/userinfo' ); private static $errors = array( '-1' => '系統繁忙', '0' => '請求成功', '40001' => '獲取access_token時AppSecret錯誤,或者access_token無效', '40002' => '不合法的憑證型別', '40003' => '不合法的OpenID', '40004' => '不合法的媒體檔案型別', '40005' => '不合法的檔案型別', '40006' => '不合法的檔案大小', '40007' => '不合法的媒體檔案id', '40008' => '不合法的訊息型別', '40009' => '不合法的圖片檔案大小', '40010' => '不合法的語音檔案大小', '40011' => '不合法的視訊檔案大小', '40012' => '不合法的縮圖檔案大小', '40013' => '不合法的APPID', '40014' => '不合法的access_token', '40015' => '不合法的選單型別', '40016' => '不合法的按鈕個數', '40017' => '不合法的按鈕個數', '40018' => '不合法的按鈕名字長度', '40019' => '不合法的按鈕KEY長度', '40020' => '不合法的按鈕URL長度', '40021' => '不合法的選單版本號', '40022' => '不合法的子選單級數', '40023' => '不合法的子選單按鈕個數', '40024' => '不合法的子選單按鈕型別', '40025' => '不合法的子選單按鈕名字長度', '40026' => '不合法的子選單按鈕KEY長度', '40027' => '不合法的子選單按鈕URL長度', '40028' => '不合法的自定義選單使用使用者', '40029' => '不合法的oauth_code', '40030' => '不合法的refresh_token', '40031' => '不合法的openid列表', '40032' => '不合法的openid列表長度', '40033' => '不合法的請求字元,不能包含\uxxxx格式的字元', '40035' => '不合法的引數', '40038' => '不合法的請求格式', '40039' => '不合法的URL長度', '40050' => '不合法的分組id', '40051' => '分組名字不合法', '41001' => '缺少access_token引數', '41002' => '缺少appid引數', '41003' => '缺少refresh_token引數', '41004' => '缺少secret引數', '41005' => '缺少多媒體檔案資料', '41006' => '缺少media_id引數', '41007' => '缺少子選單資料', '41008' => '缺少oauth code', '41009' => '缺少openid', '42001' => 'access_token超時', '42002' => 'refresh_token超時', '42003' => 'oauth_code超時', '43001' => '需要GET請求', '43002' => '需要POST請求', '43003' => '需要HTTPS請求', '43004' => '需要接收者關注', '43005' => '需要好友關係', '44001' => '多媒體檔案為空', '44002' => 'POST的資料包為空', '44003' => '圖文訊息內容為空', '44004' => '文字訊息內容為空', '45001' => '多媒體檔案大小超過限制', '45002' => '訊息內容超過限制', '45003' => '標題欄位超過限制', '45004' => '描述欄位超過限制', '45005' => '連結欄位超過限制', '45006' => '圖片連結欄位超過限制', '45007' => '語音播放時間超過限制', '45008' => '圖文訊息超過限制', '45009' => '介面呼叫超過限制', '45010' => '建立選單個數超過限制', '45015' => '回覆時間超過限制', '45016' => '系統分組,不允許修改', '45017' => '分組名字過長', '45018' => '分組數量超過上限', '46001' => '不存在媒體資料', '46002' => '不存在的選單版本', '46003' => '不存在的選單資料', '46004' => '不存在的使用者', '47001' => '解析JSON/XML內容錯誤', '48001' => 'api功能未授權', '50001' => '使用者未授權該api' ); private static $debug = false; private $token; private $postStr; private $postObj; private $appid; private $appsecret; private $access_token; private $valid = 0; /** * @param $token * @param null $appid * @param null $appsecret * @param bool $debug */ public function __construct($token, $appid = null, $appsecret = null, $debug = false) { $this->token = $token; if (!empty($_GET) && $this->checkSignature()) $this->handleRequest(); $this->appid = $appid; $this->appsecret = $appsecret; self::$debug = $debug; } /** * 檢查簽名 * * @return bool */ private function checkSignature() { if (!isset($_GET['signature']) || !isset($_GET['timestamp']) || !isset($_GET['nonce'])) return false; $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $tmpArr = array($this->token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); if ($tmpStr == $signature) return true; else return false; } /** * 處理請求 */ private function handleRequest() { if (isset($_GET['echostr'])) { echo $_GET['echostr']; exit; } else { $this->postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if (!empty($this->postStr)) { $this->postObj = simplexml_load_string($this->postStr, 'SimpleXMLElement', LIBXML_NOCDATA); } else { Log::simpleappend('fail', $this->postStr); exit; } } } /** * 獲取高階介面的access_token * * @return bool */ private function getAccessToken() { if ($this->appid && $this->appsecret) { if ($this->valid <= time()) { $access = json_decode(Tools::curl("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appid}&secret={$this->appsecret}")); if (isset($access->access_token) && isset($access->expires_in)) { $this->access_token = $access->access_token; $this->valid = time() + $access->expires_in; } else return false; } return true; } return false; } /** * 獲取請求中的收信人OpenId,一般為公眾賬號自身 * * @return mixed */ public function getToUserName() { return $this->postObj->ToUserName; } /** * 請求中的發信人OpenId * * @return mixed */ public function getFromUserName() { return $this->postObj->FromUserName; } /** * 獲取Object格式的訊息內容 * * @return mixed */ public function getPostObj() { return $this->postObj; } /** * 獲取字串格式的訊息內容 * * @return mixed */ public function getPostStr() { return $this->postStr; } /** * 獲取訊息ID * * @return mixed */ public function getMsgId() { return $this->postObj->MsgId; } /** * 訊息建立時間 * * @return string */ public function getCreateTime() { return strval($this->postObj->CreateTime); } //獲取訊息型別 public function getMsgType() { return $this->postObj->MsgType; } /** * 獲取事件推送的時間型別,非事件的訊息返回false * * @return mixed */ public function getEvent() { if ($this->postObj->MsgType == self::MSG_TYPE_EVENT) { return $this->postObj->Event; } return false; } /** * 是否為文字訊息 * * @return bool */ public function isTextMessage() { return $this->postObj->MsgType == self::MSG_TYPE_TEXT; } /** * 是否為圖片訊息 * * @return bool */ public function isImageMessage() { return $this->postObj->MsgType == self::MSG_TYPE_IMAGE; } /** * 是否為語音訊息 * * @return bool */ public function isVoiceMessage() { return $this->postObj->MsgType == self::MSG_TYPE_VOICE; } /** * 是否為視訊訊息 * * @return bool */ public function isVideoMessage() { return $this->postObj->MsgType == self::MSG_TYPE_VIDEO; } /** * 是否為地理位置訊息 * * @return bool */ public function isLocationMessage() { return $this->postObj->MsgType == self::MSG_TYPE_LOCATION; } /** * 是否為連結訊息 * * @return bool */ public function isLinkMessage() { return $this->postObj->MsgType == self::MSG_TYPE_LINK; } /** * 是否為普通關注事件 * * @return bool */ public function isEventSubscribe() { return $this->postObj->MsgType == self::MSG_TYPE_EVENT && $this->postObj->Event == self::MSG_EVENT_SUBSCRIBE && !isset($this->postObj->EventKey); } /** * 是否為取消關注事件 * * @return bool */ public function isEventUnSubscribe() { return $this->postObj->MsgType == self::MSG_TYPE_EVENT && $this->postObj->Event == self::MSG_EVENT_UNSUBSCRIBE; } /** * 是否為掃描二維碼關注事件 * * @return bool */ public function isEventScanSubscript() { return $this->postObj->MsgType == self::MSG_TYPE_EVENT && $this->postObj->Event == self::MSG_EVENT_SUBSCRIBE && isset($this->postObj->EventKey); } /** * 是否為已關注掃描二維碼事件 * * @return bool */ public function isEventScan() { return $this->postObj->MsgType == self::MSG_TYPE_EVENT && $this->postObj->Event == self::MSG_EVENT_SCAN; } /** * 是否為上報地理位置事件 * * @return bool */ public function isEventLocation() { return $this->postObj->MsgType == self::MSG_TYPE_EVENT && $this->postObj->Event == self::MSG_EVENT_LOCATION; } /** * 是否為選單點選事件 * * @return bool */ public function isEventClick() { return $this->postObj->MsgType == self::MSG_TYPE_EVENT && $this->postObj->Event == self::MSG_EVENT_CLICK; } /** * 獲取文字訊息內容 * * @return string */ public function requestText() { return strval($this->postObj->Content); } /** * 獲取圖片訊息內容 * * @return array */ public function requestImage() { $image = array(); $image['PicUrl'] = strval($this->postObj->PicUrl); $image['MediaId'] = strval($this->postObj->MediaId); return $image; } /** * 獲取語音訊息內容,可能包含語音識別結果 * * @return array */ public function requestVoice() { $voice = array(); $voice['MediaId'] = $this->postObj->MediaId; $voice['Format'] = $this->postObj->Format; if (isset($this->postObj->Recognition)) $voice['Recognition'] = $this->postObj->Recognition; return $voice; } /** * 獲取視訊訊息內容 * * @return array */ public function requestVideo() { $video = array(); $video['MediaId'] = $this->postObj->MediaId; $video['ThumbMediaId'] = $this->postObj->ThumbMediaId; return $video; } /** * 獲取地理位置訊息內容 * * @return array */ public function requestLocation() { $location = array(); $location['Location_X'] = strval($this->postObj->Location_X); $location['Location_Y'] = strval($this->postObj->Location_Y); $location['Scale'] = strval($this->postObj->Scale); $location['Label'] = strval($this->postObj->Label); return $location; } /** * 獲取連結訊息內容 * * @return array */ public function requestLink() { $link = array(); $link['Title'] = strval($this->postObj->Title); $link['Description'] = strval($this->postObj->Description); $link['Url'] = strval($this->postObj->Url); return $link; } /** * 獲取掃描二維碼事件內容 * * @return array */ public function requestEventScan() { $info = array(); $info['EventKey'] = $this->postObj->EventKey; $info['Ticket'] = $this->postObj->Ticket; $info['Scene_Id'] = str_replace('qrscene_', '', $this->postObj->EventKey); return $info; } /** * 獲取上報地理位置事件內容 * * @return array */ public function requestEventLocation() { $location = array(); $location['Latitude'] = $this->postObj->Latitude; $location['Longitude'] = $this->postObj->Longitude; $location['Precision'] = $this->postObj->Precision; return $location; } /** * 獲取選單點選事件內容 * * @return string */ public function requestEventClick() { return strval($this->postObj->EventKey); } /** * GET方法 * * @param $link * * @return mixed */ private static function get($link) { if (self::$debug) Log::out("weixin_debug", 'I', "get:" . $link); return json_decode(Tools::curl($link)); } /** * POST方法 * * @param $link * @param $data * * @return mixed */ private static function post($link, $data) { if (self::$debug) Log::out("weixin_debug", 'I', "post:", $link . ":" . serialize($data)); return json_decode(Tools::curl($link, 'POST', $data)); } /** * 向微信伺服器ECHO內容 * * @param $content */ private static function response($content) { if (self::$debug) Log::out("weixin_debug", 'I', 'echo:' . $content); echo $content; } /** * 獲取錯誤程式碼中文描述 * * @param $errorcode * * @return mixed */ public static function error($errorcode) { return self::$errors[$errorcode]; } /** * 回覆文字訊息 * * @param $content */ public function responseTextMessage($content) { $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; $resultStr = sprintf($textTpl, $this->postObj->FromUserName, $this->postObj->ToUserName, time(), self::REPLY_TYPE_TEXT, $content); if (!headers_sent()) header('Content-Type: application/xml; charset=utf-8'); self::response($resultStr); } /** * 回覆圖片訊息 * * @param $mediaid */ public function responseImageMessage($mediaid) { $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Image> <MediaId><![CDATA[%s]]></MediaId> </Image> </xml>"; $resultStr = sprintf($textTpl, $this->postObj->FromUserName, $this->postObj->ToUserName, time(), self::REPLY_TYPE_IMAGE, $mediaid); if (!headers_sent()) header('Content-Type: application/xml; charset=utf-8'); self::response($resultStr); } /** * 回覆語音訊息 * * @param $mediaid */ public function responseVoiceMessage($mediaid) { $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Voice> <MediaId><![CDATA[%s]]></MediaId> </Voice> </xml>"; $resultStr = sprintf($textTpl, $this->postObj->FromUserName, $this->postObj->ToUserName, time(), self::REPLY_TYPE_VOICE, $mediaid); if (!headers_sent()) header('Content-Type: application/xml; charset=utf-8'); self::response($resultStr); } /** * 回覆視訊訊息 * * @param $mediaid * @param string $title * @param string $description */ public function responseVideoMessage($mediaid, $title = "", $description = "") { $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Video> <MediaId><![CDATA[%s]]></MediaId> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> </Video> </xml>"; $resultStr = sprintf($textTpl, $this->postObj->FromUserName, $this->postObj->ToUserName, time(), self::REPLY_TYPE_VIDEO, $mediaid, $title, $description); if (!headers_sent()) header('Content-Type: application/xml; charset=utf-8'); self::response($resultStr); } /** * 回覆音樂訊息 * * @param string $title * @param string $description * @param string $url * @param string $hq_url */ public function responseMusicMessage($title = '', $description = '', $url = '', $hq_url = '') { $textTpl = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Music> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <MusicUrl><![CDATA[%s]]></MusicUrl> <HQMusicUrl><![CDATA[%s]]></HQMusicUrl> </Music> </xml>'; $resultStr = sprintf($textTpl, $this->postObj->FromUserName, $this->postObj->ToUserName, time(), self::REPLY_TYPE_MUSIC, $title, $description, $url, $hq_url); if (!headers_sent()) header('Content-Type: application/xml; charset=utf-8'); self::response($resultStr); } /** * 回覆圖文訊息 * * @param $items * * @throws Exception */ public function responseNewsMessage($items) { $textTpl = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <ArticleCount>%d</ArticleCount> <Articles>%s</Articles> </xml>'; $itemTpl = '<item> <Title><![CDATA[%s]]></Title> <Discription><![CDATA[%s]]></Discription> <PicUrl><![CDATA[%s]]></PicUrl> <Url><![CDATA[%s]]></Url> </item>'; $articles = ''; if ($items && is_array($items)) { foreach ($items as $item) { if (is_array($item) && (isset($item['Title']) || isset($item['Description']) || isset($item['PicUrl']) || isset($item['Url']))) $articles .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']); else throw new Exception("item => array('Title'=>'','Description'=>'','PicUrl'=>'','Url'=>'')"); } } $resultStr = sprintf($textTpl, $this->postObj->FromUserName, $this->postObj->ToUserName, time(), self::REPLY_TYPE_NEWS, count($items), $articles); if (!headers_sent()) header('Content-Type: application/xml; charset=utf-8'); self::response($resultStr); } /**傳送文字客服訊息,需要access_token * * @param $openid * @param $content * * @return bool|mixed */ public function sendTextMessage($openid, $content) { if ($this->getAccessToken()) { $message = array(); $message['touser'] = $openid; $message['msgtype'] = "text"; $message['text']['content'] = $content; return self::post(self::$links['message'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 傳送圖片客服訊息,需要access_token * * @param $openid * @param $mediaid * * @return bool|mixed */ public function sendImageMessage($openid, $mediaid) { if ($this->getAccessToken()) { $message = array(); $message['touser'] = $openid; $message['msgtype'] = "image"; $message['image']['media_id'] = $mediaid; return self::post(self::$links['message'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 傳送語音客服訊息,需要access_token * * @param $openid * @param $media_id * * @return bool|mixed */ public function sendVoiceMessage($openid, $media_id) { if ($this->getAccessToken()) { $message = array(); $message['touser'] = $openid; $message['msgtype'] = "voice"; $message['voice']['media_id'] = $media_id; return self::post(self::$links['message'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 傳送視訊客服訊息,需要access_token * * @param $openid * @param $media_id * @param string $title * @param string $description * * @return bool|mixed */ public function sendVideoMessage($openid, $media_id, $title = "", $description = "") { if ($this->getAccessToken()) { $message = array(); $message['touser'] = $openid; $message['msgtype'] = "video"; $message['video']['media_id'] = $media_id; $message['video']['title'] = $title; $message['video']['description'] = $description; return self::post(self::$links['message'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 傳送音樂客服訊息,需要access_token * * @param $openid * @param $url * @param $hq_url * @param $media_id * @param string $title * @param string $description * * @return bool|mixed */ public function sendMusicMessage($openid, $url, $hq_url, $media_id, $title = "", $description = "") { if ($this->getAccessToken()) { $message = array(); $message['touser'] = $openid; $message['msgtype'] = "music"; $message['music']['title'] = $title; $message['music']['description'] = $description; $message['music']['musicurl'] = $url; $message['music']['hqmusicurl'] = $hq_url; $message['music']['thumb_media_id'] = $media_id; return self::post(self::$links['message'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 傳送圖文客服訊息,需要access_token * * @param $openid * @param $items * * @return bool|mixed * @throws Exception */ public function sendNewsMessage($openid, $items) { if ($this->getAccessToken()) { $message = array(); $message['touser'] = $openid; $message['msgtype'] = "news"; if ($items && is_array($items)) { foreach ($items as $item) { if (is_array($item) && (isset($item['Title']) || isset($item['Description']) || isset($item['PicUrl']) || isset($item['Url']))) { $it['title'] = isset($item['Title']) ? $item['Title'] : ""; $it['description'] = isset($item['Description']) ? $item['Description'] : ""; $it['url'] = isset($item['Url']) ? $item['Url'] : ""; $it['picurl'] = isset($item['PicUrl']) ? $item['PicUrl'] : ""; if ($it['title'] && $it['description'] && $it['url'] && $it['picurl']) $message['news']['articles'][] = $it; } else throw new Exception("item => array('Title'=>'','Description'=>'','PicUrl'=>'','Url'=>'')"); } } return self::post(self::$links['message'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 建立分組 * * @param $name * * @return bool|mixed */ public function groupCreate($name) { if ($this->getAccessToken()) { $message = array(); $message['name'] = $name; return self::post(self::$links['group_create'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 查詢所有分組 * * @return bool|mixed */ public function groupGetAll() { if ($this->getAccessToken()) { return self::get(self::$links['group_get'] . "?access_token={$this->access_token}"); } return false; } /** * 查詢使用者所在分組 * * @param $openid * * @return bool|mixed */ public function groupGet($openid) { if ($this->getAccessToken()) { $message = array(); $message['openid'] = $openid; return self::post(self::$links['group_getid'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 修改分組名 * * @param $groupid * @param $name * * @return bool|mixed */ public function groupRename($groupid, $name) { if ($this->getAccessToken()) { $message = array(); $message['id'] = $groupid; $message['name'] = $name; return self::post(self::$links['group_rename'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 移動使用者分組 * * @param $openid * @param $to_groupid * * @return bool|mixed */ public function groupMove($openid, $to_groupid) { if ($this->getAccessToken()) { $message = array(); $message['openid'] = $openid; $message['to_groupid'] = $to_groupid; return self::post(self::$links['group_move'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 獲取使用者基本資訊 * * @param $openid * * @return bool|mixed */ public function userInfo($openid) { if ($this->getAccessToken()) { return self::get(self::$links['user_info'] . "?access_token={$this->access_token}&openid={$openid}"); } return false; } /** * 獲取關注者列表 * * @param null $next_openid * * @return bool|mixed */ public function userGet($next_openid = null) { if ($this->getAccessToken()) { if ($next_openid) return self::get(self::$links['user_get'] . "?access_token={$this->access_token}&openid="); else return self::get(self::$links['user_get'] . "?access_token={$this->access_token}&next_openid={$next_openid}"); } return false; } /** * 建立自定義選單 * * @param $menus * * @return bool|mixed */ public function menuCreate($menus) { if ($this->getAccessToken()) { $message = array(); $message['button'] = $menus; return self::post(self::$links['menu_create'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 獲取自定義選單 * * @return bool|mixed */ public function menuGet() { if ($this->getAccessToken()) { return self::get(self::$links['menu_get'] . "?access_token={$this->access_token}"); } return false; } /** * 刪除自定義選單 * * @return bool|mixed */ public function menuDelete() { if ($this->getAccessToken()) { return self::get(self::$links['menu_delete'] . "?access_token={$this->access_token}"); } return false; } /** * 生成帶引數的二維碼,通過expire_seconds可以設定臨時二維碼或永久二維碼 * * @param $sceneid * @param int $expire_seconds * * @return bool|mixed */ public function qrcodeCreate($sceneid, $expire_seconds = 0) { if ($this->getAccessToken()) { $message = array(); if ($expire_seconds > 0) { if ($expire_seconds > 1800) return false; $message['expire_seconds'] = $expire_seconds; $message['action_name'] = 'QR_SCENE'; } else $message['action_name'] = 'QR_LIMIT_SCENE'; $message['action_info']['scene']['scene_id'] = $sceneid; return self::post(self::$links['qrcode'] . "?access_token={$this->access_token}", json_encode($message, JSON_UNESCAPED_UNICODE)); } return false; } /** * 用ticket換取二維碼圖片,返回結果未圖片,可以直接展示或者下載 * * @param $ticket * * @return mixed */ public static function qrcodeGet($ticket) { return self::get(self::$links['showqrcode'] . "?tocket=" . urlencode($ticket)); } /** * 下載多媒體檔案 * * @param $mediaid * * @return mixed */ public function mediaDownload($mediaid) { return self::get(self::$links['media_download'] . "?access_token={$this->access_token}&media_id=" . $mediaid); } /** * 上傳多媒體檔案 * 圖片(image): 128K,支援JPG格式 * 語音(voice):256K,播放長度不超過60s,支援AMR\MP3格式 * 視訊(video):1MB,支援MP4格式 * 縮圖(thumb):64KB,支援JPG格式 * * @param $filetype * @param $filepath * * @return bool|mixed */ public function mediaUpload($filetype, $filepath) { if ($this->getAccessToken() && file_exists($filepath)) { $fileext = strtolower(Tools::getFileExtension($filepath)); $filesize = filesize($filepath); switch ($filetype) { case self::MEDIA_TYPE_IMAGE: if ($fileext != 'jpg' || $filesize > 128 * 1024) return false; break; case self::MEDIA_TYPE_VOICE: if (!in_array($fileext, array('amr', 'mp3')) || $filesize > 256 * 1024) return false; break; case self::MEDIA_TYPE_VIDEO: if ($fileext != 'mp4' || $filesize > 1024 * 1024) return false; break; case self::MEDIA_TYPE_THUMB: if ($fileext != 'jpg' || $filesize > 64 * 1024) return false; break; default: return false; break; } $media = array(); $media['access_token'] = $this->access_token; $media['type'] = $filetype; $media['media'] = '@' . $filepath; return self::post(self::$links['media_upload'], $media); } return false; } /** * 第三方網頁通過Oauth2.0獲取使用者授權 * 獲取code */ public function oauthGetCode($redirect, $scope, $state) { return self::$links['oauth_code'] . "?appid={$this->appid}&redirect_uri={$redirect}&response_type=code&scope={$scope}&state={$state}#wechat_redirect"; } /** * 第三方網頁通過Oauth2.0獲取使用者授權 * 通過code獲取access_token */ public function oauthGetAccessToken($code) { return self::get(self::$links['oauth_access_token'] . "?appid={$this->appid}&secret={$this->appsecret}&code={$code}&grant_type=authorization_code"); } /** * 第三方網頁通過Oauth2.0獲取使用者授權 * 重新整理access_token */ public function oauthRefreshAccessToken($refresh_token) { return self::get(self::$links['oauth_refresh'] . "?appid={$this->appid}&grant_type=refresh_token&refresh_token={$refresh_token}"); } /** * 第三方網頁通過Oauth2.0獲取使用者許可權 * 獲取使用者資訊,僅限scope為SCOPE_POP */ public function oauthUserInfo($access_token, $openid) { return self::get(self::$links['oauth_userinfo'] . "?access_token={$access_token}&openid={$openid}"); } /** * 返回js程式碼,隱藏微信中網頁右上角按鈕 * * @return string */ public static function hideOptionMenu() { return <<<EOF <script type="text/javascript"> document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() { WeixinJSBridge.call('hideOptionMenu'); }); </script> EOF; } /** * 返回js程式碼,隱藏微信中網頁底部導航欄 * * @return string */ public static function hideToolbar() { return <<<EOF <script type="text/javascript"> document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() { WeixinJSBridge.call('hideToolbar'); }); </script> EOF; } /** * 返回js程式碼,網頁獲取使用者網路狀態 * * @return string */ public static function getNetworkType() { return <<<EOF <script type="text/javascript"> WeixinJSBridge.invoke('getNetworkType',{}, function(e){ WeixinJSBridge.log(e.err_msg); } ); </script> EOF; } /** * 返回微信支付的JS程式碼 */ public static function getPayment($params,$account){ global $_W; $wOpt['appId'] = $_W['account']['key']; $wOpt['timeStamp'] = TIMESTAMP; $wOpt['nonceStr'] = random(8); $package = array(); $package['bank_type'] = 'WX'; $package['body'] = $params['title']; $package['attach'] = $_W['weid']; $package['partner'] = $wechat['partner']; $package['out_trade_no'] = $params['tid']; $package['total_fee'] = $params['fee'] * 100; $package['fee_type'] = '1'; $package['notify_url'] = $_W['siteroot'] . 'payment/wechat/notify.php'; $package['spbill_create_ip'] = CLIENT_IP; $package['time_start'] = date('YmdHis', TIMESTAMP); $package['time_expire'] = date('YmdHis', TIMESTAMP + 600); $package['input_charset'] = 'UTF-8'; ksort($package); $string1 = ''; foreach ($package as $key => $v) { $string1 .= "{$key}={$v}&"; } $string1 .= "key={$wechat['key']}"; $sign = strtoupper(md5($string)); $string2 = ''; foreach ($package as $key => $v) { $v = urlencode($v); $string2 .= "{$key}={$v}&"; } $string2 .= "sign={$sign}"; $string = ''; $keys = array('appId', 'timeStamp', 'nonceStr', 'package', 'appKey'); sort($keys); foreach ($keys as $key) { $v = $wOpt[$key]; if ($key == 'appKey') { $v = $wechat['signkey']; } $key = strtolower($key); $string .= "{$key}={$v}&"; } $string = rtrim($string, '&'); $wOpt['package'] = $string2; $wOpt['signType'] = 'SHA1'; $wOpt['paySign'] = sha1($string); return $wOpt; } }
log.php
<?php class Log { private static $logpath = LOG_DIR; /** * 寫入日誌 * * @param string $strFileName * @param string $strType * @param string $strMSG * @param string $strExtra * @param string $line */ public static function out($strFileName = "", $strType = "I", $strMSG = "", $strExtra = "", $line = "") { if ($strType == "") $strType = "I"; if (!file_exists(self::$logpath)) { if (!mkdir(self::$logpath, '0777')) { if (DEBUG_MODE) { die(Tools::displayError("Make " . self::$logpath . " error")); } else { die("error"); } } } elseif (!is_dir(self::$logpath)) { if (DEBUG_MODE) { die(Tools::displayError(self::$logpath . " is already token by a file")); } else { die("error"); } } else { if (!is_writable(self::$logpath)) { @chmod(self::$logpath, 0777); } $logfile = rtrim(self::$logpath, '/') . '/' . $strFileName . '_' . date("ymd") . '.log'; if (file_exists($logfile) && !is_writable($logfile)) { @chmod($logfile, 0644); } $handle = @fopen($logfile, "a+"); if ($handle) { if (Tools::isCli()) { $arg = ""; if ($_SERVER['argc'] > 0) { $arg = " ARGV:" . json_encode($_SERVER['argv']); } $strContent = "[" . date("Y-m-d H:i:s") . "] [" . strtoupper($strType) . "] [CLI] MSG:[" . $strMSG . "]" . $strExtra . " Location:" . $_SERVER["SCRIPT_FILENAME"] . $arg . ($line ? " Line:" . $line : "") . "\n"; } else $strContent = "[" . date("Y-m-d H:i:s") . "] [" . strtoupper($strType) .