接触微信,其实不难,网上找的例子,封装的好,但是对于不第一次用的感觉不好上手,就简单封装了一个,上手后用其他的应该特别简单了
类文件:wechat.php
<?php
namespace Org;
class wechat
{
public $appId;
public $appSecret;
public $accessToken;
public $url;
public $json;
public $jsConfig;
/*
*@param array $config
*/
public function __construct($config){
$this->appId = $config['appId'];
$this->appSecret = $config['appSecret'];
//access_token处理
$this->getAccessToken();
$this->url = $this->getUrl();
if(!isset($_GET['code'])){//不存在
$this->getCode($this->url);
}else{
$code = $_GET['code'];
$this->json = $this->atokenOpenid($code);
$this->jsConfig();
}
}
/**
* 获取url
**/
public function getUrl(){
return $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
}
/**
* 获取网页code
* @param string $redirect_url 跳转url
* @param string $state 业务传参
**/
public function getCode($redirect_url=null, $state=123){
$redirect_url = urlencode($redirect_url);
$url= sprintf('https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=%s#wechat_redirect', $this->appId, $redirect_url, $state);
header("Location:".$url);
}
/* 获取用户信息公众平台接口(不关注的情况,用code后的accesstoken获取)
* @param string openid
* @param string accesstoken(code换取的accesstoken)
* @return josn
*/
public function userInfo($openid=null, $accesstoken){
$url = sprintf('https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN',$accesstoken,$openid);
$json = $this->request($url);
return $json;
}
/* 获取用户信息(关注的情况)
* @param string openid
* @param string accesstoken(初始accesstoken)
* @return josn
*/
public function fansUserInfo($openid=null){
$this->getAccesstoken();
$url = sprintf('https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN',$this->accessToken,$openid);
$json = $this->request($url);
return $json;
}
/**
*批量获取用户基本信息(关注用户才能得到信息)
* {
"user_list": [
{
"openid": "otvxTs4dckWG7imySrJd6jSi0CWE",
"lang": "zh_CN"
},
{
"openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg",
"lang": "zh_CN"
}
]
}
*/
public function wxUserLists($json='')
{
$arr = [
'user_list' =>[
[
'openid' => 'o7HAi1G3Axj48D5JvQ_173-NryYo',
'lang' => 'zh_CN',
]
],
];
$json = json_encode($arr);
$this->getAccesstoken();
$url = 'https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token='.$this->accessToken;
$json = $this->request( $url, true, 'post',$json );
return $json;
}
/**
* 获取Access_Token,用户Openid
*/
public function atokenOpenid($code = null){
$url = sprintf('https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code',$this->appId,$this->appSecret,$code);
$json = $this->request($url);
return $json;
}
/**
* 入口accessToken获取
*/
public function getAccessToken(){
$res = file_get_contents('access_token.json');
$result = json_decode($res, true);
if (time() > ($result["expires_time"] + 3600)){
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$this->appId."&secret=".$this->appSecret;
$res = $this->request($url);
$result = json_decode($res, true);
$access_token = $result["access_token"];
$expires_time = time();
file_put_contents('access_token.json', '{"access_token": "'.$result["access_token"].'", "expires_time": '.$result["expires_time"].'}');
}
$this->accessToken = $result["access_token"];
}
/**htpp请求
* curl 请求的URL
* https 是否HTTP请求
* method 请求方式
* data 请求参数
*/
public function request( $curl, $https=true, $method='get', $data=null){
$ch = curl_init();//初始化
curl_setopt($ch, CURLOPT_URL, $curl);//设置访问的URL
curl_setopt($ch, CURLOPT_HEADER, false);//设置不需要头信息
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//只获取页面内容,但不输出
if($https){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//不做服务器认证
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//不做客户端认证
}
if($method == 'post'){
curl_setopt($ch, CURLOPT_POST, true);//设置请求是POST方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//设置POST请求的数据
}
$str = curl_exec($ch);//执行访问,返回结果
curl_close($ch);//关闭curl,释放资源
return $str;
}
/*
* wechat的js配置
*/
public function jsConfig(){
$res = file_get_contents('jsapi_ticket.json');
$result = json_decode($res, true);
if (time() > ($result["expires_time"] + 3600)){
$url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$this->accessToken.'&type=jsapi';
$res = $this->request($url);
$result = json_decode($res, true);
$access_token = $result["access_token"];
$expires_time = time();
file_put_contents('jsapi_ticket.json', '{"ticket": "'.$result["ticket"].'", "expires_time": '.$result["expires_time"].'}');
}
/*参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分)jntu*/
$config['timestamp'] = time();
$config['noncestr'] = 123456;
$config['url'] = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$config['jsapi_ticket'] = $result["ticket"];
$config['signature'] = sha1('jsapi_ticket='.$config['jsapi_ticket'].'&noncestr='.$config['noncestr'].'×tamp='.$config['timestamp'].'&url='.$config['url']);
$this->jsConfig = $config;
}
}
这里需要两个保存临时access_token的文件,具体看微信文档【微信中有2个不同access_token,好坑,后面接口用的是第一的,所以要提前保存起来】
涉及到view中调用wx的一些交互动作,当中用到jsapi_ticket,所以这里保存一个临时文件
即在wechat类同级下保存2个txt文件:access_token.txt和jsapi_ticket.txt,当然你可以保存到你想要的路径,修改一下读取的路径即可
直接调用
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public $wechatModel;
public $config;
public function __construct()
{
parent::__construct();
$this->config = [
'appId' => '你的appid',
'appSecret' => '你的appSecret'
];
}
//http://cc.d7f.cn/single/index.php/home/index/index/openid=o7HAi1CkRZoGbllRLICY6WbXQ9OA&a=111
public function index(){
$this->wechatModel = new \Org\wechat($this->config);
$param = json_decode($this->wechatModel->json);
//如果已经分享过则跳到拯救页面
$res = D('Help')->isShareHelp($param->openid);
if($res){
$this->redirect('home/index/helpping',['openid'=>$param->openid]);
}else{ //未分享
$json = $this->wechatModel->userInfo($param->openid, $param->access_token);
$obj = json_decode($json,true);
$this->assign('obj',$obj); //用户信息
$this->assign('jsConfig',$this->wechatModel->jsConfig); //js配置
$this->display('jion');
}
}
}
view中调用js, 当中需要加载微信的公共js,加密一定要在server完成,ajax不可以
<script type="text/javascript" src="__PUBLIC__/js/jquery.min.js"></script>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script>
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'wxdd73f45f2044ffa0', // 必填,公众号的唯一标识
timestamp: '<?= $jsConfig['timestamp'];?>', // 必填,生成签名的时间戳
nonceStr: '<?= $jsConfig['noncestr'];?>', // 必填,生成签名的随机串
signature: '<?= $jsConfig['signature'];?>',// 必填,签名,见附录1
jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
wx.onMenuShareTimeline({
title: '逃出狗笼大作战', // 分享标题
link: 'http://cc.d7f.cn/single/index.php/home/index/demo?id=11111', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
});
</script>