<?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的更多相关文章

  1. 教程三:Wechat库的使用

    上一篇教程中我们提供了wechat的php的库,这里我们简要介绍一个这个库的源码和使用.这个库的主文件为`Wechat.php`,其余的几个文件都是为这个文件服务的,提供加解密,消息拼接等功能.`We ...

  2. 如何保存微信的小视频 How to keep WeChat 'Sights'

    微信小视频非常方便,但很难将其下载到本地电脑长期保存.网上有介绍方法,如百度经验上办法,但目前看来它可能只适用安卓系统,而且或已失效(可能由于版本更新).对Windows Phone无效,而对于更加封 ...

  3. 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 ...

  4. 开源库Magicodes.WeChat.SDK总体介绍

    目录 1    概要    1 2    主要特点    2 3    架构图    8 3.1    构造器——WeChatSDKBuilder    8 3.2    函数管理器——WeChatF ...

  5. 使用开源库MAGICODES.WECHAT.SDK进行微信公众号支付开发

    概要 博客使用Word发博,发布后,排版会出现很多问题,敬请谅解.可加群获取原始文档. 本篇主要讲解微信支付的开发流程,相关业务基于MAGICODES.WECHAT.SDK实现.通过本篇教程,您可以很 ...

  6. [转]微信公众平台WeChat PHP SDK

    地址:https://github.com/dodgepudding/wechat-php-sdk 微信公众平台php开发包,细化各项接口操作,支持链式调用 微信支付接入文档: https://mp. ...

  7. 微信和WeChat的合并月活跃账户数达到7.62亿了

    昨日,腾讯公布了截至2016年3月31日未经审核的第一季度综合业绩,其中财报显示微信和WeChat的合并月活跃账户数达到7.62亿,比去年同期增长39%.网络广告业务的收入同比增长73%至2016年第 ...

  8. 微信和WeChat的合并月活跃账户达6.97亿

    腾讯最新财报显示,微信和WeChat的合并月活跃账户于2015年底达6.97亿,同比增长39%.2016年初春节假期期间,通过微信支付收发的红包数量仅在6天内就超过320亿,同比增长9倍. 腾讯网络广 ...

  9. 微信发明人竟是他!也是WeChat/Line/WhatsApp的发明者

    赵建文,很多人不知道他是谁:说到微信大家都耳熟能详吧?没错,他就是初始微信发明人,同时也是WeChat/Line/WhatsApp的发明者!正是他的专利<一种基于或囊括手机电话本的即时通讯方法和 ...

  10. 集成 WeChat SDK - 支付篇

    作者感言 惯例, 开头都是要说些东西的了, 随着现在的App越来越商业化, 很多公司的App都会集成第三方的支付SDK, 这样子的成本就比较低, 但是呢, 有很多朋友还是不太会集成, 也不太爱看集成文 ...

随机推荐

  1. POJ-3159.Candies.(差分约束 + Spfa)

    Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submissions: 40407   Accepted: 11367 Descri ...

  2. 11.20 正则表达式 断言(?=exp)

    今天看源代码,研究了一下qz写的这个方法: // 添加逗号分隔,返回为字符串 comma: function(length) { ) length = ; var source = ('' + thi ...

  3. 51单片机学习笔记(清翔版)(13)——LED点阵、74HC595

    如图3,点阵屏分单色和彩色,点阵屏是由许多点组成的,在一个点上,只有一颗一种颜色的灯珠,这就是单色点阵屏,彩色的在一个点上有三颗灯珠,分别是RGB三原色. 图4你可能没看出来,那么大块黄色的就是点阵屏 ...

  4. 主机WiFi时,vmware ubuntu 桥接上网

    1.在vmwared软件主页的编辑->虚拟网络编辑器中,桥接模式,选择桥接至电脑的无线网卡(在主机上查询) 2.虚拟机设置中,选择桥接模式 3.ubuntu 桌面右上方edit connecti ...

  5. 如何监听Element组件<el-input>标签的回车事件

    一.现象 表单提交时需要处理输入框的回车事件,一般的原生input标签可以用@keyup.enter="onSubmit"(tips:onSubmit为定义的方法) 二.解决 1. ...

  6. [Draft]iOS.Architecture.16.Truth-information-flow-and-clear-responsibilities-immutability

    Concept: Truth, Information Flow, Clear Responsibilities and Immutability 1. Truth 1.1 Single Source ...

  7. fmt.printf输出的格式

    动 词 功 能 %v 按值的本来值输出 %+v 在 %v 基础上,对结构体字段名和值进行展开 %#v 输出 Go 语言语法格式的值 %T 输出 Go 语言语法格式的类型和值 %% 输出 % 本体 %b ...

  8. Sublime text 2/3 [Decode error - output not utf-8] 完美解决方法

    原文链接 http://blog.csdn.net/bbdxf/article/details/25594703 [Decode error - output not utf-8]或者[Decode  ...

  9. EXCEL公式及宏

    VLOOKUP特别好用的一个用于映射的公式 1.需要根据ID找到对应的NAME 2.将可以用于映射的两列放到G,H列中(注意!用于检索的要放在相对的第一列中) 3.VLOOKUP(A2,G:H,2,F ...

  10. vue2项目结构搭建

    vue2项目结构初搭建与项目基本流程 一.开始项目结构搭建的重要性 决定项目是否能够健康成长 决定了项目是否利于多人协作开发 决定了项目是否利于后期维护 决定了项目是否性能良好 决定了代码是否重用率降 ...