微信公众平台开发基本教程
1、概述
1.1 微信公众平台简介
微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,可以群发文字、图片、语音三个类别的内容。

微信公众号账号类型对比:

订阅号示例:

服务号示例:

1.2 公众平台注册及功能介绍
1.2.1 微信公众平台账号注册
打开网址https://mp.weixin.qq.com/,点击右上角“立即注册”

选择注册账号类型,如“订阅号”:

填写邮箱信息并依据接收到的邮件输入邮箱验证码

选择账号类型,确认后不可修改:

1.2.2 微信公众平台模式介绍
编辑模式:

编辑模式指所有的公众号运营者都可以通过简单的编辑,设置“按关键字回复”等功能。您可以设定常用的文字/语言/图片/录音作为回复消息,并制定自动回复的规则。当订阅用户的行为符合自动回复规则的时候,就会收到自动回复的消息。
开发模式

使用公众平台的开发接口,公众号可在自身服务器上接收用户的微信消息,并可按需回复。此外,微信还提供了更多更高级的功能和体验,如会话界面的自定义菜单、获取更多类型的消息等。
群发消息(1天1次)

自动回复

自动回复优先规则
- 被关注回复:用户关注公众号时将会立即收到。
- 收到消息回复:订阅用户只要对公众号发送消息便会回复,如粉丝发送的消息包含关键字将会优先关键字自动回复(如开启了全匹配,需粉丝发送与设置一样的关键字才会自动回复)。
- 关键词回复:订阅用户发送的信息含有多个设置的关键字,则会随机回复。
自定义菜单



投票



更多功能

消息管理:


1.3 公众平台九大高级接口介绍
(1)【语音识别】
通过语音识别接口,用户发送语音,将会同时给出语音识别出的文本。
【实用意义】
第三方可以调用微信自主研发的语音识别技术。意味着微信向第三方开放语音识别技术,直接调用语音识别接口,对语音识别结果进行互动或根据识别的内容进行自动答复。
(2)【客服接口】
通用客服接口,公众号可以在客户发送消息的12小时内,向用户回复信息。
【实用意义】
以前公众帐号跟客户只能被动响应,比如用户触发了需求,如发送“关键字”给公众帐号,后者才可以与用户对话。如今,如果订户跟公众帐号对话过一次,公众帐号就可以在 12 个小时内持续给用户下发消息。这提高了公众帐号发送消息的能力。
(3)【OAuth2.0网页授权】
通过网页授权接口,公众号可以请求用户授权。
【实用意义】
这就像微博、QQ 的帐号授权功能。这意味着微信帐号正式成为一个帐号系统。
(4)【生成带参数二维码】
通过接口,公众号可以获得一系列携带不同参数的二维码,在用户扫描公众号后,可以分析各二维码的效果。
【实用意义】
举例来说,以前放一个二维码在任何网站或者微博,都是为了获得关注用户。现在可以分析订户来自哪里。开发者可以在链接里设置特殊信息,做更多的数据分析。
(5)【获取用户地理位置】
通过该接口,可以获得客户进入公众号对话时的地理位置(需要用户同意)。
【实用意义】
两种情况可以获得用户地理位置:一是与公众帐号“会话时”,二是在会话界面“每隔 5 秒”。在用户同意下,这就可以做微信导航或地理围栏方面的服务。
(6)【获得用户基本信息】
通用该接口,公众号可以根据用户加密后的OpenID,获取用户基本信息,例:头像,昵称,性别,地区。
【实用意义】
以前这是一个非常高的权限。获得用户基本信息后,可以做 CRM 管理后台,方便商家管理用户。
(7)【获取关注者列表】
通过该接口,公众号可以获取所有用户的OpenID
【实用意义】
以前不能知道有多少人关注你,是谁在关注你。如今你可以知道谁在关注你。
(8)【用户分组接口】
通过分组接口,公众号可以在后台为用户移动分组,创建,修改分组
【实用意义】
可以对用户进行分组,比如小米公司组织的一场“米4”手机体验会,现场来了 100 人,可以把它归为一组,后续活动照片只发给这 100 人。这对于商家来说,就是一个 VIP 会员管理,是 CRM 管理平台。
(9)【上传下载多媒体文件】
通过该接口,公众号可以在需要时在微信服务器上传下载多媒体文件。
【实用意义】
意味着通过微信,可以分发音乐、图片等多媒体内容。比如 QQ 音乐可以在这里向订户推送音乐。
1.4 开发原理


