首页 » 微信公众平台开发:从零基础到ThinkPHP5高性能框架实践 » 微信公众平台开发:从零基础到ThinkPHP5高性能框架实践全文在线阅读

《微信公众平台开发:从零基础到ThinkPHP5高性能框架实践》6.6.2 同步所有用户信息

关灯直达底部

很多时候,公众号需要将微信用户的信息导出到自己的服务器上。其实现流程如下。

首先设计一个表,用于存储用户的基本信息。创建表的SQL语句如下。


CREATE TABLE IF NOT EXISTS 'tp_user' (    'id' bigint(9) NOT NULL AUTO_INCREMENT COMMENT '序号',    'openid' varchar(30) NOT NULL COMMENT '微信id',    'nickname' varchar(20) NOT NULL COMMENT '昵称',    'sex' varchar(4) NOT NULL COMMENT '性别',    'country' varchar(10) NOT NULL COMMENT '国家',    'province' varchar(16) NOT NULL COMMENT '省份',    'city' varchar(16) NOT NULL COMMENT '城市',    'headimgurl' varchar(200) NOT NULL COMMENT '头像',    'subscribe' varchar(15) NOT NULL COMMENT '关注时间',    PRIMARY KEY ('id'),    UNIQUE KEY 'openid' ('openid')) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;  

