第九章 用微信开发模式做欢迎词
这部分的重点是如何将微信开发模式和SAE对接,希望朋友们已经完成了SAE注册,如果还没搞定的话请抓紧,有问题的话请及时提出,接下来的教程都在那上面进行。
在教程开始前建议朋友们可以先注册一个新的公众账号,或者用非主账号当做开发测试账号,因为开发调试过称中可能会经常出现账号无法正常回复用户的情况,影响正常使用,所以在学习期间以及后期开发过程中最好有一个测试公众账号,等开发完成了再切换到主账号上,也是非常方便的。

一、微信公众平台与SAE对接通讯

我们先回到微信公众平台上来,点击高级功能进入,选择开发模式进入开发模式的页面,使用开发模式前记得先把编辑模式关闭,如下图:
微信公众平台开发者教程第8部分
先不着急点开关,点了也没用,会提示必须先成为开发者,但第一步也不是点击“成为开发者”按钮,而是点击查看文档按钮,我们要去下载一个文件,进入开发指南页面后点击左侧菜单的“消息接口指南”,如下图:
微信公众平台开发者教程第8部分
然后在右边打开的页面导航里点击“示例代码”,如下图:
微信公众平台开发者教程第8部分
页面直接会跳到最底部,当然直接拉到页面最下也可以,可以看到示例代码下载,点击下载后会得到一个“wx_sample.php”的文件,这个就是微信接口的SDK文件,首先我们将该文件改个名字,比如“wx_interface.php”,这里强调下文件的注意事项:1、后缀必须是.php;2、名字不能用中文,尽量是全小写字母,或者字母+下划线+字母组成;3、名字要便于记忆;4、不要把名字设成“index.php”、“weixin.php”、“admin.php”这些。
让大家改名的原因是为了安全,因为这是一个和微信公众平台通讯的接口文件,原则上要隐蔽,以免被人恶意攻击。改完名字后打开SAE,进入到咱们的应用,点击编辑代码进入编辑后台,把文件上传到SAE里,如下图:
微信公众平台开发者教程第8部分
微信公众平台开发者教程第8部分
双击上传的文件,进入该文件的编辑模式,可以看到密密麻麻的一片代码,朋友们不要被吓到,咱们一步步来,首先修改第7行的通讯秘钥,如图:
微信公众平台开发者教程第8部分
那些斜杠和星号的是注释,可以看到第6行的注释英文是“define your token”,也就是说第7行的代码功能是定义微信公众平台与SAE应用通讯时约定的一个秘钥。
这里解释下define(“TOKEN”, “weixin”)这段代码:
define是用来给常量赋值的函数,这句话的意思是赋予“TOKEN”这个常量值为“weixin”。
PS:常量和变量,是每一种编程语言中都存在的,常量值被定义后,在脚本的其他任何地方都不能被改变。一个常量的名称可以由英文字母、下划线、和数字组成,但数字不能作为首字母出现。变量被定义后随时可以重新赋值,其命名规则与常量一样,区别是变量最前面还要加“$”符号,而常量直接使用它的名称就可以了,如代码第67行,就是给变量$token赋值,值为之前定义的常量TOKEN,可以看到变量和常量的赋值方式也是不同的,变量赋值很简单不需要define函数。
微信公众平台开发者教程第8部分
扯了那么多咱们先把秘钥改了吧,这个秘钥其实有点像设置一个密码,微信公众平台对秘钥设置有要求是3位以上的字母或数字,我这里是测试所以改个“123456”,如图:
微信公众平台开发者教程第8部分
修改保存后,回到微信公众平台的开发模式,点击“成为开发者”按钮,然后会到“接口配置信息”页面,如下图:
微信公众平台开发者教程第8部分

  1. 输入各位在SAE上的应用地址+反斜杠+改名后的SDK文件,比如我这里输入的是
    http://weixincourse.sinaapp.com/wx_interface.php
    要注意的是前面不要忘记加http://,域名就是咱们应用的域名,上传的SDK文件名要写完整,包括.php的后缀名。
  2. 这里就是填写在SDK文件里设置的秘钥,我这里填写的是“123456”,大家根据自己设置的填写。

填写完后点击提交,如果一切顺利就会提示成功并跳转页面到开发者页面,如下图:
微信公众平台开发者教程第8部分

  1. 接口配置信息。这里可以看到咱们设定的那些接口信息都清楚的显示出来,如果接口的地址或者token改变的话点击修改按钮可以重新设置。
  2. 接口权限表。打钩的就是咱们可以使用的接口权限,关于这些接口的权限介绍可以查看《微信公众平台入门到精通Vol.7》,有些朋友如果已经拿到自定义菜单内测资格的,那么自定义菜单也会有打钩。
  3. 最重要的一步就是打开开发模式的开关,现在公众账号进入开发模式了!

这个时候你会发现你的公众账号无论是关注还是输入都没有提示了,原来编辑模式下设置的东西都不管用了,因为公众账号已经对接到了你的SAE接口,SO,我们开始下一步吧,先来个欢迎词!

二、开发模式下的欢迎词