2、环境搭建与测试
2.1 新浪SAE平台申请
https://www.sinacloud.com/



域名信息查看:


2.2 新浪SAE代码仓库管理

2.3 SVN代码管理配置
TortoiseSVN 是 Subversion 版本控制系统的一个免费开源客户端,可以超越时间的管理文件和目录。文件保存在中央版本库,除了能记住文件和目录的每次修改以外,版本库非常像普通的文件服务器。你可以将文件恢复到过去的版本,并且可以通过检查历史知道数据做了哪些修改,谁做的修改。这就是为什么许多人将 Subversion 和版本控制系统看作一种“时间机器”。

到svn主页https://tortoisesvn.net/下载svn软件,依据提示安装
在本地新建项目文件夹,点击右键,选择“SVN Checkout”

用户名与密码为新浪云用户名与密码:


- 修改完代码后,在本地项目文件夹,点击右键,选择“SVN Commit”
- 填写修改日志,并提交修改

每次修改提交后会生成新的版本编号:

2.4 对接微信公众平台


2.5 实战
2.5.1 实战1:Hello world!
功能:实现关注微信公众平台,回复“Hello world!”
主要子模块:
- 输入信息接收;
- 关注事件判断;
- 文本输出。
接收输入信息:

事件判断与文本输出:

API函数:


2.5.2 实战2:开发模式配置验证
功能:若SAE与微信平台接口连接成功,则实现“鹦鹉学舌”功能。
签名验证程序,官方加密、验证流程:
- 用户端获取token,timestamp,nonce三个关键字值;
- 将token,timestamp,nonce进行字典排序;
- 将三个字符串拼接为一个字符串,用SHA-1算法加密;
- 将加密后的字符串与用户端获取的签名比较;
- 若加密后字符串与用户端获取的签名相同,则返回用户输入内容 。
签名验证程序:

鹦鹉学舌程序:

主程序:


2.5.3 实战3:输入对象识别
功能:判别输入数据格式,以文本形式返回输入类别。
了解各种格式输入的XML包形式,包括:text, image, link, voice, location等。




3、接收消息与发送消息

3.1 接收普通消息
-
- 文本消息
-
- 图片消息
-
- 语音消息
-
- 视频消息
-
- 地理位置消息
-
- 链接消息
3.1.1 文本消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
3.1.2 图片消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<PicUrl><![CDATA[this is a url]]></PicUrl>
<MediaId><![CDATA[media_id]]></MediaId>
<MsgId>1234567890123456</MsgId>
</xml>
3.1.3 语音消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<Format><![CDATA[Format]]></Format>
<MsgId>1234567890123456</MsgId>
</xml>
3.1.4 视频消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
<MsgId>1234567890123456</MsgId>
</xml>
3.1.5 地理位置消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[location]]></MsgType>
<Location_X>23.134521</Location_X>
<Location_Y>113.358803</Location_Y>
<Scale>20</Scale>
<Label><![CDATA[位置信息]]></Label>
<MsgId>1234567890123456</MsgId>
</xml>
3.1.6 链接消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[link]]></MsgType>
<Title><![CDATA[公众平台官网链接]]></Title>
<Description><![CDATA[公众平台官网链接]]></Description>
<Url><![CDATA[url]]></Url>
<MsgId>1234567890123456</MsgId>
</xml>
3.2 发送被动回复消息
-
- 文本消息
-
- 图片消息
-
- 语音消息
-
- 视频消息
-
- 音乐消息
-
- 图文消息
3.2.1 文本消息回复

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
3.2.2 图片消息回复

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[media_id]]></MediaId>
</Image>
</xml>
3.2.3 语音消息回复

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[media_id]]></MediaId>
</Voice>
</xml>
3.2.4 视频消息回复

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<Video>
<MediaId><![CDATA[media_id]]></MediaId>
<Title><![CDATA[title]]></Title>
<Description><![CDATA[description]]></Description>
</Video>
</xml>
3.2.5 音乐消息回复

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
<Music>
<Title><![CDATA[TITLE]]></Title>
<Description><![CDATA[DESCRIPTION]]></Description>
<MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
<HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
<ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
</Music>
</xml>
3.2.6 图文消息回复

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[title1]]></Title>
<Description><![CDATA[description1]]></Description>
<PicUrl><![CDATA[picurl]]></PicUrl>
<Url><![CDATA[url]]></Url>
</item>
</Articles>
</xml>
3.3 接收事件推送消息
3.3.1 关注/取消关注

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
</xml>
3.3.2 扫描带参数二维码

