php实现微信模拟登陆、获取用户列表及群发消息功能示例


Posted in PHP onJune 28, 2017

本文实例讲述了php实现微信模拟登陆、获取用户列表及群发消息功能。分享给大家供大家参考,具体如下:

<?php
header('Content-Type: text/html; charset=UTF-8');
/*
调用方式简单说明:
 $arr = array(
  'account' => '公众平台帐号',
  'password' => '密码'
);
$w = new Weixin($arr);
print_r($w->getAllUserInfo());//获取所有用户信息
$w->getUserInfo($groupid, $fakeid);//获取所有用户信息,如果默认分组,则$groupid传0
$w->sendMessage('群发内容'); //群发给所有用户
$w->sendMessage('群发内容',$userId); //群发给特定用户,这里的$userId就是用户的fakeid,数组方式传递
*/
class Weixin {
  public $userFakeid;//所有粉丝的fakeid
  private $_account;//用户名
  private $_password;//密码
  private $url;//请求的网址
  private $send_data;//提交的数据
  private $getHeader = 0;//是否显示Header信息
  private $token;//公共帐号TOKEN
  private $host = 'mp.weixin.qq.com';//主机
  private $origin = 'https://mp.weixin.qq.com';
  private $referer;//引用地址
  private $cookie;
  private $pageSize = 100000;//每页用户数(用于读取所有用户)
  private $userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0';
  public function __construct($options){
    $this->_account = isset($options['account'])?$options['account']:'';
    $this->_password = isset($options['password'])?$options['password']:'';
    $this->login();
  }
  //登录
  private function login(){
    $url = 'https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN';
    $this->send_data = array(
      'username' => $this->_account,
      'pwd' => md5($this->_password),
      'f' => 'json'
    );
    $this->referer = "https://mp.weixin.qq.com/";
    $this->getHeader = 1;
    $result = explode("\n",$this->curlPost($url));
    foreach ($result as $key => $value) {
      $value = trim($value);
      if (preg_match('/token=(\d+)/i', $value,$match))
      {
        //获取token
        $this->token = trim($match[1]);
      }
      if (preg_match('/"ret":(.*)/i', $value,$match)){//获取token
        switch ($match[1]) {
          case -1:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"系统错误")));
          case -2:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"帐号或密码错误")));
          case -3:
            die(urldecode(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>urlencode("密码错误")))));
          case -4:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"不存在该帐户")));
          case -5:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"访问受限")));
          case -6:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"需要输入验证码")));
          case -7:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"此帐号已绑定私人微信号,不可用于公众平台登录")));
          case -8:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"邮箱已存在")));
          case -32:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"验证码输入错误")));
          case -200:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"因频繁提交虚假资料,该帐号被拒绝登录")));
          case -94:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"请使用邮箱登陆")));
          case 10:
            die(json_encode(array('status'=>1,'errCode'=>$match[1],'msg'=>"该公众会议号已经过期,无法再登录使用")));
          case 0:
            $this->userFakeid = $this->getUserFakeid();
            break;
        }
      }
      if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $value,$match)){//获取cookie
        $this->cookie .=$match[1].'='.$match[2].'; ';
      }
    }
  }
  //单发消息
  private function send($fakeid,$content){
    $url = 'https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response&lang=zh_CN';
    $this->send_data = array(
        'type' => 1,
        'f' => 'json',
        'action' => 'sync',
        'content' => $content,
        'tofakeid' => $fakeid,
        'token' => $this->token,
        'ajax' => 1,
      );
    $this->referer = 'https://mp.weixin.qq.com/cgi-bin/singlemsgpage?token='.$this->token.'&fromfakeid='.$fakeid.'&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN';
    return $this->curlPost($url);
  }
  //群发消息
  public function sendMessage($content='',$userId='') {
    if(is_array($userId) && !empty($userId)){
      foreach($userId as $v){
        $json = json_decode($this->send($v,$content));
        if($json->ret!=0){
          $errUser[] = $v;
        }
      }
    }else{
      foreach($this->userFakeid as $v){
        $json = json_decode($this->send($v['fakeid'],$content));
        if($json->ret!=0){
          $errUser[] = $v['fakeid'];
        }
      }
    }
    //共发送用户数
    $count = count($this->userFakeid);
    //发送失败用户数
    $errCount = count($errUser);
    //发送成功用户数
    $succeCount = $count-$errCount;
    $data = array(
      'status'=>0,
      'count'=>$count,
      'succeCount'=>$succeCount,
      'errCount'=>$errCount,
      'errUser'=>$errUser
    );
    return json_encode($data);
  }
  //获取所有用户信息
  public function getAllUserInfo(){
    foreach($this->userFakeid as $v){
      $info[] = $this->getUserInfo($v['groupid'],$v['fakeid']);
    }
    return $info;
  }
  //获取用户信息
  public function getUserInfo($groupId,$fakeId){
    $url = "https://mp.weixin.qq.com/cgi-bin/getcontactinfo?t=ajax-getcontactinfo&lang=zh_CN&fakeid={$fakeId}";
    $this->getHeader = 0;
    $this->referer = 'https://mp.weixin.qq.com/cgi-bin/contactmanagepage?token='.$this->token.'&t=wxm-friend&lang=zh_CN&pagesize='.$this->pageSize.'&pageidx=0&type=0&groupid='.$groupId;
    $this->send_data = array(
      'token'=>$this->token,
      'ajax'=>1
    );
    $message_opt = $this->curlPost($url);
    return $message_opt;
  }
  //获取所有用户fakeid
  private function getUserFakeid(){
    ini_set('max_execution_time',600);
    $pageSize = 1000000;
    $this->referer = "https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token={$this->token}";
    $url = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize={$pageSize}&pageidx=0&type=0&groupid=0&token={$this->token}&lang=zh_CN";
    $user = $this->vget($url);
    $preg = "/\"id\":(\d+),\"nick_name\"/";
    preg_match_all($preg,$user,$b);
    $i = 0;
    foreach($b[1] as $v)
    {
      $arr[$i]['fakeid'] = $v;
      $arr[$i]['groupid'] = 0;
      $i++;
    }
    return $arr;
  }
  /**
   * curl模拟登录的post方法
   * @param $url request地址
   * @param $header 模拟headre头信息
   * @return json
   */
  private function curlPost($url) {
    $header = array(
      'Accept:*/*',
      'Accept-Charset:GBK,utf-8;q=0.7,*;q=0.3',
      'Accept-Encoding:gzip,deflate,sdch',
      'Accept-Language:zh-CN,zh;q=0.8',
      'Connection:keep-alive',
      'Host:'.$this->host,
      'Origin:'.$this->origin,
      'Referer:'.$this->referer,
      'X-Requested-With:XMLHttpRequest'
    );
    $curl = curl_init(); //启动一个curl会话
    curl_setopt($curl, CURLOPT_URL, $url); //要访问的地址
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header); //设置HTTP头字段的数组
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); //对认证证书来源的检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); //从证书中检查SSL加密算法是否存在
    curl_setopt($curl, CURLOPT_USERAGENT, $this->userAgent); //模拟用户使用的浏览器
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); //使用自动跳转
    curl_setopt($curl, CURLOPT_AUTOREFERER, 1); //自动设置Referer
    curl_setopt($curl, CURLOPT_POST, 1); //发送一个常规的Post请求
    curl_setopt($curl, CURLOPT_POSTFIELDS, $this->send_data); //Post提交的数据包
    curl_setopt($curl, CURLOPT_COOKIE, $this->cookie); //读取储存的Cookie信息
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); //设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HEADER, $this->getHeader); //显示返回的Header区域内容
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //获取的信息以文件流的形式返回
    $result = curl_exec($curl); //执行一个curl会话
    curl_close($curl); //关闭curl
    return $result;
  }
  private function vget($url){ // 模拟获取内容函数
    $header = array(
        'Accept: */*',
        'Connection: keep-alive',
        'Host: mp.weixin.qq.com',
        'Referer: '.$this->referer,
        'X-Requested-With: XMLHttpRequest'
    );
    $useragent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0';
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header); //设置HTTP头字段的数组
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
    curl_setopt($curl, CURLOPT_USERAGENT, $useragent); // 模拟用户使用的浏览器
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
    curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
    curl_setopt($curl, CURLOPT_HTTPGET, 1); // 发送一个常规的GET请求
    curl_setopt($curl, CURLOPT_COOKIE, $this->cookie); // 读取上面所储存的Cookie信息
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HEADER, $this->getHeader); // 显示返回的Header区域内容
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
    $tmpInfo = curl_exec($curl); // 执行操作
    if (curl_errno($curl)) {
      // echo 'Errno'.curl_error($curl);
    }
    curl_close($curl); // 关闭CURL会话
    return $tmpInfo; // 返回数据
  }
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php下判断数组中是否存在相同的值array_unique
Mar 25 PHP
PHP为表单获取的URL 地址预设 http 字符串函数代码
May 26 PHP
利用PHP实现智能文件类型检测的实现代码
Aug 02 PHP
PHP实现多进程并行操作的详解(可做守护进程)
Jun 18 PHP
基于CakePHP实现的简单博客系统实例
Jun 28 PHP
PHP会员找回密码功能的简单实现
Sep 05 PHP
PHP strcmp()和strcasecmp()的区别实例
Nov 05 PHP
php 类中的常量、静态属性、非静态属性的区别
Apr 09 PHP
Laravel中的Auth模块详解
Aug 17 PHP
PHP实现分布式memcache设置web集群session同步的方法
Apr 10 PHP
PHP设计模式之适配器模式(Adapter)原理与用法详解
Dec 12 PHP
PHP 扩展Memcached命令用法实例总结
Jun 04 PHP
Symfony2针对输入时间进行查询的方法分析
Jun 28 #PHP
Symfony查询方法实例小结
Jun 28 #PHP
关于PHP转换超过2038年日期出错的问题解决
Jun 28 #PHP
YII2自动登录Cookie总是失效的解决方法
Jun 28 #PHP
php的常量和变量实例详解
Jun 27 #PHP
Zend Framework框架中实现Ajax的方法示例
Jun 27 #PHP
PHP用continue跳过本次循环中剩余代码的注意点
Jun 27 #PHP
You might like
PHP多个版本的分析解释
2011/07/21 PHP
SSO单点登录的PHP实现方法(Laravel框架)
2016/03/23 PHP
PHP使用openssl扩展实现加解密方法示例
2020/02/20 PHP
window.open被浏览器拦截后的自定义提示效果代码
2007/11/19 Javascript
javascript 混合的构造函数和原型方式,动态原型方式
2009/12/07 Javascript
jquery1.4 教程二 ajax方法的改进
2010/02/25 Javascript
Javascript实现仿WebQQ界面的“浮云”兼容 IE7以上版本及FF
2011/04/27 Javascript
Javascript实现简单的富文本编辑器附演示
2014/06/16 Javascript
javascript实现的平方米、亩、公顷单位换算小程序
2014/08/11 Javascript
基于javascript实现单选及多选的向右和向左移动实例
2015/07/25 Javascript
jQuery解析json数据实例分析
2015/11/24 Javascript
JS通过Cookie判断页面是否为首次打开
2016/02/05 Javascript
ExtJS 4.2 Grid组件单元格合并的方法
2016/10/12 Javascript
Javascript将字符串日期格式化为yyyy-mm-dd的方法
2016/10/27 Javascript
vue-quill-editor实现图片上传功能
2017/08/08 Javascript
nodejs简单读写excel内容的方法示例
2018/03/16 NodeJs
JavaScript遍历DOM元素的常见方式示例
2019/02/16 Javascript
前端开发之便利店收银系统代码
2019/12/27 Javascript
详解JavaScript修改注册表的方法
2020/01/05 Javascript
修改vue源码实现动态路由缓存的方法
2020/01/21 Javascript
javascript使用canvas实现饼状图效果
2020/09/08 Javascript
html+vue.js 实现漂亮分页功能可兼容IE
2020/11/07 Javascript
[04:00]黄浦江畔,再会英雄——完美世界DOTA2 TI9应援视频
2019/07/31 DOTA
Python实现从url中提取域名的几种方法
2014/09/26 Python
python中requests模块的使用方法
2015/04/08 Python
Python队列的定义与使用方法示例
2017/06/24 Python
利用python和ffmpeg 批量将其他图片转换为.yuv格式的方法
2019/01/08 Python
台湾旅游网站:雄狮旅游网
2017/08/16 全球购物
德国领先的大尺码和超大尺码男装在线零售商:Bigtex
2019/06/22 全球购物
学生的自我鉴定范文
2013/10/24 职场文书
暑期培训随笔感言
2014/03/10 职场文书
另类冲刺标语
2014/06/24 职场文书
承德避暑山庄导游词
2015/02/03 职场文书
大学毕业论文致谢词
2015/05/14 职场文书
运动会100米广播稿
2015/08/19 职场文书
SQL Server代理:理解SQL代理错误日志处理方法
2021/06/30 SQL Server