PHP;thinkphp框架; 关于微信公众号的一些操作:授权,access_token,自定义菜单,二维码生成,分享功能等;
写了一个关于公众号的项目,之前没有怎么好好弄过,用thinkphp框架写的,记录一下这次的经验。
首先做公众号的项目,需要申请一个公众号,然后进行一些信息的配置:
在公众号的主页底部 开发 --基本配置里面
APPID 和 AppSecret这两个信息保存着 这俩玩意是根本;
微信公众号的一些功能需要接管微信,所以就需要配置服务器配置,这个东西一旦开启,公众号菜单,聊天 自动回复什么的就不能用了,需要你去请求接口设置;
配置这块的时候需要注意: 1.url不仅仅是要写项目的域名,还想指向到微信公众号对接的控制器,方法 2.token设置的要和代码里面的一致,如果url设置的不对 会一直提示token验证失败的,对应的控制器方法后面会上代码,还有 设置完这些 一定别忘记点击启用;
复制代码:
public function verify(){//验证函数
if(isset($_GET['echostr'])){
$token=$this->token;
$timestamp=$_GET['timestamp'];
$nonce=$_GET['nonce'];
$signature=$_GET['signature'];
$echostr=$_GET['echostr'];
$arr=array($token,$timestamp,$nonce);
sort($arr);
$str=sha1(implode('',$arr));
if($str==$signature){
ob_clean();
echo $echostr;
}
}else{
$this->every();
}
}
(这个就是你前面设置url的时候需要设置的方法,假设你把这个方法放在了wechatController.php控制器里了 url就写 域名+wechat/verify 就行.)
下面是做公众号项目,肯定会用到公众号授权,用来获取用户信息之类的
$redirect_uri = urlencode('http://'.$_SERVER['HTTP_HOST'].'/wechat/getUserInfo');
//跳转微信回调到redirect_uri获取code
$url ="https://open.weixin.qq.com/connect/oauth2/authorize?appid=$this->appId&redirect_uri=$redirect_uri&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
$redirect_uri这个变量自己设置
u
r
l
是
请
求
微
信
换
取
c
o
d
e
用
的
而
url 是请求微信换取code用的 而
url是请求微信换取code用的而redirect_uri*是你换取完code,去请求的回调方法,这个方法写获取用户信息
下面是获取用户信息的方法:
$user_info 输出出来就是获取到的用户信息,获取到用户信息以后,就可以在下面自己去写一些用户操作了;
public function getUserInfo(){
//获取code
$code = $_GET["code"];
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$this->appId&secret=$this->appSecret&code=$code&grant_type=authorization_code";
$res = $this->sendRequest($url);
$access_token = $res["access_token"];
$openId = $res['openid'];
$getUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openId&lang=zh_CN";
//得到用户信息
$user_info = $this->sendRequest($getUserInfo);
}
//发送请求
public function sendRequest($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return json_decode($output, true);
}
可能有些需求是需要判断用户是否关注公众号的,如果关注了怎么怎么的,没有关注再怎么怎么的,所以也需要写个对应的方法:这个方法需要两个参数access_token 和需要验证的用户的openid,
==access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。
access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。==针对于这一点呢,我们可以把access_token这个东西存起来放到数据库,以避免多次重复请求调用,造成资源浪费;
public function guanzhu(){
$access_token = $this->getAccessToken();
$access_msg = json_decode(file_get_contents($access_token));
$token = $access_msg->access_token;
$subscribe_msg = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=$token&openid=$_GET[openid]";
$subscribe = json_decode(file_get_contents($subscribe_msg));
$gzxx = $subscribe->subscribe;
if($gzxx === 1){
echo "已关注";
}else {
echo "未关注";
}
die();
}
public function getAccessToken(){//获取token
$url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
$json=$this->sendCurl($url);
$arr=json_decode($json,true);
$token=$arr['access_token'];
//可以在这里加存储accessToken的操作,设置一个到期时间,
//(当前时间+7199秒),如果当前时间小于到期时间,就直接获取数据库的accesstoken用,
//如果对大于,则证明accesstoken过期,就获取新的accesstoken 将老的accesstoken更新掉,
//同时更新一下到期时间
}
生成二维码图片:
public function attention($uid){//生成一个带参数的二维码
$token=$this->getAccessToken();
$url='https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='.$token;
$json='{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id":'.$uid.'}}}';
$json=$this->sendCurl($url,'post',$json);
$arr=json_decode($json,true);
$ticket=urlencode($arr['ticket']);
return "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=$ticket";
}
自定义菜单:
我这里的arr数据只是举个例子,type等于view 就是跳转链接按钮,等于click就是回复关键字,菜单列表也是,按照arr的格式去写数据就行,这个方法不是写完微信那边就自动变得,需要自己请求调用一下才可以
在这里插入代码片
```public function menu(){//设置菜单
$arr=array("button"=>array(
array("type"=>"view","name"=>"测试数据","url"=>"http://www.baidu.com"),
array("name"=>"菜单列表","sub_button"=>array(
array("type"=>"view","name"=>"测试数据",'url'=>"http://www.baidu.com"),
array("type"=>"click","name"=>"测试关键字",'key'=>"123")
))
));
$json=json_encode($arr,JSON_UNESCAPED_UNICODE);
$token=$this->getAccessToken();
$url="https://api.weixin.qq.com/cgi-bin/menu/create?access_token=$token";
$json=$this->sendCurl($url,'post',$json);
return $json;
}
微信公众号分享功能:
public function ticket(){//微信分享
$token=$this->getAccessToken();
$url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$token&type=jsapi";
$res =$this->sendCurl($url);
$res = json_decode($res, true);
return $res['ticket'];
}
public function share(){
$wechat = new WechatController();
$ticket=$wechat->ticket();
$wx = array();
$wx['appid']=$wechat->appId;
$wx['jsapi_ticket']=$ticket;
$wx['noncestr']='Wm3WZYTPz0wzccnW';
$wx['timestamp']=time();
$wx['url']='http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$string="jsapi_ticket=".$wx['jsapi_ticket']."&noncestr=". $wx['noncestr']."×tamp=".$wx['timestamp']."&url=".$wx['url'];
$wx['signature']=sha1($string);
$this->assign('wx',$wx);
$wxShare=array();
//下面对应你要分享的数据 标题 图片 简介 分享页面路径
$wxShare['title']= $data['title'];
$wxShare['desc'] =strip_tags($data['info']);
$wxShare['imgurl']= str_replace("\\","/",'http://'.$_SERVER['HTTP_HOST'].$data['img']);
$wxShare['url']='分享页面路径';
$this->assign('wxShare',$wxShare);
}
//前端页面代码 复制即可 js是微信那边的js 一定要引用!
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
wx.config({
debug : false,
appId : '{$wx.appid}',
timestamp : '{$wx.timestamp}',
nonceStr : '{$wx.noncestr}',
signature : '{$wx.signature}',
jsApiList : ['updateAppMessageShareData','updateTimelineShareData']
});
wx.ready(function(){
var
s_title = '{$wxShare.title}', // 分享标题
s_link = '{$wxShare.url}', // 分享链接
s_desc = '{$wxShare.desc}', //分享描述
s_imgUrl = '{$wxShare.imgurl}'; // 分享图标
//朋友圈
wx.updateTimelineShareData({
title: s_title, // 分享标题
link: s_link, // 分享链接
imgUrl: s_imgUrl, // 分享图标
success: function () {
},
cancel: function () {}
});
//发送给好友
wx.updateAppMessageShareData({
title: s_title, // 分享标题
desc: s_desc, // 分享描述
link: s_link, // 分享链接
imgUrl: s_imgUrl, // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
},
cancel: function () {}
});
});
</script>
END…