用户未关注:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[qrscene_123123]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>
用户已关注:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[SCAN]]></Event>
<EventKey><![CDATA[SCENE_VALUE]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>
3.3.3 上报地理位置

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[LOCATION]]></Event>
<Latitude>23.137466</Latitude>
<Longitude>113.352425</Longitude>
<Precision>119.385040</Precision>
</xml>
3.3.4 自定义菜单

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[CLICK]]></Event>
<EventKey><![CDATA[EVENTKEY]]></EventKey>
</xml>
3.3.5 点击菜单跳转链接

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[VIEW]]></Event>
<EventKey><![CDATA[www.qq.com]]></EventKey>
</xml>
3.4 案例实践
3.4.1 线上调试工具
微信公众平台接口开发调试系统:http://www.fangbei.org/tool/message

PHP线上调试系统:http://code.php.net.cn/ywye96g

3.4.2 实战1:口袋图鉴


3.4.2 实战2:实时天气查询
和风天气API接口说明:https://dev.heweather.com/docs/api/weather



4、Access Token与自定义菜单
4.1 Access Token
Access Token是调用其他高级接口的钥匙,是微信公众号的全局唯一票据。微信公众号可以使用AppID和AppSecret调用微信接口获得Access Token。
接口调用请求说明:
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s

$APPID = 'wx8835e91271001450';
$APPSECRET = '9049664c299784871ba144afa0792b6b';
$urlTmp = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';
$url = sprintf($urlTmp, $APPID, $APPSECRET);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$accessToken = curl_exec($ch);
curl_close($ch);
echo $accessToken;





4.2 自定义菜单
4.2.1 自定义菜单介绍
目前自定义菜单最多包含3个一级菜单,每个一级菜单最多包含5个二级菜单。创建自定义菜单需要24小时后客户端才会展现,重新关注公众号可以马上看到自定义菜单。

4.2.2 自定义菜单按钮类型

