批改状态:合格
老师批语:
微信公众号被动回复图文消息
回复文字消息
回复图文消息
输入任意文字,回复hello你好啊;输入图文消息,回复相应的消息;输入附近,根据用户的地理位置,调用高德地图的api
搜索附近5000m的超市,返回前3个结果,以图文的消息回复用户。
application\index\controller\Weixin.php
<?php
namespace app\index\controller;
use think\Controller;
use think\facade\Cache;
class Weixin extends Controller
{
public function __construct(){
parent::__construct();
$this->model=model('Weixin');
}
public function index()
{
$valid=$this->model->valid();
if(!$valid){
exit('signature error');
}
$xmldata=file_get_contents("php://input");
/*
$xmldata='<xml><ToUserName><![CDATA[gh_f10a1709655b]]></ToUserName>
<FromUserName><![CDATA[o9i9i0TUiPy3hlFgcVk2lswL9T_U]]></FromUserName>
<CreateTime>1527982562</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[]]></EventKey>
</xml>';
*/
// xml transfer object
$postObj=simplexml_load_string($xmldata,'SimpleXMLElement',LIBXML_NOCDATA);
$data=(array)$postObj;
// file_put_contents('D://subs.txt',var_export($data,true));
// dump($data['FromUserName']);
if(isset($data['MsgType']) && $data['MsgType'] == 'event'){
//subscribe
if($data['Event'] == 'subscribe'){
$this->model->subscribe($data);
}
//unsubscribe
if($data['Event'] == 'unsubscribe'){
$this->model->unsubscribe($data);
return 'unsubscribe ok';
}
if($data['Event'] == 'LOCATION'){
$this->model->location($data);
// file_put_contents('d://locate.txt',var_export($data,true));
exit('success');
}
}
// file_put_contents('d://msg.txt',$data);
// 回复文本消息
if(isset($data['MsgType']) && $data['MsgType'] == 'text'){
$this->robot($data);
exit('success');
}
// exit(input('get.echostr'));
}
public function get_access_token($iscache=true){
$cache_key='access_token';
if(!$iscache){
Cache::rm($cache_key);
}
$data=Cache::get($cache_key);
if($data && $iscache){
return $data;
}
$appid=config('app.appid');
$appsecret=config('app.APPSECRET');
$url='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret;
$res=http_Get($url);
// dump($res);
$res=json_decode($res,true);
// dump($res);
if(!isset($res[$cache_key])){
return false;
}
Cache::set($cache_key,$res['access_token'],($res['expires_in']-600));
return $res[$cache_key];
}
public function custom_menu(){
$access_token=$this->get_access_token();
if(!$access_token){
exit('access_token get failed');
}
$url='https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.$access_token;
$data = '{
"button":[
{
"type":"view",
"name":"Home",
"url":"http://scottshen.top/"
},
{
"type":"view",
"name":"视频教程",
"url":"http://www.baidu.com"
},
{
"name":"用户info",
"sub_button":[
{
"type":"view",
"name":"用户信息",
"url":"http://881c65b6.ngrok.io/index.php/index/weixin/auth"
},
{
"type":"view",
"name":"用户地理位置",
"url":"http://881c65b6.ngrok.io/index.php/index/weixin/location"
}]
}]
}';
$res=http_Post($url,$data);
dump($res);
}
public function auth(){
// halt(config('app.APPID'));
$appid=config('app.appid');
$redirect='http://881c65b6.ngrok.io/index.php/index/weixin/userinfo';
$url_code = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.urlEncode($redirect)
.'&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect';
header('Location:'.$url_code);
}
public function userinfo(){
// dump(config('app.APPID'));
$code=input('get.code');
// dump($code);
$res=$this->model->auth_access_token($code);
// dump($res);
$auth_access_token=$res['access_token'];
$openid=$res['openid'];
// dump($auth_access_token);
$userinfo=$this->model->get_userinfo($auth_access_token,$openid);
dump($userinfo);
}
public function location(){
$data['appid']=config('app.appid');
$data['timestamp']=time();
$data['nonceStr']=md5(time().rand(1,999));
//生成签名
$access_token=$this->get_access_token();
$jsapi_ticket=$this->model->jsapi_ticket($access_token);
//签名字符串
//noncestr s小写,查了好久这个问题,报invalid signature,
//拼接字符串是noncestr
$parmas['noncestr']=$data['nonceStr'];
$parmas['jsapi_ticket']=$jsapi_ticket;
$parmas['timestamp']=$data['timestamp'];
$parmas['url']="http://881c65b6.ngrok.io/index.php/index/weixin/location";
ksort($parmas,SORT_STRING);
// dump($parmas);
$str=urldecode(http_build_query($parmas));
//生成签名
$data['signature']=sha1($str);
// dump(sha1($str));
// dump($data['signature']);
return $this->fetch('',$data);
}
private function robot($data){
if($data['Content'] == '图文消息'){
$response=$this->model->img_article_msg($data);
exit($response);
}
if($data['Content'] == '附近'){
$response=$this->model->near_shops($data['FromUserName'],$data['ToUserName'],5000);
// exit($response);
exit($response);
}
//调用聊天机器人
$response=$this->model->robot($data);
/*
$response='<xml> <ToUserName>'.$data['FromUserName']
.'</ToUserName> <FromUserName>'.$data['ToUserName']
.'</FromUserName> <CreateTime>'.time().'</CreateTime> <MsgType>text</MsgType>
<Content>hello</Content> </xml>';
*/
exit($response);
}
public function tests(){
$params['appid'] = '10001';
$key = '4fa92702a0633127d26ba957d97680ab';
$params['timestamp'] = time();
$params['msg'] = input('get.msg');
ksort($params);
$str = http_build_query($params);
$sign = sha1($str.$key);
dump($sign);
$url = 'http://tests.php.cn/index.php/weixintest/robot?'.$str.'&sign='.$sign;
$res = http_get($url);
$res = json_decode($res,true);
dump($res);
}
}点击 "运行实例" 按钮查看在线实例
application\index\model\Weixin.php
<?php
namespace app\index\model;
use think\Model;
use think\Db;
use think\facade\Cache;
class Weixin extends Model
{
public function valid()
{
$signature=input('get.signature');
// $signature='c5052967c11f8d7e59c3b4011407b94c697b1ceb';
// var_dump($signature);
$timestamp=input('get.timestamp');
// $timestamp='1527896867';
$nonce=input('get.nonce');
// $nonce='3010175004';
$echostr=input('get.echostr');
// $echostr='9044276551450221539';
$token=config('app.token');
// file_put_contents('d://data.txt','signature='.$signature.' timestmp='.$timestamp.' nonce='.$nonce.' echostr='.$echostr);
$tmpArr=array($timestamp,$nonce,$token);
sort($tmpArr,SORT_STRING);
// dump($tmpArr);
$tmpStr=implode($tmpArr);
// echo $tmpStr;
// $tmpStr=sha1($tmpStr);
//
if(sha1($tmpStr) != $signature){
// exit('error');
return false;
}
// 首次接入成功需要输出$echostr
// exit($echostr);
return true;
}
//网页授权access_tonken
public function auth_access_token($code){
$appid=config('app.appid');
$appsecret=config('app.APPSECRET');
$url='https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.
$appsecret.'&code='.$code.'&grant_type=authorization_code';
$res=http_Get($url);
$res=json_decode($res,true);
if(!isset($res['access_token'])){
return false;
}
return $res;
}
public function get_userinfo($auth_access_token,$openid){
$url='https://api.weixin.qq.com/sns/userinfo?access_token='.
$auth_access_token.'&openid='.
$openid.'&lang=zh_CN';
$res=http_Get($url);
$res=json_decode($res,true);
return $res;
}
public function subscribe($data){
dump($data['FromUserName']);
$user=Db::table('wechat')
->where('openid',$data['FromUserName'])
->find();
// halt($user);
// 新关注用户
if(!$user){
$data=['openid'=>$data['FromUserName'],
'sub_status'=>1,
'add_time'=>time(),
];
Db::table('wechat')
->insertGetId($data);
} else {
Db::table('wechat')
->where('openid',$data['FromUserName'])
->update(['sub_status'=>1]);
}
}
public function unsubscribe(){
Db:table('wechat')
->where('openid',$data['FromUserName'])
->update(['sub_status'=>0]);
}
// 获取jsai_ticket
public function jsapi_ticket($access_token,$iscache=true){
$key='jsapi_ticket';
if(!$iscache){
Cache::rm($key);
}
$data=Cache::get($key);
if($data && $iscache){
return $data;
}
$appid=config('app.appid');
$appsecret=config('app.APPSECRET');
$url='https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.
$access_token.'&type=jsapi';
$res=http_Get($url);
$res=json_decode($res,true);
if(!isset($res['ticket'])){
return false;
}
Cache::set($key,$res['ticket'],$res['expires_in']-100);
return $res['ticket'];
}
public function robot($data){
/*
$config=config('app.robot');
$params['appid']=$config['appid'];
$key=$config['key'];
$params['timestamp']=time();
$parmas['msg']=$data['Content'];
ksort($parmas);
$str=http_build_query($parmas);
$sign=sha1($str.$key);
$url = 'http://tests.php.cn/index.php/weixintest/robot?'.$str.'&sign='.$sign;
$res=http_Get($url);
$res=json_decode($res,true);
$res['msg']=str_replace('{br}',"\n",$res['msg']);
*/
$response='<xml> <ToUserName>'.$data['FromUserName']
.'</ToUserName> <FromUserName>'.$data['ToUserName']
.'</FromUserName> <CreateTime>'.time().
'</CreateTime> <MsgType>text</MsgType> <Content>hello你好啊</Content> </xml>';
// file_put_contents('d:\\robot.txt',$response);
return $response;
}
public function img_article_msg($data){
// file_put_contents('d://imgarticle.txt',$data);
//读取图文消息
$articles=[
['title'=>'宋大牛传送门',
'description'=>'芝麻开门',
'picurl'=>'http://img.lanrentuku.com/img/allimg/1805/15270368233208.jpg',
'url'=>'haimaer.cnblogs.com',
],
['title'=>'python',
'description'=>'python好用的语言',
'picurl'=>'http://img.lanrentuku.com/img/allimg/1804/15249056684370.jpg',
'url'=>'www.python.org',
],
];
$xml=$this->build_img_text_msg($data['FromUserName'],$data['ToUserName'],$articles);
return $xml;
}
private function build_img_text_msg($from,$to,$data){
$str='<xml><ToUserName>'.$from
.'</ToUserName><FromUserName>'.$to
.'</FromUserName><CreateTime>'.time()
.'</CreateTime><MsgType>news</MsgType><ArticleCount>'.count($data).'</ArticleCount><Articles>';
foreach ($data as $item){
$str.='<item><Title>'.$item['title']
.'</Title> <Description>'.$item['description']
.'</Description><PicUrl>'.$item['picurl']
.'</PicUrl><Url>'.$item['url'].'</Url></item>';
}
$str.='</Articles></xml>';
// file_put_contents('d://build.txt',$str);
return $str;
}
// 附近的店铺,默认5公里的超市,显示3条结果
/*
*$from 微信用户
$to 开发者
*/
public function near_shops($from,$to,$distance=5000){
$query=Db::table('wechat')->where('openid',$from)
->find();
$url='http://restapi.amap.com/v3/place/around?key='.
config('app.amap').'&location='.$query['longitude'].','.$query['latitude'].'&keywords=超市&radius='.$distance.'&offset=3';
file_put_contents('d://url.txt',$url);
$res=http_Get($url);
file_put_contents('d://response.txt',$res);
//xml to objcet
$json=json_decode($res,true);
file_put_contents('d://res.txt',var_export($json,true));
$market=$json['pois'];
$shop_list=[];
if(!isset($market)){
$shop_list=[
'title'=>'暂无数据',
'description'=>'你来到了火星',
'picurl'=>'',
'url'=>'',
];
$xml=$this->build_img_text_msg($from,$to,$shop_list);
return $xml;
}
foreach($market as $item){
$inline_list=[
'title'=>$item['name'],
'description'=>'地址:'.$item['address']
.' 距离(m):'.$item['distance'],
'picurl'=>'',
'url'=>'',
];
array_push($shop_list,$inline_list);
}
file_put_contents('d://market.txt',var_export($shop_list,true));
/*
$shop_list=[
[
'title'=>'123',
'description'=>'456',
'picurl'=>'',
'url'=>'http://www.baidu.com',
]
];
*/
$xml=$this->build_img_text_msg($from,$to,$shop_list);
file_put_contents('d://xml.txt',$xml);
return $xml;
}
//少写了::
public function location($data){
Db::table('wechat')->where('openid',$data['FromUserName'])
->update(['longitude'=>$data['Longitude'],'latitude'=>$data['Latitude']]);
}
}点击 "运行实例" 按钮查看在线实例
效果


Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号