在微信类文件中,定义获取用户列表及获取用户基本信息的接口。


 1 class class_weixin 2 { 3     var $appid = APPID; 4     var $appsecret = APPSECRET; 5  6     // 构造函数,获取Access Token 7     public function __construct($appid = NULL, $appsecret = NULL) 8     { 9         if($appid && $appsecret){10             $this->appid = $appid;11             $this->appsecret = $appsecret;12         }13         // 缓存形式14         if (isset($_SERVER['HTTP_APPNAME'])){                // SAE环境,需要开通memcache15             $mem = memcache_init();16         }else {                                                // 本地环境,须安装memcache17             $mem = new Memcache;18             $mem->connect('localhost', 11211) or die ("Could not connect");19         }20         $this->access_token = $mem->get($this->appid);21         if (!isset($this->access_token) || empty($this->access_token)){22             $url = "https:// api.weixin.qq.com/cgi-bin/token?grant_type=client_creden               tial&appid=".$this->appid."&secret=".$this->appsecret;23             $res = $this->http_request($url);24             $result = json_decode($res, true);25             $this->access_token = $result["access_token"];26             $mem->set($this->appid, $this->access_token, 0, 3600);27         }28     }29 30     // 获取用户列表31     public function get_user_list($next_openid = NULL)32     {33         $url = "https:// api.weixin.qq.com/cgi-bin/user/get?access_token=".$this->       access_token."&next_openid=".$next_openid;34         $res = $this->http_request($url);35         $list = json_decode($res, true);36         if ($list["count"] == 10000){37             $new = $this->get_user_list($next_openid = $list["next_openid"]);38             $list["data"]["openid"] = array_merge_recursive($list["data"]["open               id"], $new["data"]["openid"]); // 合并OpenID列表39         }40         return $list;41     }42 43     // 获取用户基本信息44     public function get_user_info($openid)45     {46         $url = "https:// api.weixin.qq.com/cgi-bin/user/info?access_token=".$this->           access_token."&openid=".$openid."&lang=zh_CN";47         $res = $this->http_request($url);48         return json_decode($res, true);49     }50 51     // HTTP请求(支持HTTP/HTTPS,支持GET/POST)52     protected function http_request($url, $data = null)53     {54         $curl = curl_init();55         curl_setopt($curl, CURLOPT_URL, $url);56         curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);57         curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);58         if (!empty($data)){59             curl_setopt($curl, CURLOPT_POST, 1);60             curl_setopt($curl, CURLOPT_POSTFIELDS, $data);61         }62         curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);63         $output = curl_exec($curl);64         curl_close($curl);65         return $output;66     }67 }  

在获取用户列表的实现过程中,使用了递归函数。首先获取10000名用户的列表(第33~35行),如果发现本次统计的OpenID数为10000(第36行),一般意味着还有没有拉取到的用户,这时就将本次取得的netx_openid作为递归中的起始OpenID(第37行)。当取到新的用户OpenID列表时,将新的OpenID列表合并到上次取得的OpenID列表中(第38行)。

数据库类文件的实现如下。


 1 class class_mysql 2 { 3     function __construct(){ 4         $host = MYSQLHOST; 5         $port = MYSQLPORT; 6         $user = MYSQLUSER; 7         $pwd =  MYSQLPASSWORD; 8         $dbname = MYSQLDATABASE; 9         $link = @mysql_connect("{$host}:{$port}", $user, $pwd, true);10         mysql_query("SET NAMES 'UTF8'");11         mysql_select_db($dbname, $link);12     }13 14     // 执行SQL15     function query($sql)16     {17         if (!($query = mysql_query($sql))){18             return $query;19         }20         return $query;21     }22     23     // 返回数组24     function query_array($sql){25         $result = mysql_query($sql);26         if(!$result)return false;27         $arr = array();28         while ($row = mysql_fetch_array($result)) {29             $arr[] = $row;30         }31         return $arr;32     }33 } 

上述代码解读如下。

第3~12行:类的构造函数,主要功能是连接数据库,设置字符集,选择要连接的数据库。

第15~21行:执行原生的SQL语句。

第24~32行:执行SQL语句,并将结果以数组的形式返回。

上述准备工作做好之后,就开始获取用户列表,并将每个用户的OpenID存到数据库中,代码如下。


 1 require_once('weixin.class.php'); 2 $weixin = new class_weixin(); 3  4 require_once('mysql.class.php'); 5 $db = new class_mysql(); 6  7 // 拉取用户列表 8 $userlist = $weixin->get_user_list(); 9 for($i = 0; $i < count($userlist["data"]["openid"]); $i++)10 {11     $openid = $userlist["data"]["openid"][$i];12     $mysql_state = "INSERT INTO 'tp_user' ('id', 'openid') VALUES (NULL, '".$open       id."');";13     $result = $db->query($mysql_state);14 }  

更新用户信息的代码如下。


 1 <?php 2 header("Content-type: text/html; charset=utf-8"); 3  4 require_once('weixin.class.php'); 5 $weixin = new class_weixin(); 6  7 require_once('mysql.class.php'); 8 $db = new class_mysql(); 9 10 $mysql_state = "SELECT * FROM 'tp_user' WHERE 'subscribe' = '' LIMIT 0, 1";11 $result = $db->query_array($mysql_state);12 13 $sexes = array("", "男", "女");14 if (count($result) > 0){15     $openid = $result[0]["openid"];16     var_dump($openid);17     $info = $weixin->get_user_info($openid);18     var_dump($info);19     $mysql_state2 = "UPDATE 'tp_user' SET 20         'sex' = '".$sexes[$info['sex']]."', 21         'country' = '".$info['country']."', 22         'province' = '".$info['province']."', 23         'city' = '".$info['city']."', 24         'headimgurl' = '".$info['headimgurl']."',25         'subscribe' = '".$info['subscribe_time']."'26         WHERE 'openid' = '".$openid."';";27     $result = $db->query($mysql_state2);28     $mysql_state3 = "UPDATE 'tp_user' SET 'nickname' = '".$info['nickname']."'        WHERE 'openid' = '".$openid."';";29     $result = $db->query($mysql_state3);30     echo "<script language=JavaScript> location.replace(location.href);</script>";31 }else{32     echo "over";33 }  

上述代码解读如下。

第2行:设置编码为UTF-8,以便显示内容的页面不会乱码。

第4~8行:包含数据库类文件及微信类文件。

第10~11行:检索一个没有更新用户信息的记录,这里以subscribe字段为空作为检测条件。

第13~30行:如果记录存在,则读取这个记录的OpenID,并查询该用户的基本信息,然后将除了昵称之外的所有信息写入数据库,之后再将昵称更新到数据库。完成之后,使用JavaScript将该页面刷新进行下一个用户记录的更新。

第31~33行:如果没有要更新的用户记录,则返回一个提示。

用户同步到服务器后的记录如图6-2所示。

图6-2 同步到服务器的用户信息列表