4.2.3 创建菜单
创建菜单接口:
https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s
菜单内容组织结构:
$jsonmenu = ‘{ “button”: [ button1, button2, button3 ] }’;
button1/2/3结构:
button1/2/3 = {“name”: “扫码”, “sub_button”: [sub_button1, sub_button2] }
sub_button1/2结构:
sub_button1 = {“type”: “scancode_waitmsg”, “name”: “扫码带提示”, “key”: “rselfmenu0_0”}
sub_button2 = {“type”: “scancode_push”, “name”: “扫码推事件”, “key”: “rselfmenu0_1”}
扫码:
$jsonmenu = '{
"button": [
{
"name": "扫码",
"sub_button": [
{
"type": "scancode_waitmsg",
"name": "扫码带提示",
"key": "rselfmenu_0_0"
},
{
"type": "scancode_push",
"name": "扫码推事件",
"key": "rselfmenu_0_1"
}
]
},
发图:
{
"name": "发图",
"sub_button": [
{
"type": "pic_sysphoto",
"name": "系统拍照发图",
"key": "rselfmenu_1_0"
},
{
"type": "pic_photo_or_album",
"name": "拍照或者相册发图",
"key": "rselfmenu_1_1"
},
{
"type": "pic_weixin",
"name": "微信相册发图",
"key": "rselfmenu_1_2"
}
]
},
其他:
{
"name": "其他",
"sub_button": [
{
"name": "发送位置",
"type": "location_select",
"key": "rselfmenu_2_0"
},
{
"type": "click",
"name": "今日歌曲",
"key": "V1001_TODAY_MUSIC"
},
{
"type": "view",
"name": "搜索",
"url": "http://www.soso.com/"
}
]
}

$accessToken = “……”;
$url = “https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$accessToken;
$result = https_request($url, $jsonmenu);
var_dump($result);
/*
以POST方式向微信服务器提交菜单内容,菜单内容为json格式
*/
function https_request($url, $data = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
if(!empty($data))
{
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //获取的信息以文件流的形式返回
$output = curl_exec($ch);
curl_close($ch);
return $output;
}

测试号申请地址:http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index


利用现有的菜单创建工具:http://www.fangbei.org/tool/menu

4.2.4 查询菜单
创建菜单接口:$url = “https://api.weixin.qq.com/cgi-bin/menu/get?access_token=”.$accessToken

4.2.5 删除菜单
创建菜单接口:
$url = “https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=”.$accessToken

4.2.6 菜单事件推送
点击按钮类型为click,上报XML数据包如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[CLICK]]></Event>
<EventKey><![CDATA[V1001_TODAY_MUSIC]]></EventKey>
</xml>
点击按钮类型为view,上报XML数据包如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[VIEW]]></Event>
<EventKey><![CDATA[http://www.soso.com]]></EventKey>
</xml>
点击按钮类型为scancode_push/scancode_waitmsg ,上报XML数据包如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[scancode_push/scancode_waitmsg]]></Event>
<EventKey><![CDATA[rselfmenu_0_1/rselfmenu_0_0]]></EventKey>
<ScanCodeInfo>
<ScanType><![CDATA[qrcode]]></ScanType >
<ScanResult><![CDATA[……]]></ScanResult>
</ScanCodeInfo>
</xml>
点击按钮类型为pic_sysphoto/pic_photo_or_album/pic_weixin,上报XML数据包如下
……
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[pic_sysphoto/pic_photo_or_album/pic_weixin]]></Event>
<EventKey><![CDATA[rselfmenu_1_0/rselfmenu_1_1/rselfmenu_1_2]]></EventKey>
<SendPicsInfo>
<Count>2</Count>
<PicList>
<item> <PicMd5Sum><![CDATA[……]]></PicMd5Sum> </item>
<item> <PicMd5Sum><![CDATA[……]]></PicMd5Sum > </item>
</PicList>
</SendPicsInfo>
……
点击按钮类型为location_select,上报XML数据包如下:
……
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[location_select]]></Event>
<EventKey><![CDATA[6]]></EventKey>
<SendLocationInfo><Location_X><![CDATA[23]]></Location_X>
<Location_Y><![CDATA[113]]></Location_Y>
<Scale><![CDATA[15]]></Scale>
<Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>
<Poiname><![CDATA[]]></Poiname>
</SendLocationInfo>
</xml>
……
4.2.7 实战:响应自定义菜单点击事件


5、网页授权与网页应用开发
5.1 网页授权
网页授权用于在网页中获取用户的基本信息,几乎所有微信网页开发应用在绑定用户身份时都需要这一功能,这也是微信网页开发实现的第一步。
传统模式:

5.2 OAuth2.0
OAuth2.0是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站、移动或桌面应用上存储的私密资源(如用户个人信息、照片、视频、联系人列表),而无需将用户名和密码提供给第三方应用。
OAuth允许用户提供一个令牌(Access Token),而不是用户名和密码来访问他们存放的数据。每一个令牌授权一个特定的网站在特定的时段内访问特定的资源。
两种scope模式:
- snsapi_base 静默授权,仅可以获取用户的OpenID
- snsapi_userinfo 需要用户手动同意,获取用户基本信息
5.3 授权过程

5.4 详细步骤
(1)登录微信公众平台(测试号),配置授权回调页面域名。

授权回调域名配置规范为全域名并且不带http

(2) 用户授权并获取code
请求授权页面的构造方式接口为
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
把上述链接发送或者回复到用户微信中,以便在微信浏览器中打开

用户发送“授权”关键字,微信回复获取code的接口链接。用户点击链接,查看code。

(3)通过code换取网页授权的Access Token
通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了OpenID,snsapi_base式的网页授权流程即到此为止。
换取网页授权access_token页面的接口如下:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

用户发送“口令”关键字,微信回复获取口令的接口链接。用户点击链接,查看口令。


refresh_token:
由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token刷新。refresh_token具有较长的有效期(7天、30天、60天、90天),当refresh_token失效后,需要用户重新授权。
用refresh_token刷新access_token的接口链接为:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
(4)使用access_token获取用户信息(scope为snsapi_userinfo时)
接口链接地址如下:https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

