从今天起,本人对接的微信公众服务号开发,采取的阿里云服务器+阿里云备案域名方案,可以达到真实开发环境
这里分享一下经验:重点::现在租云服务器(阿里云,腾讯云,百度云都要,除非买香港免备案,略贵)要有备案域名才能建站,所以大家可以买二手备案域名也就几十元一年,。
部署云服务器坑也多,光系统都换了三个,最低配置的云服务器用WIN2003,32位的流畅。。之后就是域名没备案,弄半天备案也没成功。只能买一个。。跟着装COMPOSER THINKPHP5.1各种报错,各种百度,各种修复,,心累!!最好没办法,直接本地下载,复制到服务器,成功解决。。
这里介绍一个本地复制到服务器的方法,个人觉得比FTP方便,实时更新文件
微信公众号开发:自定义菜单
自定义菜单规则:
1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。
3、创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
创建自定义菜单接口步骤:
1,向微信发出GET请求,获取access-token,用模型中的access_token()方法:并判断获取成功与否。
public function diy_menu(){ $access_token = $this->model->access_token(); if (!$access_token) { exit('access_token获取失败'); } }
2,接口调用http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
public function diy_menu(){ $access_token = $this->model->access_token(); if (!$access_token) { exit('access_token获取失败'); } $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.$access_token; $data = '{ <--自定义菜单--> }'; $res = http_Post($url,$data); dump($res); }
在这里我们用到的是http_Post方法,同样直接采用官方的写法,写入公共文件中:common.php
// 应用公共文件 function http_Post($url,$data){ $curl = curl_init(); curl_setopt($curl,CURLOPT_URL,trim($url)); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); //启用时会发送一个常规的POST请求,为1或者为true if(!empty($data)){ $data = is_array($data)?json_encode($data):$data; curl_setopt($curl,CURLOPT_POST,1); curl_setopt($curl,CURLOPT_POSTFIELDS,$data);//需要要传送的内容 } curl_setopt($curl,CURLOPT_RETURNTRANSFER,1); $return_str = curl_exec($curl); curl_close($curl); return $return_str; } function http_Get($url){ $curl = curl_init(); curl_setopt($curl,CURLOPT_URL,trim($url)); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl,CURLOPT_HEADER,0); curl_setopt($curl,CURLOPT_CUSTOMREQUEST,'GET');//需要要传送的内容 curl_setopt($curl,CURLOPT_RETURNTRANSFER,1); $return_str = curl_exec($curl); curl_close($curl); return $return_str; }
此处,GET方法和POST的区别在于:POST方法带有单独参数$data 我们用$data写各类型的自定义菜单,
例如:后续我们会把$data写成一个变量,然后通过后台来设定菜单按钮的类型和内容
$data = '{ "button":[ { "name":"一级菜单A", "sub_button":[ { "type":"view", "name":"二级菜单A", "url":"http://www.baidu.com/" }, { "type":"view", "name":"二级菜单B", "url":"http://www.baidu.com" }, { "type":"view", "name":"二级菜单C", "url":"http://www.baidu.com" }, { "type":"view", "name":"二级菜单D", "url":"http://www.baidu.com" }, { "type":"view", "name":"二级菜单E", "url":"http://www.baidu.com" }] }, { "type":"click", "name":"一级菜单B", "key":"v002_no2menu" }, { "type":"click", "name":"一级菜单C", "key":"v003_no3menu" }] }';
自定义菜单接口可实现多种类型按钮:各类型按钮的请求方法,请参考微信公众平台官方开发文档
1、click:点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
2、view:跳转URL用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
3、scancode_push:扫码推事件用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息。
4、scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。
5、pic_sysphoto:弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。
6、pic_photo_or_album:弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。
7、pic_weixin:弹出微信相册发图器用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。
8、location_select:弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。
9、media_id:下发消息(除文本消息)用户点击media_id类型按钮后,微信服务器会将开发者填写的永久素材id对应的素材下发给用户,永久素材类型可以是图片、音频、视频、图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
10、view_limited:跳转图文消息URL用户点击view_limited类型按钮后,微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL,永久素材类型只支持图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
各类型按钮的请求参数说明
button 一级菜单数组,个数应为1~3个 sub_button 二级菜单数组,个数应为1~5个
type 菜单的响应动作类型,view表示网页类型,click表示点击类型,miniprogram表示小程序类型
name 菜单标题,不超过16个字节,子菜单不超过60个字节
key click等点击类型必须 菜单KEY值,用于消息接口推送,不超过128字节
url view、miniprogram类型必须 网页 链接,用户点击菜单可打开链接,不超过1024字节。 type为miniprogram时,不支持小程序的老版本客户端将打开本url。
media_id media_id类型和view_limited类型必须 调用新增永久素材接口返回的合法media_id
appid miniprogram类型必须 小程序的appid(仅认证公众号可配置)
pagepath miniprogram类型必须 小程序的页面路径
3,返回结果:
正确时的返回JSON数据包:{"errcode":0,"errmsg":"ok"}
错误时的返回JSON数据包:(示例为无效菜单名长度):{"errcode":40018,"errmsg":"invalid button name size"}
成功效果图
微信公众号开发:获取网页授权
用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。
1. 修改授权回调域名:先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,授权回调域名配置规范为全域名,进行OAuth2.0鉴权。
这里需要注意两点:1). 授权域名一定要是备案域名 2).下载官方验证文件到项目根目录中
2. 网页授权的两种scope的区别:scope 获取用户信息的范围
1)、以snsapi_base为scope发起的网页授权,就是用户关注进入公众号平台,后台静默授权只能获取用户openid,用户自动跳转到回调页\业务页面的。
2)、以snsapi_userinfo为scope发起的网页授权,就是可通过openid拿到昵称、性别、所在地。但这种授权需要用户手动同意,并且无须关注,就可在授权后获取该用户的基本信息。
3)、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。
获取网页授权的步骤:
先自定义一个菜单点击事件:
$data = '{ "button":[ { "name":"功能菜单C", "sub_button":[ { "type":"view", "name":"用户中心", "url":"http://11e16.cn/index.php/index/weixin/user" }, }] }';
此处注意:"url":"http://11e16.cn/index.php/index/weixin/auth" user 对接 public function user() 中 user()
一,用户同意授权,获取code
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect';
其中有几个参数需要修改添加:
APPID 公众号的唯一标识 = = confing('app.appid')
REDIRECT_URI 授权后重定向的回调链接地址 == $redirect = 'http://11e16.cn/index.php/weixintest/userinfo';
REDIRECT_URI 一定要与网页授权域名一致。。
用 urlEncode 对链接进行处理 urlEncode($redirect)
SCOPE 用授权作用域 == snsapi_base (不弹出授权页面), snsapi_userinfo (弹出授权页面)
STATE 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 == 开发者自定义 可不变 STATE
public function user() { //1.用户同意授权,获取code $redirect = 'http://11e16.cn/index.php/weixintest/userinfo'; $url_code = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.config('app.appid').'&redirect_uri='.urlEncode($redirect).'&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect'; header('Location:'.$url_code); exit($url_code)//打印输出 }
结果发现在PC端打不开,只能在手机微信上能打开~~
public function user() { //1.用户同意授权,获取code $redirect = 'http://11e16.cn/index.php/index/weixin/userinfo'; $url_code = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.config('app.appid').'&redirect_uri='.urlEncode($redirect).'&response_type=code&scope=snsapi_userinfo&state=12345#wechat_redirect'; header('Location:'.$url_code); exit; } public function userinfo(){ //获取code $code = input('get.code'); exit($code);
二,通过code换取网页授权access_token
首先请注意:这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。
网页授权access_token和普通access_token的区别:
普通 access_token 是用于整个公众平台的校验的口令 可缓存 全局性 类似于一栋房子的大门钥匙
网页授权access_token是专门用于网页授权功能的口令 谨慎缓存 局部性 类似于一栋房子中一间房的房门钥匙
网页授权access_token获取方法封装在模型中:
// 网页授权access_token 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 userinfo(){ // 1. 获取code $code = input('get.code'); // 2. 通过code换取网页授权access_token $res = $this->model->auth_access_token($code,false); $auth_access_token = $res['access_token']; $openid = $res['openid']; $tmpArr = array($code,$auth_access_token,$openid);//拼接code 网页授权 用户ID dump($tmpArr);exit; }
刷新access_token(如果需要,不需要略过)
三,拉取用户信息(需scope为 snsapi_userinfo)
// 拉取用户信息 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; }
控制器中调用:根据获取到的$auth_access_token,$openid 两个参数来拉取用户基本信息
// 显示用户信息 public function userinfo(){ $userinfo = $this->model->get_userinfo($auth_access_token,$openid); dump($userinfo); }
获取到用户信息 我们就可以开发相关功能 为所欲为了
总结:逻辑分析:用户点击--用户中心--菜单,开发者后台向微信平台发出请求,获取code,再通过code获取到auth_access_token,同时拉取到用户openid,再根据openid拉取用户基本信息,展示到用户微信客户端。。