微信接口:
//http请求方式: GET(请使用https协议)
https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
接口文档:获取用户列表
问题:
1.如果有新用户关注或者旧用户取消关注是否会影响openid列表的顺序?
答:没有具体文档说清楚。
2.之前取回来的用户列表,过了几天,有用户取消关注,也有新用户关注了,用之前缓存的列表最后一个openid作为next_openid参数,能否能取到所有新增用户的openid?
答:有可能取不到。
在实际应用中,并不能用next_openid无法实现增量同步,那我们可以换个思路来实现,用接口的openid列表与已同步的openid列表作差异 对比,同步数据库中没有的用户信息。
以下是我用Yii2写的控制台程序样本,实现了增量同步,在几万用户数据的情况下运行效率相当不错。
getServiceMpuser();
$this->getBookMpuser();
}
/**
* 全量同步
*/
public function actionSyncMpuserAll()
{
$all = true;
$this->getServiceMpuser($all);
$this->getBookMpuser($all);
}
/**
*
*/
public function getServiceMpuser($all = false)
{
date_default_timezone_set("Asia/Shanghai");
echo 'Check service user data.' . date('Y-m-d H:i:s') . PHP_EOL;
$next_openid = '';
$openids =[];
$total = 0;
do{$openidsRes = Mp::getServiceOpenids($next_openid);
// var_dump($openidsRes);exit;
if(isset($openidsRes->errcode)){
echo 'errcode:' .$openidsRes->errcode . ', errmsg:' . $openidsRes->errmsg . PHP_EOL;
break;
}
$total = $openidsRes->total;
$next_openid = $openidsRes->next_openid;
if($openidsRes->count > 0){
$openids = array_merge($openids,$openidsRes->data->openid);
}
}while($next_openid && $next_openid !='');
//新数据比对
if(!$all){
//取出数据库有的openid
$database_openids_sql = WechatMpuser::find()->where(['platform_type'=>WechatMpuser::PLATFORM_TYPE_SERVICE])
->select(['openid']);
// var_dump($database_openids_sql->createCommand()->getRawSql());exit;
$database_openids = $database_openids_sql->column();
// var_dump($database_openids);exit;
if($total > 0 && $total == count($openids)){
$new_openids = array_diff($openids,$database_openids);
}
else{
$new_openids = [];
}
}
else{
$new_openids = $openids;
}
// print_r($new_openids);exit;
//入库
foreach ($new_openids as $val){
$userInfo = Mp::getServiceUserinfo($val, '');
// var_dump($userInfo);
if(isset($userInfo->unionid) && $userInfo->unionid != ''){
$form = WechatMpuser::findOne(['unionid'=>$userInfo->unionid,'platform_type'=>WechatMpuser::PLATFORM_TYPE_SERVICE]);
if(!$form){
$form = new WechatMpuser();
}
$form->openid = $userInfo->openid;
$form->subscribe = $userInfo->subscribe;
$form->unionid = $userInfo->unionid;
$form->nickname = base64_encode($userInfo->nickname);
$form->sex = $userInfo->sex;
$form->city = $userInfo->city;
$form->province = $userInfo->province;
$form->country = $userInfo->country;
$form->headimgurl = $userInfo->headimgurl;
$form->subscribe_time = $userInfo->subscribe_time;
$form->add_time = time();
$form->platform_type = WechatMpuser::PLATFORM_TYPE_SERVICE;
$res = $form->save();
$saveMessage = $res?'success':'fail';
echo $saveMessage .': ' . 'service openid->' . $val . ',nickname->' . base64_decode($form->nickname) . PHP_EOL;
}
elseif(isset($userInfo->subscribe) && $userInfo->subscribe==0){
//删除取关的用户
WechatMpuser::deleteAll(['openid'=>$val,'platform_type'=>WechatMpuser::PLATFORM_TYPE_SERVICE]);
$saveMessage = 'fail,not subscribe';
echo $saveMessage .': ' . 'service openid->' . $val . PHP_EOL;
}
elseif(isset($userInfo->errcode) && $userInfo->errcode == 40003 ){
$saveMessage = $userInfo->errmsg;
echo $saveMessage .': ' . 'service openid->' . $val . PHP_EOL;
}
else{
//删除取关的用户
WechatMpuser::deleteAll(['openid'=>$val,'platform_type'=>WechatMpuser::PLATFORM_TYPE_SERVICE]);
$saveMessage = $userInfo->errmsg;
echo $saveMessage .': ' . 'service openid->' . $val . PHP_EOL;
}
}
$saveMessage = 'Synchronization completed, impact: '.count($new_openids).' data.';
echo $saveMessage . PHP_EOL;
}
/**
*
*/
public function getBookMpuser($all = false)
{
date_default_timezone_set("Asia/Shanghai");
echo 'Check book user data.' . date('Y-m-d H:i:s') . PHP_EOL;
$next_openid = '';
$openids =[];
$total = 0;
do{$openidsRes = Mp::getBookOpenids($next_openid);
// var_dump($openidsRes);
if(isset($openidsRes->errcode)){
echo 'errcode:' .$openidsRes->errcode . ', errmsg:' . $openidsRes->errmsg . PHP_EOL;
break;
}
$total = $openidsRes->total;
$next_openid = $openidsRes->next_openid;
if($openidsRes->count > 0){
$openids = array_merge($openids,$openidsRes->data->openid);
}
}while($next_openid && $next_openid !='');
//新数据比对
if(!$all){
//取出数据库有的openid
$database_openids_sql = WechatMpuser::find()->where(['platform_type'=>WechatMpuser::PLATFORM_TYPE_BOOK])
->select(['openid']);
// var_dump($database_openids_sql->createCommand()->getRawSql());exit;
$database_openids = $database_openids_sql->column();
// var_dump($database_openids);exit;
if($total > 0 && $total == count($openids)){
$new_openids = array_diff($openids,$database_openids);
}
else{
$new_openids = [];
}
}
else{
$new_openids = $openids;
}
// print_r($new_openids);exit;
//入库
foreach ($new_openids as $val){
$userInfo = Mp::getBookUserinfo($val, '');
// var_dump($userInfo);
if(isset($userInfo->unionid) && $userInfo->unionid != ''){
$form = WechatMpuser::findOne(['unionid'=>$userInfo->unionid,'platform_type'=>WechatMpuser::PLATFORM_TYPE_BOOK]);
if(!$form){
$form = new WechatMpuser();
}
$form->openid = $userInfo->openid;
$form->subscribe = $userInfo->subscribe;
$form->unionid = $userInfo->unionid;
$form->nickname = base64_encode($userInfo->nickname);
$form->sex = $userInfo->sex;
$form->city = $userInfo->city;
$form->province = $userInfo->province;
$form->country = $userInfo->country;
$form->headimgurl = $userInfo->headimgurl;
$form->subscribe_time = $userInfo->subscribe_time;
$form->add_time = time();
$form->platform_type = WechatMpuser::PLATFORM_TYPE_BOOK;
$res = $form->save();
$saveMessage = $res?'success':'fail';
echo $saveMessage .': ' . 'book openid->' . $val . ',nickname->' . base64_decode($form->nickname) . PHP_EOL;
}
elseif(isset($userInfo->subscribe) && $userInfo->subscribe==0){
//删除取关的用户
WechatMpuser::deleteAll(['openid'=>$val,'platform_type'=>WechatMpuser::PLATFORM_TYPE_BOOK]);
$saveMessage = 'fail,not subscribe';
echo $saveMessage .': ' . 'book openid->' . $val . PHP_EOL;
}
elseif(isset($userInfo->errcode) && $userInfo->errcode == 40003 ){
//删除取关的用户
WechatMpuser::deleteAll(['openid'=>$val,'platform_type'=>WechatMpuser::PLATFORM_TYPE_BOOK]);
$saveMessage = $userInfo->errmsg;
echo $saveMessage .': ' . 'book openid->' . $val . PHP_EOL;
}
else{
$saveMessage = $userInfo->errmsg;
echo $saveMessage .': ' . 'book openid->' . $val . PHP_EOL;
}
}
$saveMessage = 'Synchronization completed, impact: '.count($new_openids).' data.';
echo $saveMessage . PHP_EOL;
}
}
写在最后:
该接口有调用次数限制,详见 接口调用频次限制说明