当发送关键字“用户信息”时,返回用户信息文本。



6、网页开发与数据库操作
6.1 SAE Memcached
6.1.1 SAE Memcached介绍
Memcached 是一个高性能的分布式内存对象缓存系统,可以用于动态 Web 应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。
Memcached 主要的使用场景有以下两个:
需要共享某些 Key-Value 形式的小数据时(因为新浪云的 Web 服务是分布式环境,所以使用全局变量方式等方式是不行的)。
缓存 MySQL等后端存储的数据。快速进行数据响应,减轻后端存储的压力,同时,还可以为这些缓存数据指定过期时间。Memcached的实现决定了缓存的数据不是永久有效的,因此应用程序必须有针对 Memcached 失效时的向后端存取数据的重试方案。
6.1.2 Memcached开通

6.1.3 Memcached使用示例
<?php
//连接
$mem = memcache_init();
//保存数据
$mem->set('key1', 'This is first value', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: " . $val ."<br />";
//替换数据
$mem->replace('key1', 'This is replace value', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: " . $val . "<br />";
//保存数组
$arr = array('aaa', 'bbb', 'ccc', 'ddd');
$mem->set('key2', $arr, 0, 60);
$val2 = $mem->get('key2');
echo "Get key2 value: ";
print_r($val2);
echo "<br />";
//删除数据
$mem->delete('key1');
$val = $mem->get('key1');
echo "Get key1 value: " . $val . "<br />";
//清除所有数据
$mem->flush();
$val2 = $mem->get('key2');
echo "Get key2 value: ";
print_r($val2);
echo "<br />";
//关闭连接
$mem->close();
?>

6.1.4 基于SAE MemCached的Oauth2认证
在跳转目标链接中将code缓存到SAE上

在主程序中实现一次使用code即删除

6.2 WeUI组件库
6.2.1 说明
这是一套基于样式库weui-wxss开发的小程序扩展组件库,同微信原生视觉体验一致的UI组件库,由微信官方设计团队和小程序团队为微信小程序量身设计,令用户的使用感知更加统一。在微信开发中使用WeUI有如下优势:
- 同微信客户端一致的视觉效果,看起来更原生;
- 便捷获取,快速上手,降低开发和设计成本;
- 微信团队精心打造,清晰明确,简洁大方。
6.2.2 WeUI组件引入
- 到https://github.com/Tencent/weui/wiki/getting-started下载组件库weui.min.css文件
- 将文件放在开发项目目录中,如上传到SAE服务器
- 开发过程中引用该组件库
有关组件库中各个组件介绍请访问https://weui.io/
6.2.3 WeUI组件:cell
Cell是列表或者是表单的一项,常用于设置页的展示,或者用在表单中,作为表单的每一个要填写的项,Cell必须要放在Cells组件的下面,Cell效果如下图所示。

6.3 获取用户信息


用户信息显示:

6.4 SAE数据库
新浪云的PHP运行环境提供了标准的 MySQL 连接数据库,支持所有MYSQL的特性。

6.4.1 创建数据库




6.4.2 SAE MySQL使用示例
用 户 名: $SAE_MYSQL_USER
密 码 : $SAE_MYSQL_PASS
主库域名 : $SAE_MYSQL_HOST_M
从库域名 : $SAE_MYSQL_HOST_S
端 口 : $SAE_MYSQL_PORT
数据库名 : $SAE_MYSQL_DB
<?php
// 连主库
$db = mysql_connect($SAE_MYSQL_HOST_M.':'.$SAE_MYSQL_PORT,
$SAE_MYSQL_USER, $SAE_MYSQL_PASS);
// 连从库(备份用),一般不需要连接
// $db = mysql_connect($SAE_MYSQL_HOST_S.':'.$SAE_MYSQL_PORT,
$SAE_MYSQL_USER, $SAE_MYSQL_PASS);
if (!empty($db)) {
mysql_select_db($SAE_MYSQL_DB, $db); //数据库操作
……
}
?>
插入数据:
$insert_item = "INSERT INTO `wx_user` (`id`, `username`, `telephone`) VALUES (1, '张三', '15088682341');";
mysql_query($insert_item);
查询数据:
$search_item = "SELECT * FROM `wx_user` WHERE `id` = 2;";
$search_result = mysql_query($search_item);
while($row = mysql_fetch_array($search_result))
{
echo "查询结果为: ".$row['username']." ".$row['telephone'];
echo "<br />";
}
修改数据:
$update_item = "UPDATE `wx_user` SET `telephone` = '15922556666' WHERE `id` = 2;";
mysql_query($update_item);
删除数据:
$delete_item = "DELETE FROM `wx_user` WHERE `id` = 1;";
mysql_query($delete_item);
7、JSSDK使用说明与调用实例
7.1 JSSDK是什么
微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
7.2 JSSDK接口类型
- 分享类接口
- 图像类接口
- 音频类接口
- 智能类接口
- 设备信息类接口
- 地理位置类接口
- 界面操作类接口
- 微信扫一扫接口
- 微信小店接口
- 微信卡券接口
- 微信支付接口
7.3 JSSDK使用步骤
在微信公众号(测试号)中绑定域名

引入JS文件,在php脚本文件中加入语句:
<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

通过config接口注入权限验证配置

wx.config中的appId,timestamp,nonceStr,signature等签名信息可通过本地class JSSDK中的GetSignPackage( )方法返回的数组signPackage得到,即
$jssdk = new JSSDK($appId, $appSecret) ;
$signPackage = $jssdk->GetSignPackage( ) ;

通过ready接口处理成功验证(debug 为 true 时不需要)
通过error接口处理失败验证(debug 为 true 时不需要)
Debug模式:会在调试过程中弹出调试消息,如

7.4 JSSDK调用实例



//图像显示接口
$('.image_present'). (){
wx.chooseImage({click(function
count: 1,
sizeType: ['original', 'compressed'], //指定是原图还是压缩图
sourceType: ['album', 'camera'], //指定来源是相册还是相机
success: function(res){
$('.image').attr('src', res.localIds);
}
});
});
//开始录音接口
$('.startRecord').click(function(){
wx.startRecord();
});
//停止录音接口,将录音Id存到voiceId中
var voiceId
$('.stopRecord').click(function(){
wx.stopRecord({
success: function(res){
voiceId = res.localId;
}
});
});
</script>
</html>
8、Restful API
8.1 RESTful架构
REST(Representational State Transfer)表现层状态转化:一种网络应用程序的设计风格和开发方式。
RESTful:如果一个架构符合REST原则,就称它为RESTful架构。
8.1.1 资源(Resources)
网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在,用URI (Uniform Resource Identifier,统一资源标志符)指向它。
所谓“上网”,就是与互联网上一系列的“资源”互动,调用它的URI。
注:URL是URI的一个子集,它是Uniform Resource Locator的缩写,译为“统一资源定位符”。
8.1.2 表现层(Representation)
“资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层”(Representation)。
比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。
URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述。
8.1.3 状态转化(State Transfer)
访问一个网站 ->服务器数据和状态变化
客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面四个表示操作方式的动词:
GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
8.2 RESTful风格
综合上面的解释,我们总结一下什么是RESTful架构:
- (1)每一个URI代表一种资源;
- (2)客户端和服务器之间,传递这种资源的某种表现层(格式);
- (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。
8.2.1 RESTful API设计误区

8.2.2 RESTful API设计细节
(1)协议
API与用户的通信协议,总是使用HTTPs协议。
(2)域名
应该尽量将API部署在专用域名之下,如https://api.example.com。
如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下,如https://example.org/api/。
(3)版本(Version)
应该将API的版本号放入URL,如https://api.example.com/v1/。
(4)路径 (Endpoint)
路径又称“终点”(endpoint),表示API的具体网址。在RESTful架构中,API网址中的名词应该使用复数。例如有一个API提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成下面这样。
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
(5)HTTP动词
对于资源的具体操作类型,由HTTP动词表示。
常用的HTTP动词有下面五个(括号里是对应的SQL命令)。
GET(SELECT): 从服务器取出资源(一项或多项)
POST(CREATE): 在服务器新建一个资源
PUT(UPDATE): 在服务器完整更新资源 e.g. PUT UserInfo
PATCH(UPDATE): 在服务器局部更新资源 e.g. PATCH UserInfo[ ‘Id’]
DELETE(DELETE): 从服务器删除资源
动词应用举例:
- GET /zoos: 列出所有动物园
- POST /zoos: 新建一个动物园
- GET /zoos/ID: 获取某个指定动物园的信息
- PUT /zoos/ID: 更新某个指定动物园的信息(全部信息)
- PATCH /zoos/ID: 更新某个指定动物园的信息(部分信息)
- DELETE /zoos/ID: 删除某个动物园
- GET /zoos/ID/animals: 列出某个指定动物园的所有动物
- DELETE /zoos/ID/animals/ID: 删除某个指定动物园的指定动物
(6)过滤信息
如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。
- ?limit=10: 指定返回记录的数量
- ?offset=10: 指定返回记录的开始位置。
- ?page=2&per_page=100: 指定第几页,以及每页的记录数。
- ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
- ?animal_type_id=1: 指定筛选条件
参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。
(7)状态码
服务器向用户返回的状态码和提示信息,常见的有以下一些:

常见状态码(续):

(8)错误处理
如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可,如
{
error: “Invalid API key”
}
(9)返回结果
针对不同操作,服务器向用户返回的结果应该符合以下规范。
- GET /collection: 返回资源对象的列表(数组)
- GET /collection/resource: 返回单个资源对象
- POST /collection: 返回新生成的资源对象
- PUT /collection/resource: 返回完整的资源对象
- PATCH /collection/resource: 返回完整的资源对象
- DELETE /collection/resource: 返回一个空文档
下面举个例子:
- GET http://localhost/restful/class 列出所有班级
- GET http://localhost/restful/class/1 获取指定班的信息
- POST http://localhost/restful/class?name=SAT班&count=23 新建一个班
- PUT http://localhost/restful/class/1?name=SAT班&count=23 更新指定班的信息(全部信息)
- PATCH http://localhost/restful/class/1?name=SAT班 更新指定班的信息(部分信息)
- DELETE http://localhost/restful/class/1 删除指定班
9、智能开放平台
9.1 智能机器人xiaoi
http://open.xiaoi.com/




9.2 安全签名验证算法
签名算法说明:
-
- SHA1加密(app_key:realm:app_secret) 其中realm为"xiaoi.com"
-
- SHA1加密(method:uri) 其中method为请求方法,如"POST", uri为"/ask.do"
-
- SHA1加密(HA1:nonce:HA2) 其中HA1为步骤1的值,HA2为步骤2的值,nonce为40位随机数
- 4.请求头字符串为app_key=“app_key的值”, nonce=“nonce的值”, signature=“步骤3的值”
- 5.添加请求头"X-Auth",值为步骤4的请求头字符串
形如 X-Auth : app_key=“用户app_key”, nonce=“nonce的值”, signature=“生成的签名”
X-Auth: app_key=“用户app_key”, nonce=“nonce的值”, signature=“生成的签名”

$app_key ="open1_CwqbQzroP45E";
$app_secret ="eK1suXM6guYeYp4I6uDd";
//签名算法
$realm = "xiaoi.com";
$method = "POST";
$uri = "/ask.do";
$nonce = "";
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
for ($i = 0; $i < 40; $i++) {$nonce .= $chars[ mt_rand(0, strlen($chars) - 1) ];}
$HA1 = sha1($app_key.":".$realm.":".$app_secret);
$HA2 = sha1($method.":".$uri);
$sign = sha1($HA1.":".$nonce.":".$HA2);
9.3 接口调用
HTTP请求方式:POST
HTTP请求地址: http://robot.open.xiaoi.com/ask.do

//接口调用
$url = "http://robot.open.xiaoi.com/ask.do";
$httpHeader = array('X-Auth:app_key="'.$app_key.'",nonce="'.$nonce.'", signature="'.$sign.'"');
$requestData = "question=".urlencode($content)."&userId=".$openid."&platform=weixin&type=0";
//HTTP请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestData);
$output = curl_exec($ch);

9.4 人脸识别
旷视科技:https://www.faceplusplus.com.cn/




人脸检测接口调用格式:

人脸分析接口:
传入在 Detect API 检测出的人脸标识 face_token,分析得出人脸关键点,人脸属性信息(年龄、性别、是否佩戴眼镜等)。一次调用最多支持分析 5 个人脸。

人脸分析接口调用格式:

接口调用返回:

1万+

被折叠的 条评论
为什么被折叠?



