最近公司用到了微信公众平台,所以研究了一下微信公众号的开发技术,总体来说比较简单,结合现有的平台核技术,实现起来非常方便。
首先先来了解一下微信公众平台。
“微信,是一个生活方式” ,这是微信的自我评价,是不是觉得如果那天不在朋友圈里分享一下自己的最新状态,
并且收到几个赞和评价的话,会觉得空虚寂寞呢?它实实在在的改变了我们的生活方式。
“ 微信,也是一个生意方式 ”,在微信成为我们日常必备之app的同时,它同样具备巨大的的商业
或许不应该称为潜力,因为有很多人已经获利,名人们在微信上开设公众账户来吸金,商家来做推广,
服务行业借此拓展渠道,甚至微信已经支持支付了, 还有越来越的自媒体在微信平台涌现出来。
这篇文章就是介绍如何快速的成为公众平台开发者,由于个人只能申请订阅号,因此本文是以订阅号为例。
关于订阅号和服务号的区别,请参见 微信公众平台服务号、订阅号的相关说明。
从微信用户角度简单来说:
立即学习“PHP免费学习笔记(深入)”;
订阅号 主要用于信息辐射,典型的如各家 新闻媒体 。
服务号 主要由于自助服务,典型的如 招商银行 。




关于微信公众帐号注册的步骤就不再多说了,可以找到大量的图文教程。
帐号注册成功之后,需要验证自己的服务器,如果你没有自己的服务器,那可以用新浪SAE或者百度BAE,本文采用的是新浪SAE平台来搭建服务器。
注册过程略,使用新浪SAE创建应用,可以选择应用开发框架,选项中有比较热门的开发框架,选择微信公众平台phpSDK,点击后跳转到介绍页面,点击安装框架,系统会生成一个搭建好的微信公众平台应用,为了方便开发,我们可以使用svn来管理此应用代码,关于svn搭建可参见sae代码部署手册。
使用新浪SAE是比较方便的,如果我们有自己的服务器,可以把代码clone到自己的服务器上,下面来看一下代码
首先定义一个Wechat的基类
<span 1</span> <?<span php
</span><span 2</span> <span /*</span><span *
</span><span 3</span> <span * 微信公众平台 PHP SDK
</span><span 4</span> <span *
</span><span 5</span> <span * @author hanc <congcongsky2010@gmail.com>
</span><span 6</span> <span */</span>
<span 7</span>
<span 8</span> <span /*</span><span *
</span><span 9</span> <span * 微信公众平台处理类
</span><span 10</span> <span */</span>
<span 11</span> <span class</span><span Wechat {
</span><span 12</span>
<span 13</span> <span /*</span><span *
</span><span 14</span> <span * 调试模式,将错误通过文本消息回复显示
</span><span 15</span> <span *
</span><span 16</span> <span * @var boolean
</span><span 17</span> <span */</span>
<span 18</span> <span private</span> <span $debug</span><span ;
</span><span 19</span>
<span 20</span> <span /*</span><span *
</span><span 21</span> <span * 以数组的形式保存微信服务器每次发来的请求
</span><span 22</span> <span *
</span><span 23</span> <span * @var array
</span><span 24</span> <span */</span>
<span 25</span> <span private</span> <span $request</span><span ;
</span><span 26</span>
<span 27</span> <span /*</span><span *
</span><span 28</span> <span * 初始化,判断此次请求是否为验证请求,并以数组形式保存
</span><span 29</span> <span *
</span><span 30</span> <span * @param string $token 验证信息
</span><span 31</span> <span * @param boolean $debug 调试模式,默认为关闭
</span><span 32</span> <span */</span>
<span 33</span> <span public</span> <span function</span> __construct(<span $token</span>, <span $debug</span> = <span FALSE</span><span ) {
</span><span 34</span> <span if</span> (<span $this</span>->isValid() && <span $this</span>->validateSignature(<span $token</span><span )) {
</span><span 35</span> <span exit</span>(<span $_GET</span>['echostr'<span ]);
</span><span 36</span> <span }
</span><span 37</span>
<span 38</span> <span $this</span>->debug = <span $debug</span><span ;
</span><span 39</span> <span set_error_handler</span>(<span array</span>(&<span $this</span>, 'errorHandler'<span ));
</span><span 40</span> <span //</span><span 设置错误处理函数,将错误通过文本消息回复显示</span>
<span 41</span>
<span 42</span> <span $xml</span> = (<span array</span>) <span simplexml_load_string</span>(<span $GLOBALS</span>['HTTP_RAW_POST_DATA'], 'SimpleXMLElement',<span LIBXML_NOCDATA);
</span><span 43</span>
<span 44</span> <span $this</span>->request = <span array_change_key_case</span>(<span $xml</span>,<span CASE_LOWER);
</span><span 45</span> <span //</span><span 将数组键名转换为小写,提高健壮性,减少因大小写不同而出现的问题</span>
<span 46</span> <span }
</span><span 47</span>
<span 48</span> <span /*</span><span *
</span><span 49</span> <span * 判断此次请求是否为验证请求
</span><span 50</span> <span *
</span><span 51</span> <span * @return boolean
</span><span 52</span> <span */</span>
<span 53</span> <span private</span> <span function</span><span isValid() {
</span><span 54</span> <span return</span> <span isset</span>(<span $_GET</span>['echostr'<span ]);
</span><span 55</span> <span }
</span><span 56</span>
<span 57</span> <span /*</span><span *
</span><span 58</span> <span * 判断验证请求的签名信息是否正确
</span><span 59</span> <span *
</span><span 60</span> <span * @param string $token 验证信息
</span><span 61</span> <span * @return boolean
</span><span 62</span> <span */</span>
<span 63</span> <span private</span> <span function</span> validateSignature(<span $token</span><span ) {
</span><span 64</span> <span $signature</span> = <span $_GET</span>['signature'<span ];
</span><span 65</span> <span $timestamp</span> = <span $_GET</span>['timestamp'<span ];
</span><span 66</span> <span $nonce</span> = <span $_GET</span>['nonce'<span ];
</span><span 67</span>
<span 68</span> <span $signatureArray</span> = <span array</span>(<span $token</span>, <span $timestamp</span>, <span $nonce</span><span );
</span><span 69</span> <span sort</span>(<span $signatureArray</span><span );
</span><span 70</span>
<span 71</span> <span return</span> <span sha1</span>(<span implode</span>(<span $signatureArray</span>)) == <span $signature</span><span ;
</span><span 72</span> <span }
</span><span 73</span>
<span 74</span> <span /*</span><span *
</span><span 75</span> <span * 获取本次请求中的参数,不区分大小
</span><span 76</span> <span *
</span><span 77</span> <span * @param string $param 参数名,默认为无参
</span><span 78</span> <span * @return mixed
</span><span 79</span> <span */</span>
<span 80</span> <span protected</span> <span function</span> getRequest(<span $param</span> = <span FALSE</span><span ) {
</span><span 81</span> <span if</span> (<span $param</span> === <span FALSE</span><span ) {
</span><span 82</span> <span return</span> <span $this</span>-><span request;
</span><span 83</span> <span }
</span><span 84</span>
<span 85</span> <span $param</span> = <span strtolower</span>(<span $param</span><span );
</span><span 86</span>
<span 87</span> <span if</span> (<span isset</span>(<span $this</span>->request[<span $param</span><span ])) {
</span><span 88</span> <span return</span> <span $this</span>->request[<span $param</span><span ];
</span><span 89</span> <span }
</span><span 90</span>
<span 91</span> <span return</span> <span NULL</span><span ;
</span><span 92</span> <span }
</span><span 93</span>
<span 94</span> <span /*</span><span *
</span><span 95</span> <span * 用户关注时触发,用于子类重写
</span><span 96</span> <span *
</span><span 97</span> <span * @return void
</span><span 98</span> <span */</span>
<span 99</span> <span protected</span> <span function</span><span onSubscribe() {}
</span><span 100</span>
<span 101</span> <span /*</span><span *
</span><span 102</span> <span * 用户取消关注时触发,用于子类重写
</span><span 103</span> <span *
</span><span 104</span> <span * @return void
</span><span 105</span> <span */</span>
<span 106</span> <span protected</span> <span function</span><span onUnsubscribe() {}
</span><span 107</span>
<span 108</span> <span /*</span><span *
</span><span 109</span> <span * 用户自动上报地理位置触发,用于子类重写
</span><span 110</span> <span *
</span><span 111</span> <span * @return void
</span><span 112</span> <span */</span>
<span 113</span> <span protected</span> <span function</span><span onAutoloaction() {}
</span><span 114</span>
<span 115</span> <span /*</span><span *
</span><span 116</span> <span * 用户点击菜单时触发,用于子类重写
</span><span 117</span> <span *
</span><span 118</span> <span * @return void
</span><span 119</span> <span */</span>
<span 120</span> <span protected</span> <span function</span><span onClick() {}
</span><span 121</span>
<span 122</span> <span /*</span><span *
</span><span 123</span> <span * 用户点击跳转链接时触发,用于子类重写
</span><span 124</span> <span *
</span><span 125</span> <span * @return void
</span><span 126</span> <span */</span>
<span 127</span> <span protected</span> <span function</span><span onView() {}
</span><span 128</span>
<span 129</span> <span /*</span><span *
</span><span 130</span> <span * 收到文本消息时触发,用于子类重写
</span><span 131</span> <span *
</span><span 132</span> <span * @return void
</span><span 133</span> <span */</span>
<span 134</span> <span protected</span> <span function</span><span onText() {}
</span><span 135</span>
<span 136</span> <span /*</span><span *
</span><span 137</span> <span * 收到图片消息时触发,用于子类重写
</span><span 138</span> <span *
</span><span 139</span> <span * @return void
</span><span 140</span> <span */</span>
<span 141</span> <span protected</span> <span function</span><span onImage() {}
</span><span 142</span>
<span 143</span> <span /*</span><span *
</span><span 144</span> <span * 收到地理位置消息时触发,用于子类重写
</span><span 145</span> <span *
</span><span 146</span> <span * @return void
</span><span 147</span> <span */</span>
<span 148</span> <span protected</span> <span function</span><span onLocation() {}
</span><span 149</span>
<span 150</span> <span /*</span><span *
</span><span 151</span> <span * 收到链接消息时触发,用于子类重写
</span><span 152</span> <span *
</span><span 153</span> <span * @return void
</span><span 154</span> <span */</span>
<span 155</span> <span protected</span> <span function</span><span onLink() {}
</span><span 156</span> <span /*</span><span *
</span><span 157</span> <span * 收到语音消息时触发,用于子类重写
</span><span 158</span> <span *
</span><span 159</span> <span * @return void
</span><span 160</span> <span */</span>
<span 161</span> <span protected</span> <span function</span><span onVoice() {}
</span><span 162</span>
<span 163</span> <span /*</span><span *
</span><span 164</span> <span * 收到未知类型消息时触发,用于子类重写
</span><span 165</span> <span *
</span><span 166</span> <span * @return void
</span><span 167</span> <span */</span>
<span 168</span> <span protected</span> <span function</span><span onUnknown() {}
</span><span 169</span>
<span 170</span> <span /*</span><span *
</span><span 171</span> <span * 回复文本消息
</span><span 172</span> <span *
</span><span 173</span> <span * @param string $content 消息内容
</span><span 174</span> <span * @param integer $funcFlag 默认为0,设为1时星标刚才收到的消息
</span><span 175</span> <span * @return void
</span><span 176</span> <span */</span>
<span 177</span> <span protected</span> <span function</span> responseText(<span $content</span>, <span $funcFlag</span> = 0<span ) {
</span><span 178</span> <span exit</span>(<span new</span> TextResponse(<span $this</span>->getRequest('fromusername'), <span $this</span>->getRequest('tousername'), <span $content</span>, <span $funcFlag</span><span ));
</span><span 179</span> <span }
</span><span 180</span>
<span 181</span> <span /*</span><span *
</span><span 182</span> <span * 回复音乐消息
</span><span 183</span> <span *
</span><span 184</span> <span * @param string $title 音乐标题
</span><span 185</span> <span * @param string $description 音乐描述
</span><span 186</span> <span * @param string $musicUrl 音乐链接
</span><span 187</span> <span * @param string $hqMusicUrl 高质量音乐链接,Wi-Fi 环境下优先使用
</span><span 188</span> <span * @param integer $funcFlag 默认为0,设为1时星标刚才收到的消息
</span><span 189</span> <span * @return void
</span><span 190</span> <span */</span>
<span 191</span> <span protected</span> <span function</span> responseMusic(<span $title</span>, <span $description</span>, <span $musicUrl</span>, <span $hqMusicUrl</span>, <span $funcFlag</span> = 0<span ) {
</span><span 192</span> <span exit</span>(<span new</span> MusicResponse(<span $this</span>->getRequest('fromusername'), <span $this</span>->getRequest('tousername'), <span $title</span>, <span $description</span>, <span $musicUrl</span>, <span $hqMusicUrl</span>, <span $funcFlag</span><span ));
</span><span 193</span> <span }
</span><span 194</span>
<span 195</span> <span /*</span><span *
</span><span 196</span> <span * 回复图文消息
</span><span 197</span> <span * @param array $items 由单条图文消息类型 NewsResponseItem() 组成的数组
</span><span 198</span> <span * @param integer $funcFlag 默认为0,设为1时星标刚才收到的消息
</span><span 199</span> <span * @return void
</span><span 200</span> <span */</span>
<span 201</span> <span protected</span> <span function</span> responseNews(<span $items</span>, <span $funcFlag</span> = 0<span ) {
</span><span 202</span> <span exit</span>(<span new</span> NewsResponse(<span $this</span>->getRequest('fromusername'), <span $this</span>->getRequest('tousername'), <span $items</span>, <span $funcFlag</span><span ));
</span><span 203</span> <span }
</span><span 204</span> <span /*</span><span *
</span><span 205</span> <span * 回复语音识别消息
</span><span 206</span> <span * @param array $recognition 系统接收到语音后识别的字符串
</span><span 207</span> <span * @param integer $funcFlag 默认为0,设为1时星标刚才收到的消息
</span><span 208</span> <span * @return void
</span><span 209</span> <span */</span>
<span 210</span> <span protected</span> <span function</span> responseVoice(<span $recognition</span>, <span $funcFlag</span> = 0<span ) {
</span><span 211</span> <span exit</span>(<span new</span> TextResponse(<span $this</span>->getRequest('fromusername'), <span $this</span>->getRequest('tousername'), <span $recognition</span>, <span $funcFlag</span><span ));
</span><span 212</span> <span }
</span><span 213</span>
<span 214</span> <span /*</span><span *
</span><span 215</span> <span * 分析消息类型,并分发给对应的函数
</span><span 216</span> <span *
</span><span 217</span> <span * @return void
</span><span 218</span> <span */</span>
<span 219</span> <span public</span> <span function</span><span run() {
</span><span 220</span> <span switch</span> (<span $this</span>->getRequest('msgtype'<span )) {
</span><span 221</span>
<span 222</span> <span case</span> 'event':
<span 223</span> <span switch</span> (<span $this</span>->getRequest('event'<span )) {
</span><span 224</span>
<span 225</span> <span case</span> 'subscribe':
<span 226</span> <span $this</span>-><span onSubscribe();
</span><span 227</span> <span break</span><span ;
</span><span 228</span>
<span 229</span> <span case</span> 'unsubscribe':
<span 230</span> <span $this</span>-><span onUnsubscribe();
</span><span 231</span> <span break</span><span ;
</span><span 232</span>
<span 233</span> <span case</span> 'LOCATION':
<span 234</span> <span $this</span>-><span onAutoloaction();
</span><span 235</span> <span break</span><span ;
</span><span 236</span>
<span 237</span> <span case</span> 'CLICK':
<span 238</span> <span $this</span>-><span onClick();
</span><span 239</span> <span break</span><span ;
</span><span 240</span>
<span 241</span> <span case</span> 'VIEW':
<span 242</span> <span $this</span>-><span onView();
</span><span 243</span> <span break</span><span ;
</span><span 244</span>
<span 245</span> <span }
</span><span 246</span> <span break</span><span ;
</span><span 247</span>
<span 248</span> <span case</span> 'text':
<span 249</span> <span $this</span>-><span onText();
</span><span 250</span> <span break</span><span ;
</span><span 251</span>
<span 252</span> <span case</span> 'image':
<span 253</span> <span $this</span>-><span onImage();
</span><span 254</span> <span break</span><span ;
</span><span 255</span>
<span 256</span> <span case</span> 'location':
<span 257</span> <span $this</span>-><span onLocation();
</span><span 258</span> <span break</span><span ;
</span><span 259</span>
<span 260</span> <span case</span> 'link':
<span 261</span> <span $this</span>-><span onLink();
</span><span 262</span> <span break</span><span ;
</span><span 263</span>
<span 264</span> <span case</span> 'voice':
<span 265</span> <span $this</span>-><span onVoice();
</span><span 266</span> <span break</span><span ;
</span><span 267</span>
<span 268</span> <span default</span>:
<span 269</span> <span $this</span>-><span onUnknown();
</span><span 270</span> <span break</span><span ;
</span><span 271</span>
<span 272</span> <span }
</span><span 273</span> <span }
</span><span 274</span>
<span 275</span> <span /*</span><span *
</span><span 276</span> <span * 自定义的错误处理函数,将 PHP 错误通过文本消息回复显示
</span><span 277</span> <span * @param int $level 错误代码
</span><span 278</span> <span * @param string $msg 错误内容
</span><span 279</span> <span * @param string $file 产生错误的文件
</span><span 280</span> <span * @param int $line 产生错误的行数
</span><span 281</span> <span * @return void
</span><span 282</span> <span */</span>
<span 283</span> <span protected</span> <span function</span> errorHandler(<span $level</span>, <span $msg</span>, <span $file</span>, <span $line</span><span ) {
</span><span 284</span> <span if</span> ( ! <span $this</span>-><span debug) {
</span><span 285</span> <span return</span><span ;
</span><span 286</span> <span }
</span><span 287</span>
<span 288</span> <span $error_type</span> = <span array</span><span (
</span><span 289</span> <span //</span><span E_ERROR => 'Error',</span>
<span 290</span> <span E_WARNING</span> => 'Warning',
<span 291</span> <span //</span><span E_PARSE => 'Parse Error',</span>
<span 292</span> <span E_NOTICE</span> => 'Notice',
<span 293</span> <span //</span><span E_CORE_ERROR => 'Core Error',
</span><span 294</span> <span // E_CORE_WARNING => 'Core Warning',
</span><span 295</span> <span // E_COMPILE_ERROR => 'Compile Error',
</span><span 296</span> <span // E_COMPILE_WARNING => 'Compile Warning',</span>
<span 297</span> <span E_USER_ERROR</span> => 'User Error',
<span 298</span> <span E_USER_WARNING</span> => 'User Warning',
<span 299</span> <span E_USER_NOTICE</span> => 'User Notice',
<span 300</span> <span E_STRICT</span> => 'Strict',
<span 301</span> E_RECOVERABLE_ERROR => 'Recoverable Error',
<span 302</span> E_DEPRECATED => 'Deprecated',
<span 303</span> E_USER_DEPRECATED => 'User Deprecated',
<span 304</span> <span );
</span><span 305</span>
<span 306</span> <span $template</span> = <<<<span ERR
</span><span 307</span> <span PHP 报错啦!
</span><span 308</span>
<span 309</span> %s: %<span s
</span><span 310</span> <span File</span>: %<span s
</span><span 311</span> Line: %<span s
</span><span 312</span> <span ERR;
</span><span 313</span>
<span 314</span> <span $this</span>->responseText(<span sprintf</span>(<span $template</span>,
<span 315</span> <span $error_type</span>[<span $level</span>],
<span 316</span> <span $msg</span>,
<span 317</span> <span $file</span>,
<span 318</span> <span $line</span>
<span 319</span> <span ));
</span><span 320</span> <span }
</span><span 321</span>
<span 322</span> <span }
</span><span 323</span>
<span 324</span> <span /*</span><span *
</span><span 325</span> <span * 用于回复的基本消息类型
</span><span 326</span> <span */</span>
<span 327</span> <span abstract</span> <span class</span><span WechatResponse {
</span><span 328</span>
<span 329</span> <span protected</span> <span $toUserName</span><span ;
</span><span 330</span> <span protected</span> <span $fromUserName</span><span ;
</span><span 331</span> <span protected</span> <span $funcFlag</span><span ;
</span><span 332</span>
<span 333</span> <span public</span> <span function</span> __construct(<span $toUserName</span>, <span $fromUserName</span>, <span $funcFlag</span><span ) {
</span><span 334</span> <span $this</span>->toUserName = <span $toUserName</span><span ;
</span><span 335</span> <span $this</span>->fromUserName = <span $fromUserName</span><span ;
</span><span 336</span> <span $this</span>->funcFlag = <span $funcFlag</span><span ;
</span><span 337</span> <span }
</span><span 338</span>
<span 339</span> <span abstract</span> <span public</span> <span function</span><span __toString();
</span><span 340</span>
<span 341</span> <span }
</span><span 342</span>
<span 343</span>
<span 344</span> <span /*</span><span *
</span><span 345</span> <span * 用于回复的文本消息类型
</span><span 346</span> <span */</span>
<span 347</span> <span class</span> TextResponse <span extends</span><span WechatResponse {
</span><span 348</span>
<span 349</span> <span protected</span> <span $content</span><span ;
</span><span 350</span>
<span 351</span> <span protected</span> <span $template</span> = <<<<span XML
</span><span 352</span> <xml>
<span 353</span> <ToUserName><![CDATA[%s]]></ToUserName>
<span 354</span> <FromUserName><![CDATA[%s]]></FromUserName>
<span 355</span> <CreateTime>%s</CreateTime>
<span 356</span> <MsgType><![CDATA[text]]></MsgType>
<span 357</span> <Content><![CDATA[%s]]></Content>
<span 358</span> <FuncFlag>%s<FuncFlag>
<span 359</span> </xml>
<span 360</span> <span XML;
</span><span 361</span>
<span 362</span> <span public</span> <span function</span> __construct(<span $toUserName</span>, <span $fromUserName</span>, <span $content</span>, <span $funcFlag</span> = 0<span ) {
</span><span 363</span> parent::__construct(<span $toUserName</span>, <span $fromUserName</span>, <span $funcFlag</span><span );
</span><span 364</span> <span $this</span>->content = <span $content</span><span ;
</span><span 365</span> <span }
</span><span 366</span>
<span 367</span> <span public</span> <span function</span><span __toString() {
</span><span 368</span> <span return</span> <span sprintf</span>(<span $this</span>->template,
<span 369</span> <span $this</span>->toUserName,
<span 370</span> <span $this</span>->fromUserName,
<span 371</span> <span time</span>(),
<span 372</span> <span $this</span>->content,
<span 373</span> <span $this</span>-><span funcFlag
</span><span 374</span> <span );
</span><span 375</span> <span }
</span><span 376</span>
<span 377</span> <span }
</span><span 378</span>
<span 379</span> <span /*</span><span *
</span><span 380</span> <span * 用于回复的音乐消息类型
</span><span 381</span> <span */</span>
<span 382</span> <span class</span> MusicResponse <span extends</span><span WechatResponse {
</span><span 383</span>
<span 384</span> <span protected</span> <span $title</span><span ;
</span><span 385</span> <span protected</span> <span $description</span><span ;
</span><span 386</span> <span protected</span> <span $musicUrl</span><span ;
</span><span 387</span> <span protected</span> <span $hqMusicUrl</span><span ;
</span><span 388</span>
<span 389</span> <span protected</span> <span $template</span> = <<<<span XML
</span><span 390</span> <xml>
<span 391</span> <ToUserName><![CDATA[%s]]></ToUserName>
<span 392</span> <FromUserName><![CDATA[%s]]></FromUserName>
<span 393</span> <CreateTime>%s</CreateTime>
<span 394</span> <MsgType><![CDATA[music]]></MsgType>
<span 395</span> <Music>
<span 396</span> <Title><![CDATA[%s]]></Title>
<span 397</span> <Description><![CDATA[%s]]></Description>
<span 398</span> <MusicUrl><![CDATA[%s]]></MusicUrl>
<span 399</span> <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
<span 400</span> </Music>
<span 401</span> <FuncFlag>%s<FuncFlag>
<span 402</span> </xml>
<span 403</span> <span XML;
</span><span 404</span>
<span 405</span> <span public</span> <span function</span> __construct(<span $toUserName</span>, <span $fromUserName</span>, <span $title</span>, <span $description</span>, <span $musicUrl</span>, <span $hqMusicUrl</span>, <span $funcFlag</span><span ) {
</span><span 406</span> parent::__construct(<span $toUserName</span>, <span $fromUserName</span>, <span $funcFlag</span><span );
</span><span 407</span> <span $this</span>->title = <span $title</span><span ;
</span><span 408</span> <span $this</span>->description = <span $description</span><span ;
</span><span 409</span> <span $this</span>->musicUrl = <span $musicUrl</span><span ;
</span><span 410</span> <span $this</span>->hqMusicUrl = <span $hqMusicUrl</span><span ;
</span><span 411</span> <span }
</span><span 412</span>
<span 413</span> <span public</span> <span function</span><span __toString() {
</span><span 414</span> <span return</span> <span sprintf</span>(<span $this</span>->template,
<span 415</span> <span $this</span>->toUserName,
<span 416</span> <span $this</span>->fromUserName,
<span 417</span> <span time</span>(),
<span 418</span> <span $this</span>->title,
<span 419</span> <span $this</span>->description,
<span 420</span> <span $this</span>->musicUrl,
<span 421</span> <span $this</span>->hqMusicUrl,
<span 422</span> <span $this</span>-><span funcFlag
</span><span 423</span> <span );
</span><span 424</span> <span }
</span><span 425</span>
<span 426</span> <span }
</span><span 427</span>
<span 428</span>
<span 429</span> <span /*</span><span *
</span><span 430</span> <span * 用于回复的图文消息类型
</span><span 431</span> <span */</span>
<span 432</span> <span class</span> NewsResponse <span extends</span><span WechatResponse {
</span><span 433</span>
<span 434</span> <span protected</span> <span $items</span> = <span array</span><span ();
</span><span 435</span>
<span 436</span> <span protected</span> <span $template</span> = <<<<span XML
</span><span 437</span> <xml>
<span 438</span> <ToUserName><![CDATA[%s]]></ToUserName>
<span 439</span> <FromUserName><![CDATA[%s]]></FromUserName>
<span 440</span> <CreateTime>%s</CreateTime>
<span 441</span> <MsgType><![CDATA[news]]></MsgType>
<span 442</span> <ArticleCount>%s</ArticleCount>
<span 443</span> <Articles>
<span 444</span> %<span s
</span><span 445</span> </Articles>
<span 446</span> <FuncFlag>%s<FuncFlag>
<span 447</span> </xml>'
<span 448</span> <span XML;
</span><span 449</span>
<span 450</span> <span public function __construct($toUserName, $fromUserName, $items, $funcFlag) {
</span><span 451</span> <span parent::__construct($toUserName, $fromUserName, $funcFlag);
</span><span 452</span> <span $this->items = $items;
</span><span 453</span> <span }
</span><span 454</span>
<span 455</span> <span public function __toString() {
</span><span 456</span> <span return sprintf($this->template,
</span><span 457</span> <span $this->toUserName,
</span><span 458</span> <span $this->fromUserName,
</span><span 459</span> <span time(),
</span><span 460</span> <span count($this->items),
</span><span 461</span> <span implode($this->items),
</span><span 462</span> <span $this->funcFlag
</span><span 463</span> <span );
</span><span 464</span> <span }
</span><span 465</span>
<span 466</span> <span }
</span><span 467</span>
<span 468</span>
<span 469</span> <span /**
</span><span 470</span> <span * 单条图文消息类型
</span><span 471</span> <span */
</span><span 472</span> <span class NewsResponseItem {
</span><span 473</span>
<span 474</span> <span protected $title;
</span><span 475</span> <span protected $description;
</span><span 476</span> <span protected $picUrl;
</span><span 477</span> <span protected $url;
</span><span 478</span>
<span 479</span> <span protected $template = <<<XML
</span><span 480</span> <span <item>
</span><span 481</span> <span <Title><![CDATA[%s]]></Title>
</span><span 482</span> <span <Description><![CDATA[%s]]></Description>
</span><span 483</span> <span <PicUrl><![CDATA[%s]]></PicUrl>
</span><span 484</span> <span <Url><![CDATA[%s]]></Url>
</span><span 485</span> <span </item>
</span><span 486</span> <span XML;
</span><span 487</span>
<span 488</span> <span public function __construct($title, $description, $picUrl, $url) {
</span><span 489</span> <span $this->title = $title;
</span><span 490</span> <span $this->description = $description;
</span><span 491</span> <span $this->picUrl = $picUrl;
</span><span 492</span> <span $this->url = $url;
</span><span 493</span> <span }
</span><span 494</span>
<span 495</span> <span public function __toString() {
</span><span 496</span> <span return sprintf($this->template,
</span><span 497</span> <span $this->title,
</span><span 498</span> <span $this->description,
</span><span 499</span> <span $this->picUrl,
</span><span 500</span> <span $this->url
</span><span 501</span> <span );
</span><span 502</span> <span }
</span><span 503</span>
<span 504</span> }此基类我稍作了更改,包含了能实现的微信所有的接口,通过继承 `Wechat` 类进行扩展,例如通过重写 `onSubscribe()` 等方法响应关注等请求,下面是实现的示例代码:
<span 1</span> <?<span php
</span><span 2</span> <span /*</span><span *
</span><span 3</span> <span * 微信公众平台 PHP SDK 示例文件
</span><span 4</span> <span *
</span><span 5</span> <span * @author hanc <congcongsky2010@gmail.com>
</span><span 6</span> <span */</span>
<span 7</span>
<span 8</span> <span require</span>('src/Wechat.php'<span );
</span><span 9</span>
<span 10</span> <span /*</span><span *
</span><span 11</span> <span * 微信公众平台演示类
</span><span 12</span> <span */</span>
<span 13</span> <span class</span> MyWechat <span extends</span><span Wechat {
</span><span 14</span>
<span 15</span> <span /*</span><span *
</span><span 16</span> <span * 用户关注时触发,回复「欢迎关注」
</span><span 17</span> <span *
</span><span 18</span> <span * @return void
</span><span 19</span> <span */</span>
<span 20</span> <span protected</span> <span function</span><span onSubscribe() {
</span><span 21</span> <span $this</span>->responseText('欢迎关注韩聪的微信号'<span );
</span><span 22</span> <span }
</span><span 23</span>
<span 24</span> <span /*</span><span *
</span><span 25</span> <span * 用户取消关注时触发
</span><span 26</span> <span *
</span><span 27</span> <span * @return void
</span><span 28</span> <span */</span>
<span 29</span> <span protected</span> <span function</span><span onUnsubscribe() {
</span><span 30</span> <span //</span><span 「悄悄的我走了,正如我悄悄的来;我挥一挥衣袖,不带走一片云彩。」</span>
<span 31</span> <span }
</span><span 32</span>
<span 33</span> <span /*</span><span *
</span><span 34</span> <span * 用户自动上报地理位置时触发
</span><span 35</span> <span *
</span><span 36</span> <span * @return void
</span><span 37</span> <span */</span>
<span 38</span> <span protected</span> <span function</span><span onAutoloaction() {
</span><span 39</span>
<span 40</span> <span $this</span>->responseText('您的地理位置为:' . <span $this</span>->getRequest('Latitude') . ',' . <span $this</span>->getRequest('Longitude'<span ));
</span><span 41</span> <span }
</span><span 42</span>
<span 43</span> <span /*</span><span *
</span><span 44</span> <span * 用户点击菜单时触发
</span><span 45</span> <span *
</span><span 46</span> <span * @return void
</span><span 47</span> <span */</span>
<span 48</span> <span protected</span> <span function</span><span onClick() {
</span><span 49</span> <span $eventKey</span>=<span $this</span>->getRequest('EventKey'<span );
</span><span 50</span> <span switch</span>(<span $eventKey</span><span ){
</span><span 51</span> <span case</span> 'C001':
<span 52</span> <span $this</span>->responseText('我赢了'<span );
</span><span 53</span> <span break</span><span ;
</span><span 54</span> <span case</span> 'C002':
<span 55</span> <span $this</span>->responseText('我最近很好o(∩_∩)o '<span );
</span><span 56</span> <span break</span><span ;
</span><span 57</span> <span case</span> 'C003':
<span 58</span> <span $this</span>->responseText('谢谢(*^__^*) 嘻嘻'<span );
</span><span 59</span> <span break</span><span ;
</span><span 60</span> <span }
</span><span 61</span> <span }
</span><span 62</span>
<span 63</span> <span /*</span><span *
</span><span 64</span> <span * 收到文本消息时触发,回复收到的文本消息内容
</span><span 65</span> <span *
</span><span 66</span> <span * @return void
</span><span 67</span> <span */</span>
<span 68</span> <span protected</span> <span function</span><span onText() {
</span><span 69</span> <span $this</span>->responseText('收到了文字消息:' . <span $this</span>->getRequest('content'<span ));
</span><span 70</span> <span }
</span><span 71</span>
<span 72</span> <span /*</span><span *
</span><span 73</span> <span * 收到图片消息时触发,回复由收到的图片组成的图文消息
</span><span 74</span> <span *
</span><span 75</span> <span * @return void
</span><span 76</span> <span */</span>
<span 77</span> <span protected</span> <span function</span><span onImage() {
</span><span 78</span> <span $items</span> = <span array</span><span (
</span><span 79</span> <span new</span> NewsResponseItem('标题一', '描述一', <span $this</span>->getRequest('picurl'), <span $this</span>->getRequest('picurl')),
<span 80</span> <span new</span> NewsResponseItem('标题二', '描述二', <span $this</span>->getRequest('picurl'), <span $this</span>->getRequest('picurl')),
<span 81</span> <span );
</span><span 82</span>
<span 83</span> <span $this</span>->responseNews(<span $items</span><span );
</span><span 84</span> <span }
</span><span 85</span>
<span 86</span> <span /*</span><span *
</span><span 87</span> <span * 收到地理位置消息时触发,回复收到的地理位置
</span><span 88</span> <span *
</span><span 89</span> <span * @return void
</span><span 90</span> <span */</span>
<span 91</span> <span protected</span> <span function</span><span onLocation() {
</span><span 92</span> <span //</span><span $num = 1 / 0;
</span><span 93</span> <span // 故意触发错误,用于演示调试功能</span>
<span 94</span>
<span 95</span> <span $this</span>->responseText('收到了位置消息:' . <span $this</span>->getRequest('location_x') . ',' . <span $this</span>->getRequest('location_y'<span ));
</span><span 96</span> <span }
</span><span 97</span>
<span 98</span> <span /*</span><span *
</span><span 99</span> <span * 收到链接消息时触发,回复收到的链接地址
</span><span 100</span> <span *
</span><span 101</span> <span * @return void
</span><span 102</span> <span */</span>
<span 103</span> <span protected</span> <span function</span><span onLink() {
</span><span 104</span> <span $this</span>->responseText('收到了链接:' . <span $this</span>->getRequest('url'<span ));
</span><span 105</span> <span }
</span><span 106</span>
<span 107</span> <span /*</span><span *
</span><span 108</span> <span * 收到语音消息时触发,回复收到的语音
</span><span 109</span> <span *
</span><span 110</span> <span * @return void
</span><span 111</span> <span */</span>
<span 112</span> <span protected</span> <span function</span><span onVoice() {
</span><span 113</span> <span $this</span>->responseVoice('收到了语音:' . <span $this</span>->getRequest('recognition'<span ));
</span><span 114</span> <span }
</span><span 115</span>
<span 116</span> <span /*</span><span *
</span><span 117</span> <span * 收到未知类型消息时触发,回复收到的消息类型
</span><span 118</span> <span *
</span><span 119</span> <span * @return void
</span><span 120</span> <span */</span>
<span 121</span> <span protected</span> <span function</span><span onUnknown() {
</span><span 122</span> <span $this</span>->responseText('收到了未知类型消息:' . <span $this</span>->getRequest('msgtype'<span ));
</span><span 123</span> <span }
</span><span 124</span>
<span 125</span> <span }
</span><span 126</span>
<span 127</span> <span $wechat</span> = <span new</span> MyWechat('hancong', <span TRUE</span><span );
</span><span 128</span> <span $wechat</span>->run();以上代码部分功能需要开通服务号并且申请认证,比如语音识别,地理信息,添加菜单的功能,申请认证需要300元/年,可以享受微信所有的接口功能。
注:如果验证服务器URL,需要修改一句代码
<span $wechat</span> = <span new</span> MyWechat('hancong', <span TRUE</span><span );
</span><span //</span><span $wechat->run();</span>
<span $wechat</span>->validateSignature('hancong');<span //</span><span 参数为填写的token</span>验证完后回复调用run方法,validateSignature方法只是第一次验证服务器调用,验证完后即可删掉。
微信是一款手机通信软件,支持通过手机网络发送语音短信、视频、图片和文字。微信可以单聊及群聊,还能根据地理位置找到附近的人,带给大家全新的移动沟通体验,有需要的小伙伴快来保存下载体验吧!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号