wechat.php
<?php
/**
*Author @zhongbo
* 步骤说明
* 1,微信服务器返回一个会话ID
* 2.通过会话ID获得二维码
* 3.轮询手机端是否已经扫描二维码并确认在Web端登录
* 4.访问登录地址,获得uin和sid
* 5.初使化微信信息
* 6.获得所有的好友列表
* 7.保持与服务器的信息同步
* 8.获得别人发来的消息
* 9.向用户发送消息
**/
class wechat {
/**
* uuid 微信服务器返回的会话id
**/
private $uuid = '';
/**
* loginUrl 扫描二维码并确认后返回的登录url
**/
private $loginUrl = '';
/**
* toLingUrl 图灵机器人api
**/
private $tlApi = 'http://www.tuling123.com/openapi/api';
private $tlAppkey = '820176b52352471a943d73a8c304ad32';
/**
* 发起GET请求
*
* @access public
* @param string $url
* @return string
*/
function get($url = '', $cookie = '')
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
if($cookie){
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt ($ch, CURLOPT_REFERER,'https://wx.qq.com');
}
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
/**
* 发起POST请求
*
* @access public
* @param string $url
* @param array $data
* @return string
*/
public function post($url, $data = '', $cookie = '', $type = 0)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
if($cookie){
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt ($ch, CURLOPT_REFERER,'https://wx.qq.com');
}
if($type){
$header = array(
'Content-Type: application/json',
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
/**
* 获取当前时间戳精确到毫秒级
*
* @access private
* @return string
*
**/
private function getMillisecond()
{
list($usec, $sec) = explode(" ", microtime());
return (float)sprintf('%.0f',(floatval($usec)+floatval($sec))*1000);
}
/**
* 获取微信服务器返回的一个会话ID
*
* @access public
* @return string
**/
public function getUuid(){
$url = 'https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_='.$this->getMillisecond();
$str = $this->get($url);
preg_match('/"(.*?)"/',$str,$match);
$_SESSION['uuid'] = $match[1];
return $match[1];
}
/**
* 通过会话ID获得二维码
* @access public
* @return string
**/
public function getQrcode($uuid){
$url = 'https://login.weixin.qq.com/qrcode/'.$uuid.'?t=webwx';
return "<img src='$url' />";
}
/**
* 轮询手机端是否已经扫描二维码并确认在Web端登录
* @access public
* @param $uuid string 用户会话id
* @return mixed
**/
public function getLoginStatus($uuid = ''){
$url = sprintf("https://login.wx2.qq.com/cgi-bin/mmwebwx-bin/login?uuid=%s&tip=1&_=%s", $uuid, $this->getMillisecond());
$res = $this->get($url);
preg_match('/=(.*?);/',$res,$match);
if($match[1] == 200){
//登陆成功
preg_match('/redirect_uri="(.*?)";/',$res,$match2);
return $match2[1];
}
return $match[1];
}
/**
* 访问登录地址,获得uin和sid,并且保存cookies
* @access public
* @param $url string 登录地址
* @return array
**/
public function getCookies($url){
$cookie_jar = dirname(__FILE__)."/".$_SESSION['uuid'].".cookie";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_HEADER,1);//如果你想把一个头包含在输出中,
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//将 curl_exec()获取的信息以文件流的形式返回,而不是直接输出。设置为0是直接输出
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);//获取的cookie 保存到指定的 文件路径
$content=curl_exec($ch);
if(curl_errno($ch)){
$info = array('status' => 0, 'msg' => 'Curl error: '.curl_error($ch));
return $info;//这里是设置个错误信息的反馈
}
if($content==false){
$info = array('status' => 0, 'msg' => '无法获取cookies');
return $info;//这里是设置个错误信息的反馈
}
//正则匹配出wxuin、wxsid
preg_match('/wxuin=;/iU',$content,$uin);
preg_match('/wxsid=(.*);/iU',$content,$sid);
preg_match('/webwx_data_ticket=(.*);/iU',$content,$webwx);
//@TODO将wxuin、wxsid、webwx_data_ticket存入cookies,以便获取微信头像----暂无效
/*if(preg_match_all('/Set-Cookie:[\s]+([^=]+)=([^;]+)/i', $content,$match)) {
foreach ($match[1] as $key => $cookieKey ) {
setcookie($cookieKey,$match[2][$key],'36000','','.wx.qq.com');
}
}*/
//将wxuin、wxsid、webwx_data_ticket存入session
$_SESSION['uin'] = @$uin[1];
$_SESSION['sid'] = @$sid[1];
$wxinfo = array(
'uin' => @$uin[1],
'sid' => @$sid[1]
);
curl_close($ch);
return $wxinfo;
}
/**
* 登录成功,初始化微信信息
* @access public
* @param $uin string 用户uin
* @param $sid string 用户sid
* @return mixed
**/
public function initWebchat($uin = '', $sid = ''){
$cookie_jar = dirname(__FILE__)."/".$_SESSION['uuid'].".cookie";
$url = sprintf("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=%s", $this->getMillisecond());
if(!$uin || !$sid){
$uin = $_SESSION['uin'];
$sid = $_SESSION['sid'];
}
$data['BaseRequest'] = array(
'Uin' => $uin,
'Sid' => $sid,
'Skey' => '',
'DeviceID' => 'e189320295398756'
);
$res = $this->post($url, json_encode($data),$cookie_jar);
//将登陆用户username、nickname存入session中
$user = json_decode($res, true);
$_SESSION['username'] = $user['User']['UserName'];
$_SESSION['nickname'] = $user['User']['NickName'];
return $res;
}
/**
* 获取全部联系人
* @access public
* @param $uin string 用户uin
* @param $sid string 用户sid
* @return mixed
**/
public function getContact($uin = '', $sid = ''){
$cookie_jar = dirname(__FILE__)."/".$_SESSION['uuid'].".cookie";
$url = sprintf("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&r=%s&seq=0", $this->getMillisecond());
if(!$uin || !$sid){
$uin = $_SESSION['uin'];
$sid = $_SESSION['sid'];
}
$res = $this->post($url, '{}',$cookie_jar);
return $res;
}
/**
* 登录成功,保持与服务器的信息同步,获取是否有推送消息等
* @access public
* @param $synckey string
* @return mixed
**/
public function wxsync($synckey){
$uin = $_SESSION['uin'];
$sid = $_SESSION['sid'];
$cookie_jar = dirname(__FILE__)."/".$_SESSION['uuid'].".cookie";
$url = sprintf("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=%s", $sid);
$data['BaseRequest'] = array(
'Uin' => $uin,
'Sid' => $sid,
'Skey' => '',
'DeviceID' => 'e189320295398756'
);
$data['SyncKey'] = json_decode($synckey);
$data['rr'] = time();
$res = $this->post($url, json_encode($data),$cookie_jar);
return $res;
}
/**
* 发送消息
* @access public
* @param $toUsername string
* @return mixed
**/
public function sendMessage($toUsername = '', $content = ''){
$uin = $_SESSION['uin'];
$sid = $_SESSION['sid'];
$cookie = dirname(__FILE__)."/".$_SESSION['uuid'].".cookie";
$url = sprintf("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?sid=%s&r=%s",$sid,$this->getMillisecond());
$data['BaseRequest'] = array(
'Uin' => $uin,
'Sid' => $sid,
'Skey' => "",
'DeviceID' => "e287276317582836"
);
$data['Msg'] = array(
'ClientMsgId' => $this->getMillisecond(),
'Content' => $content,
'FromUserName' => $_SESSION['username'],
'LocalID' => $this->getMillisecond(),
'ToUserName' => $toUsername,
'Type' => 1
);
$data['Scene'] = 0;
//json_encode JSON_UNESCAPED_UNICODE防止将汉字转义为unicode字符
$res = $this->post($url, json_encode($data,JSON_UNESCAPED_UNICODE),$cookie);
return $res;
}
/**
* 获取头像
* @access public
* @param $uri string 头像地址
* @return mixed
**/
public function getAvatar($uri = ''){
$cookie = dirname(__FILE__)."/".$_SESSION['uuid'].".cookie";
$url = "https://wx.qq.com".$uri;
$res = $this->get($url, $cookie);
echo $res;
}
/**
* 图灵机器人 =》文本
* @access public
* @param $toUsername string
* @return mixed
**/
public function sendMessageToTuling($content = ''){
$data = array(
'key' => $this->tlAppkey,
'info' => $content,
'userid' => '123456789'
);
$res = $this->post($this->tlApi,json_encode($data,JSON_UNESCAPED_UNICODE),'',1);
$r = json_decode($res,true);
//文本类
if(isset($r['url'])){
//存在链接则发送链接
return $r['url'];
}
return $r['text'];
}
//转换为UTF-8
public function characet($data){
if( !empty($data) ){
$fileType = mb_detect_encoding($data , array('UTF-8','GBK','LATIN1','BIG5')) ;
if( $fileType != 'UTF-8'){
$data = mb_convert_encoding($data ,'utf-8' , $fileType);
}
}
return $data;
}
}
wechat.php的更多相关文章
- 教程三:Wechat库的使用
上一篇教程中我们提供了wechat的php的库,这里我们简要介绍一个这个库的源码和使用.这个库的主文件为`Wechat.php`,其余的几个文件都是为这个文件服务的,提供加解密,消息拼接等功能.`We ...
- 如何保存微信的小视频 How to keep WeChat 'Sights'
微信小视频非常方便,但很难将其下载到本地电脑长期保存.网上有介绍方法,如百度经验上办法,但目前看来它可能只适用安卓系统,而且或已失效(可能由于版本更新).对Windows Phone无效,而对于更加封 ...
- win环境 yii2 框架 overtrue/wechat 包 由 sys_get_temp_dir 引发的 the directory "c:\Windows" is not writable
vendor\overtrue\wechat\src\Foundation\Application.php registerBase 方法 在初始化属性时 $this['cache'] = funct ...
- 开源库Magicodes.WeChat.SDK总体介绍
目录 1 概要 1 2 主要特点 2 3 架构图 8 3.1 构造器——WeChatSDKBuilder 8 3.2 函数管理器——WeChatF ...
- 使用开源库MAGICODES.WECHAT.SDK进行微信公众号支付开发
概要 博客使用Word发博,发布后,排版会出现很多问题,敬请谅解.可加群获取原始文档. 本篇主要讲解微信支付的开发流程,相关业务基于MAGICODES.WECHAT.SDK实现.通过本篇教程,您可以很 ...
- [转]微信公众平台WeChat PHP SDK
地址:https://github.com/dodgepudding/wechat-php-sdk 微信公众平台php开发包,细化各项接口操作,支持链式调用 微信支付接入文档: https://mp. ...
- 微信和WeChat的合并月活跃账户数达到7.62亿了
昨日,腾讯公布了截至2016年3月31日未经审核的第一季度综合业绩,其中财报显示微信和WeChat的合并月活跃账户数达到7.62亿,比去年同期增长39%.网络广告业务的收入同比增长73%至2016年第 ...
- 微信和WeChat的合并月活跃账户达6.97亿
腾讯最新财报显示,微信和WeChat的合并月活跃账户于2015年底达6.97亿,同比增长39%.2016年初春节假期期间,通过微信支付收发的红包数量仅在6天内就超过320亿,同比增长9倍. 腾讯网络广 ...
- 微信发明人竟是他!也是WeChat/Line/WhatsApp的发明者
赵建文,很多人不知道他是谁:说到微信大家都耳熟能详吧?没错,他就是初始微信发明人,同时也是WeChat/Line/WhatsApp的发明者!正是他的专利<一种基于或囊括手机电话本的即时通讯方法和 ...
- 集成 WeChat SDK - 支付篇
作者感言 惯例, 开头都是要说些东西的了, 随着现在的App越来越商业化, 很多公司的App都会集成第三方的支付SDK, 这样子的成本就比较低, 但是呢, 有很多朋友还是不太会集成, 也不太爱看集成文 ...
随机推荐
- 统一集中管理系统cronsun简介,替代crontab
一.背景 crontab 是 Linux 系统里面最简单易用的定时任务管理工具,相信绝大多数开发和运维都用到过.在咱们公司,很多业务系统的定时任务都是通过 crontab 来定义的,时间长了后会发现存 ...
- UnitZ Battlegrounds beta5 - Unity吃鸡类型游戏模版 源码 仿绝地求生
Requires Unity 2018.2.6 or higher.The first battle royale game starter kit on Asset Store, all syste ...
- 【C++】undered_map的用法总结(1)
1.介绍 unordered_map是一个关联容器,内部采用的是hash表结构,拥有快速检索的功能. 1.1 特性 关联性:通过key去检索value,而不是通过绝对地址(和顺序容器不同)无序性:使用 ...
- ios 根据 schemes 打开 app
公司出需求,要让 h5链接直接打开用户的 app,如果没有安装 app 直接跳转到 appStore 这就需要给 app 配置 schemes 即可 1.在Info.plist中 LSApplicat ...
- 移值UCOS2到M4核与M3核的区别
之前移值过ucos2到stm32f2系列的单片机,这个单片机是属于arm的m3内核的.最近在学习永磁同步电机的控制,对于这个电机的控制,有比较多的数学计算,甚至于还有浮点的运算.所以用到了stm32f ...
- HYSBZ 2743 (树状数组) 采花
题目:这里 题意: 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记, ...
- Opecv + Anaconda 读取视频(windows)
前言:之前一直用的是python(x,y),但是发现在使用opencv时容易出现一些pythonw.exe停止工作的问题.后来发现自己的操作系统是64位的,却安装了32位的python(x,y),虽然 ...
- 关于egg.js的安全延伸思考
我看到全部的安全基于围绕http来操作,那么如果我只用websocket传输数据,是不是就会好很多?
- 201771010134杨其菊《面向对象程序设计java》第十二周学习总结
第十二周学习总结 第一部分:理论知识 内容概要: AWT与Swing简介:框架的创建:图形程序设计: 显示图像: 1.AWT组件: 2.Swing 组件层次关系 3 .AWT与Swing的关系:大部分 ...
- Codeforces Round #436 (Div. 2)D. Make a Permutation! 模拟
D. Make a Permutation! time limit per test: 2 seconds memory limit per test: 256 megabytes input: st ...