近段时间由于工作需要,需要写个QQ通知的功能,仔细百度了一下,发现了现有的码,现分享大家。特别应该注意的是腾讯公司并未提供过QQ直接通讯的API接口,不过很庆幸的是咋们还有个3g qq可以小小利用下,3Gqq应采用session会话(也许是考虑到部分手机不支持COOKIE或其他功能),总之就是功能限制把。整个QQ会话以唯一会话SID为标识进行通讯,每次登录有效期为30天,说白了也就是大家平常用过的书签功能。不过有时平凡的登录或者太有规律的数据也会被腾讯公司给筛选出来,从而让SID失效,需重新登录,这的确很麻烦,博主也在认真研究...,现奉上整理出来的CODE
1 <?php 2 //打开网址函数(无心问世出品) 3 function openu($url){ 4 $url = eregi_replace('^http://', '', $url); 5 $temp = explode('/', $url); 6 $host = array_shift($temp); 7 $path = '/'.implode('/', $temp); 8 $temp = explode(':', $host); 9 $host = $temp[0]; 10 $port = isset($temp[1]) ? $temp[1] : 80; 11 $fp = @fsockopen($host, $port, &$errno, &$errstr, 30); 12 if ($fp){ 13 @fputs($fp, "GET $path HTTP/1.1 "); 14 @fputs($fp, "Host: $host "); 15 @fputs($fp, "Accept: */* "); 16 @fputs($fp, "Referer: http://$host/ "); 17 @fputs($fp, "User-Agent: TTMobile/09.03.18/symbianOS9.1 Series60/3.0 Nokia6120cAP3.03 "); 18 @fputs($fp, "Connection: Close "); 19 } 20 $Content = ''; 21 while ($str = @fread($fp, 4096)) 22 $Content .= $str; 23 @fclose($fp); 24 return $Content; 25 } 26 //QQ登陆函数(需curl的支持) 27 function qq_login($qqno,$qqpw){ 28 $cookie = dirname(__FILE__).'/cookie.txt'; 29 $post = array( 30 'login_url' => 'http://pt.3g.qq.com/s?sid=ATAll43N7ZULRQ5V8zdfojol&aid=nLogin', 31 'q_from' => '', 32 'loginTitle' => 'login', 33 'bid' => '0', 34 'qq' => $qqno, 35 'pwd' => $qqpw, 36 'loginType' => '1', 37 'loginsubmit' => 'login', 38 ); 39 $curl = curl_init('http://pt.3g.qq.com/handleLogin?aid=nLoginHandle&sid=ATAll43N7ZULRQ5V8zdfojol'); 40 curl_setopt($curl, CURLOPT_HEADER, 0); 41 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 42 curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie); // ?Cookie 43 curl_setopt($curl, CURLOPT_POST, 1); 44 curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post)); 45 global $result; 46 $result = curl_exec($curl); 47 curl_close($curl); 48 return $result; 49 } 50 51 function get_sid($result){ 52 preg_match_all("/sid=([^&=?]*)/",$result,$regs); 53 $sid=$regs[1][0];//sid 54 return $sid; 55 } 56 57 //QQ验证码函数 58 function qq_yzm(){ 59 $cookie = dirname(__FILE__).'/cookie.txt'; 60 $post = array( 61 'auto'=>0, 62 'bid'=> 0, 63 ); 64 $curl = curl_init('http://pt5.3g.qq.com/psw3gqqLogin?sid=AepMDkt5vrXH64LvijQHTfWd'); 65 curl_setopt($curl, CURLOPT_HEADER, 0); 66 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 67 curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie); // ?Cookie 68 curl_setopt($curl, CURLOPT_POST, 1); 69 curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post)); 70 global $result; 71 $result = curl_exec($curl); 72 curl_close($curl); 73 return $result; 74 } 75 76 //时间函数 77 function time2string($second){ 78 $day = floor($second/(3600*24)); 79 $second = $second%(3600*24);//除去整天之后剩余的时间 80 $hour = floor($second/3600); 81 $second = $second%3600;//除去整小时之后剩余的时间 82 $minute = floor($second/60); 83 $second = $second%60;//除去整分钟之后剩余的时间 84 //返回字符串 85 return $day.'天'.$hour.'小时'.$minute.'分'.$second.'秒'; 86 } 87 88 //sid到期时间 89 function add_onlinetime(){ 90 date_default_timezone_set('PRC'); 91 $tomorrow = mktime(0,0,0,date("m"),date("d")+30,date("Y")); 92 $time=date("Y-m-d",$tomorrow); 93 $now=date("Y-m-d"); 94 $deltime=date('G:i:s'); 95 $time5= $time.' '.$deltime; 96 return $time5; 97 } 98 99 function sendmsg($sid,$to_num,$msg){ 100 $params = array(); 101 $params["msg"] = $msg; 102 $params["u"] = $to_num; 103 $params["saveURL"] = 0; 104 $params["do"] = "send"; 105 $params["on"] = 1; 106 $params["aid"] = "发送"; 107 $url = "http://q16.3g.qq.com/g/s?sid=" . $sid; 108 $data = http_post($url, $params); 109 if(preg_match('/消息发送成功/',$data)) 110 echo 'success<br />'; 111 else 'failure'; 112 } 113 114 function getMsg($qq_num = 0, $sid = 0) { 115 $url = "http://q16.3g.qq.com/g/s?sid=" . $sid . "&3G_UIN=" . $qq_num ."&saveURL=0&aid=nqqChat"; 116 $data = http_get($url); 117 preg_match("/name="u" value="(d+)"/", $data, $matches); 118 $result["qq"] = $matches[1]; 119 $data = explode("<form", $data); 120 $data = $data[0]; 121 preg_match_all("/<p>(.+)?</p>/", $data, $matches); 122 unset($matches[1][0]); 123 $result["content"] = $matches[1]; 124 return $result; 125 } 126 127 function http_get($url,$header=0){ 128 $opt = array( 129 CURLOPT_URL => $url, 130 CURLOPT_HEADER => $header, 131 CURLOPT_RETURNTRANSFER => 1, 132 CURLOPT_TIMEOUT => 60, 133 CURLOPT_USERAGENT=>'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13' 134 ); 135 return curl_run($opt); 136 } 137 138 function http_post($url,$data,$header=0){ 139 $opt = array( 140 CURLOPT_URL => $url, 141 CURLOPT_HEADER => $header, 142 CURLOPT_RETURNTRANSFER => 1, 143 CURLOPT_TIMEOUT => 60, 144 CURLOPT_POSTFIELDS => http_build_query($data), 145 CURLOPT_USERAGENT=>'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13' 146 ); 147 return curl_run($opt); 148 } 149 150 function curl_run($opt){ 151 $ch=curl_init(); 152 curl_setopt_array($ch,$opt); 153 $r = curl_exec($ch); 154 curl_close($ch); 155 return $r; 156 } 157 ?>
另外还有一个版本也顺便奉献给大家,原理大同小异
<?php /* *该类用于登录3gqq,可以作为3gqq网游戏辅助登录的基类,继承该类,可以添加具体游戏的处理方法,类还有待完善 *By 草木の灰(CrazyK) *QQ:497920802 *email:netchen@vip.qq.com *2013.5.4 */ class qq{ /** *为了继承时候可访问属性,故使用保护属性 */ protected $m_sid; protected $m_qq; protected $m_cookie; protected $m_error; protected $m_cookie_file; protected $m_yzm_post_data; protected $m_yzm_post_url; protected $m_yzm_url; protected $m_http_header; protected $m_login_status;//0没有登录3g,1登录3g protected $m_chat_status;//0离线,1上线,2隐身,3离开 /** * 构造函数 * */ function __construct($sid=null,$cookie_file=null){ $this->m_http_header=array( 'Cache-Control:max-age=0', 'User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11 QIHU THEWORLD', 'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language:zh-CN,zh;q=0.8', 'Accept-Charset:GBK,utf-8;q=0.7,*;q=0.3', 'Accept-Encoding:gzip,deflate,sdch' ); if($sid==null||$cookie_file==null){ $this->m_cookie_file=tempnam('./cookietmp/','tmp'); $this->m_login_status=0;//没有登录3gqq $this->m_chat_status=0;//没有进行3g聊天 }else{ $this->m_sid=$sid; $this->m_cookie_file=$cookie_file; $this->m_login_status=1;//没有登录3gqq $this->m_chat_status=0;//没有进行3g聊天 } } /** * 析构函数 * 用于测试时候删除临时文件 */ /* function __destruct() { if(file_exists($this->m_cookie_file)) { unlink($this->m_cookie_file); } } */ /** * 利用qq账号和密码登录 * mode为登录方式,3为不登陆qq聊天,2为隐身登录,1为在线登录 * 成功返回0,失败返回其他值 */ function login($qq,$pwd,$mode='3'){ if($this->m_login_status===0){ $http_header=$this->m_http_header; $this->m_qq=$qq; $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,"http://pt.3g.qq.com/"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_HTTPHEADER,$http_header); curl_setopt($ch,CURLOPT_ENCODING,'gzip'); $content=curl_exec($ch); curl_close($ch); $post_url=$this->substring($content,'action="','"'); $http_header[]='Origin:http://pt.3g.qq.com'; $http_header[]='Referer:http://pt.3g.qq.com/g/s?aid=nLogin&go_url=http://Fhouse60.3g.qq.com/g/my_home.jsp'; //array_push($http_header,'Content-Type: application/x-www-form-urlencoded'); $post_data='login_url=http%3A%2F%2Fpt.3g.qq.com%2Fs%3Faid%3DnLogin%26go_url%3Dhttp%3A%2F%2FFhouse60.3g.qq.com%2Fg%2Fmy_home.jsp&sidtype=1&nopre=0&q_from=&loginTitle=%E6%89%8B%E6%9C%BA%E8%85%BE%E8%AE%AF%E7%BD%91&bid=0&go_url=http%3A%2F%2FFhouse60.3g.qq.com%2Fg%2Fmy_home.jsp&qq='.$qq.'&pwd='.urlencode($pwd).'&loginType='.$mode.'&loginsubmit=%E7%99%BB%E5%BD%95'; $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$post_url); curl_setopt($ch,CURLOPT_COOKIEJAR,$this->m_cookie_file); //curl_setopt($ch,CURLOPT_COOKIEFILE,) curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_HTTPHEADER,$http_header); curl_setopt($ch,CURLOPT_POST,1); //curl_setopt($ch,CURLOPT_HEADER,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$post_data); curl_setopt($ch,CURLOPT_ENCODING,'gzip'); $content=curl_exec($ch); //echo $content; curl_close($ch); return $this->check_login($content); } $this->m_error='已登录'; return 3; } function substring($text,$strstart,$strend,$mode=''){ //preg_match('/action="(?P<post_url>.*?sid=(?P<sid>.{24}).*?)"/',$text,$m); preg_match('/'.$strstart.'(.*?)'.$strend.'/'.$mode,$text,$m); return $m[1]; } /** * 核对验证码 * $yzm验证码 * 成功返回0,失败返回其他值 */ function check_yzm($yzm){ $this->m_yzm_post_data['verify']=$yzm; $http_header=$this->m_http_header; $ch=curl_init('http://pt.3g.qq.com'.$this->m_yzm_post_url); curl_setopt_array($ch,array(CURLOPT_POST=>1,CURLOPT_FOLLOWLOCATION=>1,CURLOPT_HEADER=>1,CURLOPT_HTTPHEADER=>$http_header,CURLOPT_RETURNTRANSFER=>1,CURLOPT_COOKIEJAR=>$this->m_cookie_file,CURLOPT_COOKIEFILE=>$this->m_cookie_file,CURLOPT_POSTFIELDS=>$this->m_yzm_post_data,CURLOPT_ENCODING=>'gzip')); $content=curl_exec($ch); curl_close($ch); return $this->check_login($content); } function check_login($content) { if(strpos($content,"不正确")) { $this->m_error="用户名或密码不正确"; return 1; } else if(strpos($content,"验证码")) { $this->m_error="需要输入或验证码不正确"; preg_match('/<img src="(?P<yzm_url>.*?)" alt="验证码"s?/?>/si',$content,$m); $this->m_yzm_url=$m['yzm_url'];//得到验证码地址 //echo $this->m_yzm_url; $reg='/<form action="(?P<posturl>.*?)"/si'; preg_match_all($reg,$content,$m); $this->m_yzm_post_url=$m['posturl'][1];//得到验证码表单发送地址 //var_dump($m); //echo $this->m_yzm_post_url; $this->m_yzm_post_data=$this->get_input_value($content,1);//得到验证码表单各个域的name=>value数组 return 2; } else { preg_match('/sid=(?P<sid>.{24})/',$content,$m); $this->m_sid=$m['sid']; $this->m_login_status=1; return 0; } } //获取表单中hidden表域的name和value值,成功返回以表单中name为key,value为值的数组,失败返回空数组 //text为需要查找的表单文本,如果有多个表单将使用index来提取对应表单 function get_input_value($text,$index=null) { if($index!=null) { $reg='/<form.*?/form>/si'; preg_match_all($reg,$text,$m); //var_dump($m); $text=$m[0][$index]; //echo $text; } $reg='/<input type="hidden" name="(?P<name>.*?)" value="(?P<value>.*?)"s?/?>/si'; preg_match_all($reg,$text,$m); //var_dump($m); $ret=array(); if($m) { for($i=0;$i<count($m['name']);$i++) { $ret[$m['name'][$i]]=$m['value'][$i]; } } //var_dump($ret); return $ret; } /* * 退出登录 * 成功返回0,失败返回1 */ function logout() { if($this->m_login_status===1) { $http_header=$this->m_http_header; $ch=curl_init('http://pt.3g.qq.com/s?sid='.$this->m_sid.'&aid=nLogout'); curl_setopt_array($ch,array(CURLOPT_FOLLOWLOCATION=>1,CURLOPT_HTTPHEADER=>$http_header,CURLOPT_RETURNTRANSFER=>1,CURLOPT_COOKIEJAR=>$this->m_cookie_file,CURLOPT_COOKIEFILE=>$this->m_cookie_file,CURLOPT_ENCODING=>'gzip')); $content=curl_exec($ch); curl_close($ch); unlink($this->m_cookie_file); $this->m_login_status=0; return 0; } else { $this->m_error="未登录"; return 1; } } /** * 改变qq聊天状态,10上线,20离线,30离开,40隐身,默认为隐身 * 成功返回0,失败返回其他值,此函数暂时不可用 */ function change_status($status='40') { if($this->m_login_status===1&&$this->m_chat_status!==0) { $post_url='http://q16.3g.qq.com/g/s?sid='.$this->m_sid; $post_data=array('s'=>$status,'aid'=>'chgStatus'); $http_header=$this->m_http_header; $http_header[]='Origin:http://q32.3g.qq.com'; $http_header[]='Referer:http://q32.3g.qq.com/g/s?sid='.$this->m_sid.'&aid=nqqStatus'; $ch=curl_init($post_url); curl_setopt_array($ch,array(CURLOPT_POST=>1,CURLOPT_FOLLOWLOCATION=>1,CURLOPT_HTTPHEADER=>$http_header,CURLOPT_RETURNTRANSFER=>1,CURLOPT_COOKIEJAR=>$this->m_cookie_file,CURLOPT_COOKIEFILE=>$this->m_cookie_file,CURLOPT_ENCODING=>'gzip',CURLOPT_POSTFIELDS=>$post_data)); $content=curl_exec($ch); curl_close($ch); echo $content; if(strpos($content,"成功")) { return 0; } } return 1; } /** * 登录3gqq,用于保持3gqq在线状态 * 成功返回0,失败返回其他值 */ function chat_login() { if($this->m_login_status===1&&$this->m_chat_status>0) { $this->m_error="已登录聊天"; return 2; } if($this->m_login_status===0) { $this->m_error="还未登录3g网"; return 1; } if($this->m_login_status===1&&$this->m_chat_status===0) { $chat_url='http://pt.3g.qq.com/s?aid=nLogin3gqqbysid&3gqqsid='.$this->m_sid; //$chat_url='http://q32.3g.qq.com/g/s?aid=nqqchatMain&sid='.$this->m_sid.'&myqq='.$this->m_qq; $http_header=$this->m_http_header; $ch=curl_init($chat_url); curl_setopt_array($ch,array(CURLOPT_FOLLOWLOCATION=>1,CURLOPT_HTTPHEADER=>$http_header,CURLOPT_RETURNTRANSFER=>1,CURLOPT_COOKIEJAR=>$this->m_cookie_file,CURLOPT_COOKIEFILE=>$this->m_cookie_file,CURLOPT_ENCODING=>'gzip')); $content=curl_exec($ch); curl_close($ch); $this->m_chat_status=2;//设置为已经登录状态 //echo $content; if(strpos($content,"sid已经过期")) { $this->m_error="sid已经过期,请重新登录"; $this->m_login_status=0; unlink($this->m_cookie_file); return 3; } } return 0; } } //以下是测试 header("Content-Type","application/xhtml+xml; charset=UTF-8"); $a=new qq(); echo $a->login('280759843','****','1'); echo $a->chat_login(); $a->logout(); ?>
一定得注意SID的有效期,祝大家好运。