Sae与微信订阅号的php开发
Sae与微信订阅号的开发基础学习
概述: 本文主要说明的是如何利用sae进行微信订阅号的程序开发。关于本文以下内容您必须要简单了解:
①Sae是新浪的云计算平台,全称为:Sina App Engine。
②关于如何创建sae账号及应用可参照百度经验。 如何注册SAE账号并创建SAE应用:
http://jingyan.baidu.com/article/9f63fb91cfc99dc8400f0e25.html
③微信公众账号分为订阅号、服务号、企业号等。因为我们是以个人身份进行基础学习,暂时只能申请订阅号。有关不同号别的区别,可自行百度。
④关于如何创建微信订阅号可参照百度经验。 怎么创建微信订阅号:
http://jingyan.baidu.com/article/90895e0ff5ae1564ec6b0bc9.html
⑤本文开发语言是PHP。如果不懂php也没有关系。因为本人也不懂php,但是各种语言的逻辑本来就是相通的,除了形式上不一样外,其他的都大同小异,对于稍微有点经验的开发者来说,不懂php对于理解本文,并成功创建自己的订阅号没有任何影响。
⑥如果想系统全面的了解sae与订阅号的开发,可以花点时间看看网易云课堂上的视频教程,可以不全部看完,但是前面几课必须认认真真的看完。看的时候也不需要动手做,只是理解一下原理就好。
《军哥带你玩转微信开发》系列教程-初级篇:
http://study.163.com/course/courseMain.htm?courseId=759002
⑦本文并不是分享如何实现订阅号的各种复杂功能(事实上复杂功能我也不会 - -)。主要就是想说说一些很关键性的东西,包括:
1)实现微信订阅号的网址接入
2)接收消息与回复消息 3)Mysql数据库的使用 4)Storage的使用
⑧由于本文作者并非专业的微信平台开发者,也不是php程序的开发者,所以所述的遗漏或错误都在所难免,所了解的也十分有限。不足之处,请多多包涵;有任何疑问都可以提出。
根据微信开发者文档的说明:
在开发者首次提交验证申请时,微信服务器将发送GET请求到填写的URL上,并且带上四个参数(signature、timestamp、nonce、echostr),开发者通过对签名(即signature)的效验,来判断此条消息的真实性。
此后,每次开发者接收用户消息的时候,微信也都会带上前面三个参数
(signature、timestamp、nonce)访问开发者设置的URL,开发者依然通过对签名的效验判断此条消息的真实性。效验方式与首次提交验证申请一致。
可以知道首次提交验证请求时,GET请求中包含参数echostr,而其后接收用户消息时,没有这个参数。
于是可以根据有没有echostr来判断是否是微信的首次接入请求。
如果是首次接入,则需要对TOKEN、timestamp、nonce三个参数进行处理,并将其处理结果与signature参数进行比较,如果比较结果为相同,则原样返回echostr参数,表示接入成功,否则接入失败。
如果不是首次接入(没有echostr参数),那么同样需要验证TOKEN
、timestamp、nonce与signatuer(本文示例代码中略去了这个验证)。不是首次接入,那么微信是将POST的数据放在xml中,xml中的数据包括消息类型(文本消息、图片消息、语言消息、视频消息、小视频消息、地理位置消息、链接消息)、消息内容等。根据不同的消息内容程序可以做出不同的响应逻辑,回复不同的消息给用户。
1)本文中实现了网址接入。
2)本文示例代码中实现了各个消息类型的接收,但只实现了回复消息中的回复文本消息。
3)本文中实现了如果不是首次接入但没有接收到微信发送的消息的时候,其接下来的处理。此时,将利用Storage中存储的图片,提醒用户关注微信订阅号。
4)本文实现了将用户发送的消息、订阅号回复的消息保存到Mysql数据库中的功能。
(★★需要注意的是,在sae中实现网址接入,sae账号必须要经过实名验证。★★)
只需要经过实名验证,不需要经过开发者验证即可。是否通过实名验证可以在资料中看得出来。
1)首次验证的实现方法:
//验证签名
public function valid(){
//验证通过时原样返回的string:echostr
$echoStr = $_GET[
$signature = $_GET[
//timestamp、nonce、TOKEN 待组合、处理的三个字符串 $timestamp = $_GET[
//①现将三个字符串排序
$tmpArr = array($token, $timestamp, $nonce); sort($tmpArr);
//②再将其连接成一个字符串 $tmpStr = implode($tmpArr); //③进行sha1加密
$tmpStr = sha1($tmpStr);
//④与signature进行比较验证,若相同,则原样返回echostr if($tmpStr == $signature){ echo $echoStr; exit; } }
2)接收消息与回复消息请参见全部代码。
3)Storage的使用
//显示添加关注的图片
private function showSubscribeImage(){ $accessKey = ACCESSKEY; $secretKey = SECRETKEY;
$sae_storage = new SaeStorage($accessKey, $secretKey); //domain名称
$domainName =
$directoryName =
$lstFiles = $sae_storage->getListByPath($domainName, $directoryName);
//取得所有文件
$files = $lstFiles['files'];
foreach($files as $imageFile){ //匹配到文件
if($imageFile['Name'] == 'abc_qiu.jpg'){
$tempName = $directoryName.
$imageUrl = $sae_storage->getUrl($domainName, $tempName); } }
if(isset($imageUrl)){
echo
Source中一些参数,如domain名称(hellolamp),文件夹路径(BackImage),匹配到的文件名(abc_qiu.jpg)需要替换成实际开发时的参数。 效果如下:http://hellolamp.sinaapp.com/
网页中的图片需事先保存到Storage中。图片来源是从微信公众账号平台中取得的。
在Storage保存图片的方法: ①开启Sotrage服务
②创建domain
③domain管理中的创建文件夹
④将文件上传到文件夹
以上步骤就可以保存将文件保存在storage中了。然后就可以在代码中使用了
(使用方
法如前面的代码)
。
4)Mysql数据库的使用
//日志记录(到mysql数据库中的Log表)
private function logger($log_type, $log_content){ $mysql = new SaeMysql(); //
获取IP地址
$ip = $_SERVER['REMOTE_ADDR'];
$sql =
if($mysql->errno() != 0){ //sae的日志中心进行记录
if(isset($_SERVER['HTTP_APPNAME'])){ sae_set_display_errors(false);
sae_debug(
//关闭数据库连接 $mysql->closeDb(); }
首先必须开启mysql服务,并在mysql中创建表。 ①开启mysql服务
②管理mysql
③在mysql中创建Table
④我这边的Log表已经创建成功了,所以就看看创建的表结构类型吧
⑤保存的数据截图
表创建成功后,就可以在php中使用了。使用的示例代码前面已经贴出来了。
全部代码(注释也很详细)如下所示。将一下代码直接覆盖到你的sae代码,并配置好代码中的一些常量、变量,你就可以在微信中看到效果啦!
//定义TOKEN常量(常量使用时,需修改为自己的常量,不能照抄) define(
define(
define(
$chatObj = new chatCls();
//若GET参数不存在echostr,则为用户发送消息,微信需根据实际情况返回消息给用户
if (!isset($_GET['echostr'])) { //响应用户发送的消息 $chatObj->responseMsg(); }else{
//验证网址接入 $chatObj->valid(); }
//消息的处理 class chatCls {
//验证签名
public function valid(){
//验证通过时原样返回的string:echostr $echoStr = $_GET[
$signature = $_GET[
//timestamp、nonce、TOKEN 待组合、处理的三个字符串 $timestamp = $_GET[
//①现将三个字符串排序
$tmpArr = array($token, $timestamp, $nonce); sort($tmpArr);
//②再将其连接成一个字符串 $tmpStr = implode($tmpArr); //③进行sha1加密
$tmpStr = sha1($tmpStr);
//④与signature进行比较验证,若相同,则原样返回echostr if($tmpStr == $signature){ echo $echoStr; exit; } }
//响应消息
public function responseMsg(){
$postStr = $GLOBALS[
//记录接收到的消息内容
$this->logger(
//接收到的消息内容进行xml转化
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
//取得消息类型
$RX_TYPE = trim($postObj->MsgType);
//消息类型分离 switch ($RX_TYPE) {
//事件消息 case
$result = $this->receiveEvent($postObj); break; //①文本消息 case
$result = $this->receiveText($postObj); break; //②图片消息 case
$result = $this->receiveImage($postObj); break; //③语音消息 case
$result = $this->receiveVoice($postObj); break; //④视频消息 case
$result = $this->receiveVideo($postObj);
break;
//⑤小视频消息
case
$result = $this->receiveShortVideo($postObj);
break;
//⑥地理位置消息
case
$result = $this->receiveLocation($postObj);
break;
//⑦链接消息 case
$result = $this->receiveLink($postObj);
break;
//其他未知消息
default:
$this->logger(
}
// 记录发送的Log内容
$this->logger(
echo $result;
}else {
// 不含有微信发送来的消息,说明是从别的方式直接访问了网址,所以显示“广告”
$this->showSubscribeImage();
// 记录Log
$this->logger(
exit;
}
}
//接收事件消息
private function receiveEvent($object){
$content = date(
return $result;
}
//①接收文本消息
private function receiveText($object){
$content = date(
return $result;
}
//②接收图片消息
private function receiveImage($object){
$content = date(
return $result;
}
//③接收语音消息
private function receiveVoice($object){
$content = date(
return $result; }
//④接收视频消息
private function receiveVideo($object){
$content = date(
return $result;
}
//⑤接收小视频消息
private function receiveShowVideo($object){
$content = date(
return $result;
}
//⑥接收位置消息
private function receiveLocation($object){
$content = date(
$result = $this->transmitText($object, $content);
return $result;
}
//⑦接收链接消息
private function receiveLink($object){
$content = date(
return $result;
}
//回复文本消息
private function transmitText($object, $content){
$xmlTpl =
%s
$result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), $content); return $result;
}
//显示添加关注的图片
private function showSubscribeImage(){
$accessKey = ACCESSKEY;
$secretKey = SECRETKEY;
$sae_storage = new SaeStorage($accessKey, $secretKey);
//domain名称
$domainName =
//domain下文件夹路径
$directoryName =
//取得该文件夹下的所有文件信息
$lstFiles = $sae_storage->getListByPath($domainName,
$directoryName);
//取得所有文件
$files = $lstFiles['files'];
foreach($files as $imageFile){
//匹配到文件
if($imageFile['Name'] == 'abc_qiu.jpg'){
$tempName = $directoryName.
//图片链接地址
$imageUrl = $sae_storage->getUrl($domainName, $tempName); }
}
if(isset($imageUrl)){
echo
}
echo
}
//日志记录(到mysql数据库中的Log表)
private function logger($log_type, $log_content){
$mysql = new SaeMysql();
//获取IP地址
$ip = $_SERVER['REMOTE_ADDR'];
$sql =
$mysql->runSql($sql);
//sql执行失败
if($mysql->errno() != 0){
//sae的日志中心进行记录
if(isset($_SERVER['HTTP_APPNAME'])){
sae_set_display_errors(false);
sae_debug(
sae_debug(
sae_set_display_errors(true);
}
}
//关闭数据库连接
$mysql->closeDb();
}
}
?>