本次实验不涉及过多逻辑代码的操作,主要是对上一个实验的功能测试与总结,由于微信公众平台接口较多,所以不能封装所有的方法,在上一个实验中,我们主要针对四个方面做了API接口封装,实现了其基本功能,这节实验我们就针对这几个方面做一些简单的测试。
首先,我们需要准备一些文件,测试素材管理的操作。
接口测试 (只要不涉及与用户之间的消息交互,就可以在本地调试接口功能:127.0.0.1:80)
- 上传临时素材
// 上传图片素材(yes)
$data = ['@img/w110.jpg'];
$info = $wechatObj->uploadTmp('image',$data);
//如果运行正确,将获得返回数据
//{ ["type"]=> string(5) "image" ["media_id"]=> string(64) "R_hwAih90QbedV9SyKJy210uOI27uRKZvrNRMBcCSrXNV6wI3rk83cjUePgmcPGe" ["created_at"]=> int(1476193867) }
//上传音频素材(yes)
$data = ['@audio/cut.mp3'];
$info = $wechatObj->uploadTmp('voice',$data);
// { ["type"]=> string(5) "voice" ["media_id"]=> string(64) "3aQ3GdVnjPEXCSEtYuW8udXP4JajBWyllM95APV5H5pqjDoa1ffPAAIjDVG2uBmU" ["created_at"]=> int(1476194919) }
//上传缩略图(yes)
$data = ['@img/tx.jpg'];
$info = $wechatObj->uploadTmp('thumb',$data);
// { ["type"]=> string(5) "thumb" ["thumb_media_id"]=> string(64) "-aTLKtqCt-dGHYPAFXfd2wZUMboDU65QyAwb88whlAGcG2cy8ufo1f4a1p9iDmW3" ["created_at"]=> int(1476195230) }
//上传视频(yes)
$data = ['@mp4/test.mp4'];
$info = $wechatObj->uploadTmp('video',$data);
// { ["type"]=> string(5) "video" ["media_id"]=> string(64) "pDgBd31gaIA--SjKkqqZbgZkOhvQOjGY0JFkU-CWWvBtTp2ssoigSq1KKftHQCuD" ["created_at"]=> int(1476195642) }
-
获取临时素材
// 获取素材(yes),通过给定的mediaid获取 $mediaid = "R_hwAih90QbedV9SyKJy210uOI27uRKZvrNRMBcCSrXNV6wI3rk83cjUePgmcPGe"; $mediaid = "3aQ3GdVnjPEXCSEtYuW8udXP4JajBWyllM95APV5H5pqjDoa1ffPAAIjDVG2uBmU"; $mediaid = "-aTLKtqCt-dGHYPAFXfd2wZUMboDU65QyAwb88whlAGcG2cy8ufo1f4a1p9iDmW3"; $mediaid = "pDgBd31gaIA--SjKkqqZbgZkOhvQOjGY0JFkU-CWWvBtTp2ssoigSq1KKftHQCuD"; $result = $wechatObj->getTmp($mediaid);
请注意,视频文件不支持https下载,调用该接口需http协议。
正确情况下的返回HTTP头如下(示例):
HTTP/1.1 200 OK
Connection: close
Content-Type: image/jpeg
Content-disposition: attachment; filename="MEDIA_ID.jpg"
Date: Sun, 06 Jan 2013 10:20:18 GMT
Cache-Control: no-cache, must-revalidate
Content-Length: 339721
-
添加永久素材
//添加图片 $data = ['@img/w110.jpg']; $info = $wechatObj->addMaterial('image',$data); // array(1) { ["url"]=> string(124) "http://mmbiz.qpic.cn/mmbiz_jpg/eNkf5QIHGdw3bUTQbbehP2ibemFcnFR13y9Xp6VAVpiaia96YX4fw2QMFGx15XUAYQg8QHEtUK3lG5lKrSicrQkiaWA/0" } //添加音频 $data = ['media'=>'@audio/cut.mp3']; $info = $wechatObj->addMaterial('video',$data); // array(1) { ["media_id"]=> string(43) "oCmCA6JW8AUym2t9uhqzeFd28BpCHYsj5fQZGoaVuDA" } //添加缩略图 $data = ['media'=>'@img/tx.jpg']; $info = $wechatObj->addMaterial('thumb',$data); //array(2) { ["media_id"]=> string(43) "oCmCA6JW8AUym2t9uhqzeIzNHOLe7GNsO2fvhAsuUtI" ["url"]=> string(133) "http://mmbiz.qpic.cn/mmbiz_jpg/eNkf5QIHGdw3bUTQbbehP2ibemFcnFR13nWKJfLusYNl1RkbibesFqLP13gD87u1sDbnmuaEfWCp4nYR8grtsnAw/0?wx_fmt=jpeg" } //添加视频(需做视频描述说明) $data = ['media'=>'@mp4/test.mp4']; $desc = ['title'=>'shiyanlou','introduction'=>'woshi ce shi']; $info = $wechatObj->addMaterial('video',$data,true,$desc); // array(1) { ["media_id"]=> string(43) "oCmCA6JW8AUym2t9uhqzeKtiYQzppXBMyn6U2k2IMmU" } // 添加图文 $data = ['articles'=> [ [ 'title'=>'test', 'thumb_media_id'=>'oCmCA6JW8AUym2t9uhqzeIzNHOLe7GNsO2fvhAsuUtI', 'author'=>'fuli', 'digest'=>'dddfdsfds', 'show_cover_pic'=>'1', 'content'=>'fdssssssssgaaaaaaaaaaaaeg', 'content_source_url'=>'http://www.shiyanlou.com' ] ] ]; $info = $wechatObj->addMaterial('news',$data); // { ["media_id"]=> string(43) "oCmCA6JW8AUym2t9uhqzeEHdfvJ_Z0MUoqUjOWWEOrQ" }
-
获取永久素材数
// 永久素材数 $info = $wechatObj->getLongCount();
-
获取永久素材
在新增了永久素材后,开发者可以根据media_id来获取永久素材,需要时也可保存到本地。
请注意:
1、获取永久素材也可以获取公众号在公众平台官网素材管理模块中新建的图文消息、图片、语音、视频等素材(但需要先通过获取素材列表来获知素材的media_id) 2、临时素材无法通过本接口获取 3、调用该接口需https协议
// 获取图文 $info = $wechatObj->getMaterial('oCmCA6JW8AUym2t9uhqzeBh1UQrvEdzCMOSp53eujfY'); // 获取素材 $info = $wechatObj->getMaterial('oCmCA6JW8AUym2t9uhqzeIzNHOLe7GNsO2fvhAsuUtI'); header('Content-Type:image/png'); //显示输出图片 echo $info; // 删除素材 $info = $wechatObj->delMaterial('oCmCA6JW8AUym2t9uhqzeFd28BpCHYsj5fQZGoaVuDA'); // 修改永久图文 $data = [ 'articles'=> [ 'title'=>'testbyfuli', 'thumb_media_id'=>'oCmCA6JW8AUym2t9uhqzeIzNHOLe7GNsO2fvhAsuUtI', 'author'=>'fuli', 'digest'=>'dddfdsfds', 'show_cover_pic'=>'1', 'content'=>'fdssssssssgaaaaaaaaaaaaeg', 'content_source_url'=>'http://www.baidu.com' ] ]; $info = $wechatObj->updateNews('oCmCA6JW8AUym2t9uhqzeEHdfvJ_Z0MUoqUjOWWEOrQ',0,$data);
-
菜单管理
//=============================菜单管理 //菜单 $menu = [ 'button'=>[ [ 'name'=>'实验楼', 'sub_button'=>[ [ 'type'=>'view', 'name'=>'主页', 'url'=>'http://www.shiyanlou.com' ], [ 'type'=>'click', 'name'=>'点我啊', 'key'=>'clickme' ], [ 'type'=>'click', 'name'=>'点歌', 'key'=>'diange' ], [ 'name'=>'我的位置', 'type'=>'location_select', 'key'=>'mylocation' ] ] ], [ 'name'=>'扫码', 'sub_button'=>[ [ 'type'=>'scancode_waitmsg', 'name'=>'扫我获取', 'key'=>'scammsg' ], [ 'type'=>'scancode_push', 'name'=>'扫我进入', 'key'=>'scaninto' ], [ 'type'=>'media_id', 'name'=>'看图', 'media_id'=>'oCmCA6JW8AUym2t9uhqzeIzNHOLe7GNsO2fvhAsuUtI' ], [ 'type'=>'media_id', 'name'=>'图文信息', 'media_id'=>'oCmCA6JW8AUym2t9uhqzeEHdfvJ_Z0MUoqUjOWWEOrQ' ], [ 'type'=>'media_id', 'name'=>'电影', 'media_id'=>'oCmCA6JW8AUym2t9uhqzeKtiYQzppXBMyn6U2k2IMmU' ] ] ], [ 'name'=>'拍照', 'sub_button'=>[ [ 'type'=>'pic_sysphoto', 'name'=>'系统拍照', 'key'=>'photosys' ], [ 'type'=>'pic_photo_or_album', 'name'=>'选择方式', 'key'=>'photosel' ], [ 'type'=>'pic_weixin', 'name'=>'相册选择', 'key'=>'photoweixin' ] ] ] ] ]; $info = $wechatObj->createMenu($menu); //创建自定义菜单 $info = $wechatObj->delMenu(); //删除菜单 $info = $wechatObj->getMenuInfo(); //菜单信息
-
用户管理
$info = $wechatObj->getUserList(); //获取用户列表 $openid = 'oLA-5v9JKdKz_Unir3urFleTlVj4'; $info = $wechatObj->getUserInfo($openid); //获取用户信息 $info = $wechatObj->setUserName($openid,'fuli'); //获取用户信息 $info = $wechatObj->userTagCreate(['tag'=>['name'=>'实验楼']]); $info = $wechatObj->userTagGet(); //获取公众号已创建的标签 $data = ['tag'=>['id'=>104,'name'=>'实验楼+1']]; //编辑某个标签 $info = $wechatObj->userTagEdit($data); $data = ['tag'=>['id'=>104]]; //删除一个标签 $info = $wechatObj->userTagDelete($data); var_dump($wechatObj->errCode); var_dump($wechatObj->errMsg); var_dump($info);
最后,再做一个可以自动回复的功能。
$msgType = $wechatObj->getRec()->getRecType();
switch ($msgType) { //判断消息的类型
case 'text': //如果是文本信息
$content = $wechatObj->getRecContent(); //获取文本内容
switch ($content) {
case 'ip': //如果用户发送的内容是 ‘ip’,则获取微信服务器的全部ip地址
$ip = $wechatObj->getServerIp();
$ipstr = implode("\r\n",$ip);
$wechatObj->text("微信服务器IP:\r\n".$ipstr)->reply(); //回复内容
break;
case '呵呵': //内容是‘呵呵’
$wechatObj->text("Are U kidding me?")->reply(); //回复内容
break;
case 'help': //内容是‘help’
$wechatObj->text("微信公众号使用帮助:\r\n 1.回复'ip',查看全部微信服务器IP地址 \r\n 2.回复'呵呵','调戏微信' \r\n 3.回复'你是谁',详细了解我 \r\n 4.回复'关于',关于信息 \r\n 5.回复任意内容(文字,语音,图片),回复任意内容(文字,语音,图片) \r\n 6.------TODO-----")->reply();
break;
case '你是谁':
$wechatObj->text("呵呵,你猜啊!")->reply(); //回复内容
break;
case '点歌': //发送内容点歌
$music = [
'title'=>'测试歌曲',
'desc'=>'这是我用(sui)心(bian)为你点播的一首歌',
'url'=>'http://music.163.com/#/program?id=7940893', //歌曲链接
'hqurl'=>'http://music.163.com/#/program?id=7490893', //高音质链接,wifi下优先
'thumbid'=>'oCmCA6JW8AUym2t9uhqzeIzNHOLe7GNsO2fvhAsuUtI' //封面缩略图
];
$wechatObj->music($music)->reply(); //回复音乐消息
break;
case '关于': //关于
$wechatObj->text("我是微信机器人,Powered by Lifue-本条消息来自火星")->reply();
break;
default:
$wechatObj->text($content."(小孩子不要乱发消息哦)")->reply();
break;
}
break;
case 'image': //如果用户发送的是图像信息
$imageInfo = $wechatObj->getRecPic(); //获取图像信息
$wechatObj->image($imageInfo)->reply(); //回复图片消息
break;
case 'voice': //若用户发送的是语音消息
$voiceInfo = $wechatObj->getRecVoice(); //获取语音信息
// $wechatObj->text('不要给我发语音,我听不懂')->reply();
$wechatObj->voice($voiceInfo)->reply(); //回复语音消息
break;
case 'shortvideo': //如果用户发送的是短视频
// $videoInfo = $wechatObj->getRecVideo();
$videoInfo['title'] = '这是一个测试用的视频文件!';
$videoInfo['description'] = '这是测试时用的一个视频文件,仅用于测试公众号内容回复!!';
$videoInfo['mediaid'] = 'oCmCA6JW8AUym2t9uhqzeKtiYQzppXBMyn6U2k2IMmU';
// $wechatObj->text('不要给我发短视频,我分分钟几百万上下,没有时间看!')->reply();
$wechatObj->video($videoInfo)->reply(); //回复视频消息
break;
case 'event': //若消息类型是事件推送
$eventInfo = $wechatObj->getRecEvent(); //获取事件信息
switch ($eventInfo['event']) {
case 'CLICK': //若是点击事件
if ($eventInfo['key'] == 'diange') { //时间的key值
$music = [
'title'=>'测试歌曲',
'desc'=>'这是我用(sui)心(bian)为你点播的一首歌',
'url'=>'http://music.163.com/#/program?id=7944993',
'hqurl'=>'http://music.163.com/#/program?id=7490893',
'thumbid'=>'oCmCA6JW8AUym2t9uhqzeIzNHOLe7GNsO2fvhAsuUtI'
];
$wechatObj->music($music)->reply(); //回复音乐消息
} else {
$wechatObj->text('我开个玩笑而已,你还真敢点我啊!')->reply(); //回复文本消息
}
break;
case 'subscribe': //若事件类型是:用户关注事件,发送欢迎消息
$wechatObj->text('欢迎欢迎,热烈欢迎!回复 "help" 查看帮助信息!')->reply();
break;
case 'scancode_waitmsg': //若事件类型是:扫码等待消息
$info = $wechatObj->getScanInfo(); //获取扫码结果
$wechatObj->text('扫描方式:扫我有喜('.$info['type'].'),扫描结果:'.$info['result'])->reply(); //回复扫码的结果
break;
case 'VIEW': //如果是点击链接,回复success即可
$wechatObj->text('success')->reply();
break;
case 'pic_sysphoto': //调用系统拍照事件
$wechatObj->text('调用系统拍照!')->reply();
break;
default: //其他事件类型,回复消息
$wechatObj->text('休息,一会儿,马上回来!')->reply();
break;
}
break;
case 'location': //若事件类型是上报地理位置
$locinfo = $wechatObj->getLocation(); //获取地理位置信息
$wechatObj->text("你的位置信息:\r\n 经纬度:(".$locinfo['latitude'].",".$locinfo['longitude'].") \r\n 地名:".$locinfo['label']."\r\n 你的位置已暴露,注意人身安全!")->reply(); //将地理位置回复给用户
break;
default: //其他消息,自动回复
$wechatObj->text('我迷路了,待会儿再说')->reply();
break;
}
以上代码基本包含了微信公众号的常用功能,包括各种消息的发送与接收,各种消息的自动回复,扫码事件,以及拍照上传事件,以及上报地理位置事件。上面用到了一下方法之前没有做说明,比如获取扫码信息,获取地理位置信息,以及获取微信服务器信息。这里在补充说明一下。
-
获取微信服务器IP:
如果公众号基于安全等考虑,需要获知微信服务器的IP地址列表,以便进行相关限制,可以通过该接口获得微信服务器IP地址列表或者IP网段信息。
定义常量:
//获取微信服务器ip const SERVER_IP_URL = 'getcallbackip?';
定义方法:
//获取微信服务器的ip地址 public function getServerIp() { $url = self::API_URL_PREFIX . self::SERVER_IP_URL . 'access_token='.$this->access_token; $result = $this->http_get($url); if ($result) { $result = json_decode($result); } return $result->ip_list; }
-
自定义菜单的相关事件
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。
上面用到了一个方法,获取微信扫码结果,就是上门的第四个事件,大家都知道微信可以扫码,但是你可能没有注意过,其实微信扫码分为两种方式,一种叫做
扫码等:scancode_waitmsg
和扫码推:scancode_push
。前者在扫码之后,会弹出一个消息接收中
的提示框,同时将扫描的结果发送到后台服务器,这里当然是由微信服务器转发给我们。我们就能知道扫码的结果是什么,并作出对应的消息回复。另一种叫扫码推
,即是当扫码完成之后,如果扫码的结果是URL数据,则直接跳转到对应的URL,并非URL,则直接显示扫描结果。是,同时也会把扫码的数据传给后台的服务器。我们要关心的就是前者,因为它需要等待后台回应才有结果。我定义了个方法,获取扫码结果:
//扫描二维码 public function getScanInfo() { $info['type'] = $this->receive['ScanCodeInfo']->ScanType; $info['result'] = $this->receive['ScanCodeInfo']->ScanResult; if (!empty($info)) { return $info; } else { return false; } }
最后,我们将扫码的结果,通过文本消息的形式回复给用户。
-
地址位置信息
微信还有一个功能,可以上传自己的地址位置信息,同理,我们在后台也会收到位置信息,我们也可以对此消息做出回应:
//获取地理位置 public function getLocation() { $locinfo['latitude'] = $this->receive['Location_X']; $locinfo['longitude'] = $this->receive['Location_Y']; $locinfo['label'] = $this->receive['Label']; if (!empty($locinfo)) { return $locinfo; } else { return false; } }
好了,学到这里,本门课程也接近尾声了。回顾这三个实验,其实内容还算比较多,特别是第二个实验,代码量较大,如果认真写下来,代码量接近千行,不过现在在去看之前写的那些代码,觉得其实还是很简单的,没什么技术难度,只是注意数据的处理而已,并没有太多逻辑操作,很多方法的原理都是很类似的,只是稍微改了一下API地址而已。
其实本课程最主要的目的不是让大家如何去经营公众号,也不是教大家如何去搭建一个公众号,而是更多的希望大家能通过本门课程的学习,简单了解微信公众平台的运行流程,和开发者如何调用API接口实现功能测试与研发。这些内容都是微信公众号开发的最基础的内容,只要大家了解了基本原理和实现方式,再去学习其他方面的技术可能会更快掌握。
最后,希望大家一定要仔细阅读微信公众平台开发者文档,深入了解微信公众号开发技术。课程学习中,如果有任何疑惑或苦难,欢迎到课程下方给我留言,我会尽量帮你解答,感谢大家的学习。