-
-
Save rebaomi/10010967 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
*微信公众平台模拟登录 | |
* | |
*实现了公众平台上的操作<br>包括 实时消息获取 快速回复 用户管理 群发消息 获取用户基本信息 | |
*@copyright Copyright info | |
*@author dml | |
*@version version | |
*@package defalut | |
*/ | |
class WxMockLogin{ | |
/** | |
*以键值对形式存储微信公众平台验证必需的cookie | |
* | |
*@var array | |
*/ | |
public $cookie = array(); | |
/** | |
*微信公众平台的必需字段字典,字典目的是过滤掉非微信平台必需的cookie | |
* | |
*@var array | |
*/ | |
public $usedcookie = array('sig','cert','slave_sid','slave_user'); //登录需要用到的cookie | |
/** | |
*登录账号 | |
* | |
*@var string | |
*/ | |
protected $_username; | |
/** | |
*密码 MD5加密后 | |
* | |
*@var string | |
*/ | |
protected $_password; | |
/** | |
*验证码 | |
* | |
*@var string | |
*/ | |
protected $_verifyCode; | |
/** | |
*是否已经登录 | |
* | |
*@var boolean | |
*/ | |
protected $_islogin = false; | |
/** | |
*token 每次curl都要用到 | |
* | |
*@var int|string | |
*/ | |
public $_token; | |
/** | |
*crul资源指针 | |
* | |
*@var resource | |
*/ | |
protected $_curlRes; | |
/** | |
*微信登录url地址 | |
* | |
*@var string | |
*/ | |
protected $_urlLogin = 'https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN'; | |
/** | |
*初始化 | |
* | |
*@param string $username 用户名,非必需 | |
*@param string $password 密码,非必需 | |
*@param string $verifyCode 验证码,非必需 | |
*@return void | |
* | |
* | |
* | |
*/ | |
public function __construct($username='',$password='',$verifyCode='') { | |
$this->_username = $username; | |
$this->_loadCookie(); | |
$this->_password = md5($password); | |
$this->_verifyCode = $verifyCode; | |
if($password != '' && $verifyCode != ''){ | |
$this->login(); | |
} | |
} | |
/** | |
*判断是否已经登录状态 | |
* | |
*@return boolean 是否登录 | |
*/ | |
public function isLogin(){ | |
return $this->_islogin; | |
} | |
/** | |
*获取地域信息 | |
* | |
*@param int $id 地区编码(微信) | |
*@return string json格式字符串<br> | |
*<code> | |
* 返回格式: | |
*{"num":"34", | |
* "data":[ | |
* {"id":"10012","name":"上海"} | |
* [,...] | |
* ] | |
*} | |
*</code> | |
*/ | |
public function getregions($id){ | |
$token = $this->_token; | |
$url = "https://mp.weixin.qq.com/cgi-bin/getregions?token=$token&id=$id&t=ajax-getregions&lang=zh_CN"; | |
return $this->_curl($url); | |
} | |
/** | |
*根据关键字搜索消息列表 | |
* | |
*@param string 搜索关键词 | |
*@return string json格式字符串 | |
*<code> | |
* 正确返回的格式:{"msg_item":[ | |
* {"id":100001064, | |
* "type":1, | |
* "fakeid":"82487945", | |
* "nick_name":"Ero", | |
* "date_time":1382696544, | |
* "content":"我日", | |
* "source":"", | |
* "msg_status":4, | |
* "has_reply":0, | |
* "refuse_reason":"" | |
* } | |
* [,...] | |
* ] | |
* } | |
* token或签名错误返回:'need login '+ 访问的url | |
*</code> | |
*/ | |
public function searchmsgbykeyword($keyword = '日'){ | |
$token = $this->_token; | |
$url = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&action=search&keyword=$keyword&count=20&token=$token&lang=zh_CN"; | |
$result = $this->_curl($url); | |
if(preg_match('/登录超时/s',$result) == 1){ | |
$this->_clearCookie(); | |
$this->_islogin = false; | |
return 'need login '.$url; | |
} | |
//preg_match("/cgiData=\{(.*?)\};/s",$result,$match); //cigData | |
preg_match("/list : \((.*?)\).msg_item/",$result,$match); | |
return $match[1]; | |
} | |
/** | |
*获取个人信息 | |
* | |
*@param int $fakeid 用户fakeid | |
*@return string json格式字符串 | |
*<code> | |
*{"base_resp":{"ret":0,"err_msg":"ok"}, | |
* "contact_info":{ "fake_id":30312195, | |
* "nick_name":"李泽", | |
* "user_name":"llliiizzzeee", | |
* "signature":"专注社会化营销,玩微博的多聊聊:)", | |
* "city":"深圳", | |
* "province":"广东", | |
* "country":"中国", | |
* "gender":1, | |
* "remark_name":"", | |
* "group_id":0 | |
* }, | |
* "groups":{"groups":[ | |
* {"id":0,"name":"未分组","cnt":6}, | |
* {"id":1,"name":"黑名单","cnt":0}, | |
* {"id":2,"name":"星标组","cnt":0}, | |
* {"id":100,"name":"测试","cnt":1} | |
* ] | |
* } | |
*} | |
*</code>*/ | |
public function getcontactinfo($fakeid){ | |
$token = $this->_token; | |
$url = 'https://mp.weixin.qq.com/cgi-bin/getcontactinfo'; | |
$data = array('lang'=>'zh_CN', | |
't'=>'ajax-getcontactinfo', | |
'token'=>$token, | |
'fakeid'=>$fakeid | |
); | |
$result = $this->_curl($url,$data); | |
return $result; | |
/*token:1426845324 | |
lang:zh_CN | |
t:ajax-getcontactinfo | |
fakeid:2969320762*/ | |
} | |
/** | |
*消息群发 | |
* | |
*@param string $content 消息内容 | |
*@param string $groupid 分组ID | |
*@param string $sex 性别 0:未知 1:男 2:女 | |
*@param string $country 国家编码 通过$WxmockLogin->getregions(0)获取 | |
*@param string $province 省份编码 通过$WxmockLogin->getregions()获取 | |
*@param string $city 城市代码 | |
*@param string $type 类型ID 1:文字 2:图片 3:语音 4:视频 10:图文消息 目前只支持文字 | |
*@return string json格式字符串 | |
*<code> | |
* | |
* | |
*</code> | |
*/ | |
public function masssend($content, $groupid = '-1', $sex = '0', $country = '', $province = '', $city = '', $type = '1') { | |
$token = $this->_token; | |
$url = 'https://mp.weixin.qq.com/cgi-bin/masssend?t=ajax-response'; | |
$data = array('type'=>$type, | |
'content'=>$content, | |
'error'=>'false', | |
'imgcode'=>'', | |
'needcomment'=>'0', | |
'groupid'=>$groupid, | |
'sex'=>$sex,//0:全部 1:男 2:女 | |
'country'=>$country, | |
'city'=>$city, | |
'province'=>$province, | |
'synctxweibo'=>'0', | |
'synctxnews'=>'0', | |
'token'=>$token, | |
'ajax'=>'1' | |
); | |
/* return print_r($data,true);*/ | |
$result = $this->_curl($url,$data); | |
return $result; | |
/* type:1 | |
content:hi | |
error:false | |
imgcode: | |
needcomment:0 | |
groupid:100 | |
sex:0 | |
country: | |
city: | |
province: | |
synctxweibo:0 | |
synctxnews:0 | |
token:1765302028 | |
ajax:1*/ | |
} | |
//5天消息烈性列表获取快速回复 | |
public function singlesend($tofakeid,$content,$quickreplyid){ | |
$token = $this->_token; | |
$url = "https://mp.weixin.qq.com/cgi-bin/singlesend"; | |
$referer = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&token=$token&count=20&day=7"; | |
$data = array('mask'=>'false', | |
'tofakeid'=>$tofakeid, | |
'imgcode'=>'', | |
'type'=>'1', | |
'content'=>$content, | |
'quickreplyid'=>$quickreplyid, | |
'token'=>$token, | |
'lang'=>'zh_CN', | |
't'=>'ajax-response' | |
); | |
$result = $this->_curl($url,$data,true,$referer); | |
if(preg_match('/登录超时/s',$result) == 1){ | |
$this->_clearCookie(); | |
$this->_islogin = false; | |
return 'need login '.$url.' '.print_r($data,true); | |
} | |
return $result; | |
/*mask:false | |
tofakeid:1638219980 | |
imgcode: | |
type:1 | |
content:你也好 | |
quickreplyid:100001050 | |
token:2123921385 | |
lang:zh_CN | |
t:ajax-response*/ | |
} | |
//主动针对某fake_id进行推送信息 | |
public function sendMsgForFakeid($fake_id,$content){ | |
$token = $this->_token; | |
$url = "https://mp.weixin.qq.com/cgi-bin/singlesend"; | |
$referer="https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=$fake_id&token=$token&lang=zh_CN"; | |
$data = array('type'=>1, | |
'content'=>$content, | |
'tofakeid'=>$fake_id, | |
'imgcode'=>'', | |
'token'=>$token, | |
'lang'=>'zh_CN', | |
'random'=>1/rand(0,10000), | |
't'=>'ajax-response' | |
); | |
$result = $this->_curl($url,$data,true,$referer); | |
if(preg_match('/登录超时/s',$result) == 1){ | |
$this->_clearCookie(); | |
$this->_islogin = false; | |
return 'need login '.$url.' '.print_r($data,true); | |
} | |
return $result; | |
} | |
//改变分组 | |
/* | |
contacttype 表示转去的目的组别 | |
*/ | |
public function changeGroup($fakeid,$contacttype){ | |
$token = $this->_token; | |
$url = "https://mp.weixin.qq.com/cgi-bin/modifycontacts"; | |
$referer = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&token=1954377267&lang=zh_CN"; | |
$data = array('contacttype'=>$contacttype,'tofakeidlist'=>$fakeid,'token'=>$token,'lang'=>'zh_CN','random'=>1/rand(0,10000),'f'=>'json','ajax'=>1,'action'=>'modifycontacts','t'=>'ajax-putinto-group'); | |
$result = $this->_curl($url,$data,true,$referer); | |
if(preg_match('/登录超时/s',$result) == 1){ | |
$this->_clearCookie(); | |
$this->_islogin = false; | |
return 'need login '.$url.' '.print_r($data,true); | |
} | |
return $result; | |
} | |
//修改备注 | |
public function changeRemark($fakeid,$newRemark){ | |
$token = $this->_token; | |
$url = "https://mp.weixin.qq.com/cgi-bin/modifycontacts"; | |
$referer = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=1&token=$token&lang=zh_CN"; | |
$data = array('remark'=>$newRemark,'tofakeuin'=>$fakeid,'token'=>$token,'lang'=>'zh_CN','random'=>1/rand(0,10000),'f'=>'json','ajax'=>1,'t'=>'ajax-response','action'=>'setremark'); | |
$result = $this->_curl($url,$data,true,$referer); | |
if(preg_match('/登录超时/s',$result) == 1){ | |
$this->_clearCookie(); | |
$this->_islogin = false; | |
return 'need login '.$url.' '.print_r($data,true); | |
} | |
return $result; | |
} | |
//用户5天内消息获取 | |
public function get5dayMsg($count=20,$day=7){ | |
$token = $this->_token; | |
$url = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=$count&day=$day&token=$token&lang=zh_CN"; | |
$result = $this->_curl($url); | |
if(preg_match('/登录超时/s',$result) == 1){ | |
$this->_clearCookie(); | |
$this->_islogin = false; | |
return 'need login '.$url; | |
} | |
//preg_match("/cgiData=\{(.*?)\};/s",$result,$match); //cigData | |
preg_match("/list : \((.*?)\).msg_item/",$result,$match); | |
return $match[1]; | |
} | |
//获取用户(最近*个),最大1000 ? | |
public function getUserInfo($pagesize=10,$pageidx=0,$type=0,$groupid=0){ | |
$token = $this->_token; | |
$url = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=$pagesize&pageidx=$pageidx&type=$type&groupid=$groupid&token=$token&lang=zh_CN"; | |
$result = $this->_curl($url); | |
if(preg_match('/登录超时/s',$result) == 1){ | |
$this->_clearCookie(); | |
$this->_islogin = false; | |
return 'need login '.$url; | |
} | |
//preg_match("/cgiData=\{(.*?)\};/s",$result,$match); //cigData | |
preg_match("/friendsList : \(\{(.*?)\}\).contacts/",$result,$match); | |
preg_match("/groupsList : \(\{(.*?)\}\).groups/",$result,$groups); | |
return '{'.$match[1].','.$groups[1].'}'; | |
} | |
//过滤登录需要的cookie | |
protected function _loadCookie(){ | |
foreach($_COOKIE as $key => $value){ | |
if(in_array($key,$this->usedcookie)){ | |
$this->cookie[$key] = $value; | |
} | |
if($key == 'token'){ | |
$this->_token = $value; | |
} | |
} | |
} | |
//获取登录状态cookie | |
public function login() { | |
$postData = array('username'=>$this->_username, | |
'pwd'=>$this->_password, | |
'imgcode'=>$this->_verifyCode, | |
'f'=>'json' | |
); | |
$rtstring = $this->_curl($this->_urlLogin,$postData,true); | |
//cookie | |
preg_match_all("/Set-Cookie: ([\w=]*);/",$rtstring,$matches); | |
$this->_cookiepush($matches[1]); | |
//token | |
preg_match_all("/\r\n\r\n(.*)/s",$rtstring,$bodys); | |
$resArr = json_decode($bodys[1][0],true); | |
//正确返回结果的msg示例:cgi-bin/home?t=home/index&lang=zh_CN&token=2123921385 | |
preg_match("/token=(\d*)/",$resArr['ErrMsg'],$token); | |
print_r($token); | |
$this->_cookiepush($token[0]); | |
$this->_token = $token[1]; | |
$this->_islogin = true; | |
} | |
//$cookiestr 格式 sig=cookievalvalvalval 或者 array('sig=cookievalvalval','sig1=cookievalvalval'...) | |
protected function _cookiepush($cookies) { | |
if(is_array($cookies)) { | |
foreach($cookies as $cookie){ | |
$kpos = strpos($cookie,'='); | |
if($kpos !== false) { | |
$key = substr($cookie,0,$kpos); | |
$value = substr($cookie,$kpos+1); | |
$this->cookie[$key] = $value; | |
setcookie($key,$value); | |
} | |
} | |
return true; | |
} elseif(is_string($cookies)) { | |
$kpos = strpos($cookies,'='); | |
if($kpos !== false) { | |
$key = substr($cookies,0,$kpos); | |
$value = substr($cookies,$kpos+1); | |
$this->cookie[$key] = $value; | |
setcookie($key,$value); | |
} | |
return true; | |
} else { | |
return false; | |
} | |
} | |
//清除cookie | |
protected function _clearCookie(){ | |
foreach($this->usedcookie as $value){ | |
setcookie ($value, "", time() - 3600); | |
} | |
} | |
//解析$_cookie生成可发送的cookie字符串 | |
protected function _getCookieStr(){ | |
$cookiestr = ''; | |
foreach ($this->cookie as $key => $value) { | |
$cookiestr .= $key.'='.$value.'; '; | |
} | |
return $cookiestr; | |
} | |
//获取验证码,保存cookie.sig | |
public function getVerifyCode() { | |
$username = $this->_username; | |
$rtstring = $this->_curl("https://mp.weixin.qq.com/cgi-bin/verifycode?username=$username&r=".time(),'',true); | |
preg_match_all("/Set-Cookie: ([\w=]*)/",$rtstring,$matches); | |
$this->_cookiepush($matches[1][0]); | |
header('Content-Type:image/jpeg'); | |
$st = curl_getinfo($this->_curlRes,CURLINFO_HEADER_SIZE); | |
echo substr($rtstring,$st); | |
//preg_match_all("/\r\n\r\n(.*)/s",$rtstring,$matches1); | |
//print_r($matches1); | |
//echo $matches1[1][0]; | |
} | |
//curl操作,$url:请求地址 $data:post数据(数组或字符串) $return_herder:是否返回http响应头文件 | |
protected function _curl($url,$data='',$return_header=false,$referer='https://mp.weixin.qq.com/') { | |
$headers_org = array('Origin:https://mp.weixin.qq.com','Host:mp.weixin.qq.com','Cookie:'.$this->_getCookieStr()); | |
$user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36'; | |
if($this->_curlRes){ | |
curl_close($this->_curlRes); | |
} | |
$this->_curlRes = curl_init($url); | |
$ch = $this->_curlRes; | |
curl_setopt($ch,CURLOPT_HTTPHEADER, $headers_org); //设置请求头 | |
curl_setopt($ch,CURLOPT_USERAGENT, $user_agent); | |
curl_setopt($ch, CURLOPT_REFERER, $referer); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回字符串,而非直接输出 | |
curl_setopt($ch, CURLOPT_HEADER, $return_header); // 返回header部分 | |
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120); // 设置socket连接超时时间 | |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //ssl | |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //ssl | |
//post数据 | |
if (is_string($data) && $data !=''){ | |
curl_setopt($ch, CURLOPT_POST, true); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | |
} else if (is_array($data)) { | |
curl_setopt($ch, CURLOPT_POST, true); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); | |
} | |
set_time_limit(120); // 设置自己服务器超时时间 | |
return curl_exec($ch); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment