簡介
使用 Zephir 開發的集合架構,能夠輕鬆的整合到你的 PHP 中。經過了簡單的測試。
當然還有很多功能沒有完善和實現,以及文檔的欠缺,我會抽取時間一點一點的完善。
安裝
Linux
安裝環境依賴
#Ubuntu sudo apt-get install php5-dev php5-mysql gcc libpcre3-dev#Fedora sudo yum install php-devel php-mysqlnd gcc libtool#RHEL sudo yum install php-devel php-mysql gcc libtool#Suse yast2 -i php5-pear php5-devel php5-mysql gcc
安裝
git clone https://git.coding.net/widuu/wechat.git cd wechat/ext && ./install
Windows
現在直編譯了php5.6和php5.5版本,可以點擊下邊的地址下載。
| DLL List |
| PHP 5.6 |
5.6 Non Thread Safe (NTS) x86 5.6 Thread Safe (TS) x86 5.6 Non Thread Safe (NTS) x64 5.6 Thread Safe (TS) x64 |
| PHP 5.5 |
5.5 Non Thread Safe (NTS) x86 5.5 Thread Safe (TS) x86 5.5 Non Thread Safe (NTS) x64 5.5 Thread Safe (TS) x64 |
|
Contributing
登入 https://coding.net 或 https://github.com
倉庫地址分布:
Coding倉庫:https://coding.net/u/widuu/p/wechat/git
github倉庫:http://github.com/widuu/wechat
建立您的特性分支 (git checkout -b my-new-feature)
提交您的改動 (git commit -am 'Added some feature')
將您的改動記錄提交到遠程 git 倉庫 (git push origin my-new-feature)
然後到 coding 網站的該 git 遠程倉庫的 my-new-feature 分支下發起 Pull Request
連絡方式
Email: admin#widuu.com <#換成@>
Blog:http://www.widuu.com
WeiBo:http://weibo.com/widuu
核心代碼
wechat.zep
namespace Wechat; class Wechat extends Wechatabstract{ /** * 寄件者id */ protected _tousername { get,set }; /** * wechat id */ protected _fromusername { get,set }; /** * 事件類型 */ protected _msgtype { get,set }; /** * 事件 */ protected _event { get,set }; /** * 建立時間 */ protected _createtime { get,set }; /** * 簡訊內容 */ protected _content { get,set }; /** * 訊息id */ protected _msgid { get,set }; /** * 圖片連結 */ protected _picurl { get,set }; /** * 媒體id */ protected _mediaid { get,set }; /** * 語音格式 */ protected _format { get,set }; /** * 縮圖的媒體id */ protected _thumbmediaid { get,set }; /** * 地理位置維度 */ protected _location_x { get,set }; /** * 地理位置經度 */ protected _location_y { get,set }; /** * 地圖縮放大小 */ protected _scale { get,set }; /** * 地理位置資訊 */ protected _label { get,set }; /** * 訊息標題 */ protected _title { get,set }; /** * 訊息描述 */ protected _description { get,set }; /** * 訊息連結 */ protected _url { get,set }; /** * TOKEN URL */ const TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?"; /** * User URL */ const USER_URL = "https://api.weixin.qq.com/cgi-bin/user/"; /** * Menu URL */ const MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/"; /** * 接收 POST 資訊 * @author widuu */ public function getRequest(){ if this->isPost() { var key,value; let this->_request_data = this->getInfo(true); if this->_debug { if empty this->_request_data{ this->log("[ERROR".date("Y-m-d H:i:s",time())."] Request Data NULL\r\n"); } }; if !empty this->_request_data{ for key,value in this->_request_data { let key = "_".strtolower(key); if isset this->{key} { let this->{key} = value; } } return this->_request_data; } }else{ return false; } } /** * 返回訊息方法 * @param string type * @param (array|string) type * @return boolean * @author widuu */ public function response(string! type=null,info){ if empty this->_request_data { return false; } var tpl; let tpl = this->getTpl(type,info); if this->_debug { if empty tpl{ this->log("[ERROR".date("Y-m-d H:i:s",time())."] Get Response XML Type Error\r\n"); } }; echo tpl; } /** * 訂閱事件 * @author widuu */ public function subscribe(string! type="text", info){ if empty this->_request_data { return false; } if(this->_event == "subscribe"){ this->response(type,info); return; } } /** * 擷取Token * @param string appid * @param string secret * @return array * @author widuu */ public function getToken(string! appid="",string! secret=""){ if (empty appid || empty secret) { throw new Exception("getToken Method Parameter does not allow nulls",4001); }; var tokenUrl,urlQurey,result; let urlQurey = ["grant_type":"client_credential","appid":appid,"secret":secret]; let tokenUrl = Wechat::TOKEN_URL.http_build_query(urlQurey); let result = this->httpGet(tokenUrl); return json_decode(result,true); } /** * 擷取使用者資訊 * @param string type * @param string token * @param string openid * @return array * @author widuu */ public function getUser(string! type=null,string! token="",string openid=""){ if empty token || empty type { throw new Exception("Parameter does not allow nulls",4002); } var url,param,result; switch(type){ case "userinfo" : let param = ["access_token":token,"openid":openid,"lang":"zh_CN"]; let url = Wechat::USER_URL."info?".http_build_query(param); let result = this->httpGet(url); break; case "userlist" : let param = ["access_token":token,"next_openid":openid]; let url = Wechat::USER_URL."get?".http_build_query(param); let result = this->httpGet(url); break; default: return false; } return json_decode(result,true); } /** * 設定使用者備忘 * @param string token * @param string openid * @param string remarke * @return array * @author widuu */ public function setRemark(string! token=null,string! openid=null,string! remarke=null)->boolean{ var remarkUrl,postInfo,result; let remarkUrl = Wechat::USER_URL."info/updateremark?access_token=".token; let postInfo = ["openid":openid,"remark":remarke]; let result = this->httpPost(remarkUrl,postInfo); if !result { return false; } return json_decode(result,true); } /** * 擷取自訂菜單 * @author widuu */ public function Menu(string!type = null,string! token =null,array info = null){ var menu_url,result; switch(type){ case "get": let menu_url = Wechat::MENU_URL."get?access_token=".token; let result = this->httpGet(menu_url); break; case "delete": let menu_url = Wechat::MENU_URL."delete?access_token=".token; let result = this->httpGet(menu_url); break; case "create": if typeof info != "array" || empty info { throw new Exception("create param error",4005); } let menu_url = Wechat::MENU_URL."create?access_token=".token; let result = this->httpPost(menu_url,info); default : return false; } if !empty result{ return json_decode(result,true); }else{ throw new Exception("Response Error",4003); } } /** * 擷取變數的方法 * @param string name * @return boolean | string * @author widuu */ public function _get(string! name){ let name = "_".name; if isset this->{name} { return this->{name}; } return false; } /** * 設定變數的方法 * @param string name * @param value * @return boolean * @author widuu */ public function _set(string! name,value) ->boolean{ let name = "_".name; if isset this->{name} { let this->{name} = value; return true; } return false; } /** * 設定變數的方法 * @param string name * @param value * @return boolean * @author widuu */ protected function getTpl(string! type=null,info){ //組織 xml var tpl; let tpl = "".this->_fromusername."".this->_tousername."".time()."".type.""; switch (type){ case "text": let tpl .= "".info.""; break; case "image": let tpl .= "
".info.""; break; case "voice": let tpl .= "".info.""; break; case "video": let tpl .= "".info."<![CDATA[title]]>description "; break; case "music": if typeof info != "array"{ return false; } let tpl .= "<![CDATA[".info["title"]."]]>".info["description"]."".info["musicurl"]."".info["hqmusicurl"]."".info["mediaid"].""; break; case "news" : if typeof info != "array"{ return false; } var num; if isset info["title"] { let num = 1; }else{ let num = count(info); } let tpl .= "".num."".this->getNews(info).""; break; default : return false; } let tpl.= ""; return tpl; } /** * 判斷要求方法 * @author widuu */ private function isPost() -> boolean { if strtolower(_SERVER["REQUEST_METHOD"]) == "post" { return true; } return false; } /** * 擷取新聞 * @author widuu */ private function getNews(array! info){ var value,tpl = ""; if isset info["title"] { let tpl.="<![CDATA[".info["title"]."]]>".info["description"]."".info["picurl"]."".info["url"].""; }else{ for _,value in info { let tpl.="<![CDATA[".value["title"]."]]>".value["description"]."".value["picurl"]."".value["url"].""; } } return tpl; } /** * 驗證 * @author widuu */ static public function valid(string! token = null){ var signature,timestamp,nonce,tmpArr,tmpStr,echoStr; let signature = _GET["signature"]; let timestamp = _GET["timestamp"]; let nonce = _GET["nonce"]; let echoStr = _GET["echostr"]; let tmpArr = [ token, timestamp, nonce ]; sort(tmpArr, SORT_STRING); let tmpStr = implode( "", tmpArr ); let tmpStr = sha1( tmpStr ); if tmpStr == signature { echo echoStr; }else{ return false; } } /** * 設定URL到期時間 * @author widuu */ public static function setTimeout(int! timeout = 1){ globals_set("curl_timeout", timeout); return true; } /** * HTTP GET 方法 * @param string url * @author widuu */ protected function httpGet(string! url="") { var curlHandle, content,timeout ; let timeout = globals_get("curl_timeout"); let curlHandle = curl_init(); curl_setopt( curlHandle , CURLOPT_URL, url ); curl_setopt( curlHandle , CURLOPT_RETURNTRANSFER, 1 ); curl_setopt( curlHandle , CURLOPT_SSL_VERIFYPEER, false); curl_setopt( curlHandle , CURLOPT_SSL_VERIFYHOST, false); curl_setopt( curlHandle , CURLOPT_TIMEOUT, timeout ); let content = curl_exec( curlHandle ); curl_close( curlHandle ); return content; } /** * HTTP POST 方法 * @param string url * @param array info * @author widuu */ protected function httpPost(string! url=null ,array info){ var curlHandle, content,timeout ; if typeof info != "array"{ throw new Exception("infomation must be type array",4004); } let timeout = globals_get("curl_timeout"); let curlHandle = curl_init( url ); curl_setopt(curlHandle, CURLOPT_HEADER, 0); curl_setopt(curlHandle, CURLOPT_RETURNTRANSFER, 1); curl_setopt(curlHandle, CURLOPT_POST, 1); curl_setopt(curlHandle, CURLOPT_POSTFIELDS, json_encode(info,JSON_UNESCAPED_UNICODE)); curl_setopt(curlHandle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt(curlHandle, CURLOPT_SSL_VERIFYHOST, false); curl_setopt(curlHandle ,CURLOPT_TIMEOUT, timeout ); let content = curl_exec( curlHandle ); curl_close( curlHandle ); return content; }