先控诉下微信开发模式的设置不合理,接口校验和接口服务用同一个文件,而校验时这个文件必须直接返回echostr参数内容,当接口要启动正式服务时又得修改同个文件……好了这些跟大家无关,抱怨一下而已!
前面接口对接成功后,公众账号无法再与用户互动了,那么我们先把订阅欢迎这个功能恢复吧,回到SAE平台上,在编辑平台新建一个文件,我们把它命名为“wx_tpl.php”,这个文件的目的是存放微信输出内容的模板,细心的朋友会发现这就是目前接口可以给用户回复的三种消息格式,分别是文本、图文、音乐。内容如图:
微信公众平台开发者教程第8部分
然后把前面的那个SDK文件内容全部清空,没错就是全部清空,因为官方那个SDK除了用来做接口校验几乎没有什么用处。然后换上自己的代码,如图:
微信公众平台开发者教程第8部分
给大家解释下这一大段代码:
第3行,include_once是用来加载其他php文件的函数,在这里加载了wx_tpl.php,加载文件是可以设置路径的,由于现在两个文件在同一目录下,因此没有加路径。这样做的好处是有利于代码复用,一些经常用到的类、函数和变量可以放在其他文件统一加载,让代码简洁轻便。
第6行,接收微信公众平台发送过来的用户消息,该消息数据结构为XML,不是php默认的识别数据类型,因此这里用了$GLOBALS[‘HTTP_RAW_POST_DATA’]来接收,同时赋值给了$postStr,这里强调一个php的铁律就是php对大小写是敏感的,也就是变量也好函数也好,大小写不同是表示不同的变量或者函数,即$Q1和$q1是两个不同的变量,大家在写代码时千万注意。
第9行,一个条件语句,empty是判断变量是否为空的函数,如果是空返回0否则返回1,感叹号在这里是运算符表示非(not的意思),非0就是1,非1就是0,可能有点绕,意思就是如果$postStr不为空(接收到了数据)就继续执行下面的语句,如果为空就跳转到39行执行(这里就执行了两句代码,第一句是输出空字符串,第二句是退出)。
PS:
1、php的逻辑运算符有“&&”表示与(并且的意思),“||”标示或(或者的意思)“!”表示非(不是的意思),记住并且理解这些符号对后面写代码很有好处……
2、所有的编程语言都有if…else..语句,php的规则是if(条件){执行语句}else{执行语句},这里else可以没有,或者可以多重判定,if(条件1){执行语句}elseif(条件2){执行语句}else{执行语句}。判断条件用“()”包含,执行语句用“{}”包含,相邻最近的一对括号标示一段脚本,大家在编写的时候不要漏掉后面的半个括号。我在这段代码里括号标示的比较清楚,大家可以仔细参照一下。
第12行,使用simplexml_load_string() 函数将接收到的XML消息数据载入对象$postObj中。这个严谨的写法后面还得加个判断是否载入成功的条件语句,不过不写也没事。
第14行,将对象$postObj中的发送消息用户的OPENID赋值给$fromUsername变量,这里的“->”是指针,大家了解下就行了。
第16行,将对象$postObj中的公众账号的ID赋值给$toUsername变量。
第18行,将对象$postObj中的消息类型赋值给$form_MsgType变量。
第21行,判断消息是否为事件消息,现在微信公众账号的用户关注和取消订阅都是通过事件消息发送,因此咱们要欢迎用户关注首先得判断来接收的消息类型是否为事件。这里要强调的是在php里一个“=”用来赋值,“==”用来比较是否相等,大家千万注意在判断语句时如果少写一个“=”号这个判断会永远成立。
第24行,如果接收到的消息是事件消息,判断事件类型是否为订阅,在事件消息里“subscribe”表示订阅,“unsubscribe”表示取消订阅。
第29到32行,完成的是欢迎词回复的输出:
第29行是设定回复消息类型为文本;
第30行是设定回复消息的内容,其中可以使用表情符号的文本方式,换行使用“\n”,这里要注意的是字符串里如果要使用双引号或者单引号一般用中文符号,如果一定要用英文符号,要在引号前面加反斜杠比如“echo “\””;”输出的是一个双引号;
第31行,使用sprintf这个函数将格式化的数据写入到变量中去,其中“$textTpl”这个就是我们在wx_tpl.php里定义过的文本消息模板变量,后面的“$fromUsername, $toUsername, time(), $msgType, $contentStr”分别顺序替换模板里“%s”位置,也即是“$resultStr”这个变量最后实际为:

< ![CDATA[$fromUsername]]>
< ![CDATA[$toUsername,]]>
time()
< ![CDATA[$msgType]]>
< ![CDATA[$contentStr]]>
0

PS:time()是php里的时间函数,返回当前时间的 Unix 时间戳(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数。
第32行就是把回复消息输出。
第33行是退出整个程序,在php里exit可以放置在任何地方,当程序运行到这里就直接退出,否则还将继续运行,即使已经有结果输出在页面。
好了大家可以自己试着玩玩,不想敲字的朋友可以直接下载(点我),或者点击原文链接下载,下载后解压里面两个文件都有,请用记事本或者其他文本编辑器打开,复制内容到SAE上,请尽量不要使用文件上传,主要是怕大家编辑器保存文件时没存成UTF-8,会出错。