tp6微信公众号开发者模式token认证
<div id="topads"></div><div> </div>
<div class="col-md-8">
<h2>微信公众号开发完整教程(一) PHP7.0版本,TP5.0框架</h2>
<p>技术标签: 微信公众号开发</p>
<div> </div>
<div id="ads"> </div>
<div id="article_content">
<div id="mbads1">
<div id="con_all">
<div id="con_da1"> </div>
<div id="con_da2"> </div>
</div>
</div>
<div id="ad_before_content"></div>
<div class="htmledit_views">
<p>因为工作的需要,这一两年对微信公众号和小程序,项目制作的比较多。所以我才打算写一篇全面的制作教程,当然了,最好的教程是微信工作平台的文档。我这里只是讲述一下我的工作中的制作流程。所有相关文章的源码,我托管在我自己的github上面,欢迎关注:地址点击打开链接。接下来开始我们的教程。</p>
<h2>1.微信与公众平台的区别:</h2>
<p>微信:即时聊天的软件,属于一对一的关系</p>
<p>微信公众平台:属于一对多的关系。</p>
<h2>2.订阅号与服务号的区别:</h2>
<p>订阅号:针对个人或媒体每天可以群发1条信息,默认不具有自定义菜单。服务器号:针对企业或银行每月可以群发4条信息,默认具有自定义菜单。运营主体是组织(比如企业、媒体、公益组织)的,可以申请服务号。运营主体是组织和个人的可以申请订阅号,但是个人不能申请服务号。</p>
<h2>3.公众平台的两种模式:</h2>
<p>1、编辑模式:直接使用微信公众平台所提供的后台操作进行用户交互。编辑模式可以使用在如下的场景:不具备开发能力的运营者,主要是进行品牌宣传、新闻媒体、自助客服的公众账号,运营初期,不需要特别多的功能,开发模式系统升级,故障等特殊情况</p>
<p>2、开发者模式:直接使用接口代码实现用户的交流</p>
<h2>4.微信公众平台前期准备:</h2>
<div>
<p>注册公众平台,拥有线上服务器</p>
</div>
<h2>5.认识一下编辑模式:</h2>
<p>原理:</p>
<p><img src="https://www.pianshen.com/images/149/db2673c7a8d4c6d260bffce5e2635b65.png"></p>
<h4>5.1消息群发:</h4>
<p><img src="https://www.pianshen.com/images/124/797256cf80923d48bd23e314a53f86ec.png"></p>
<p> </p>
<p>选择对象选择素材进行群发:</p>
<p><img src="https://www.pianshen.com/images/843/e2ef03f525896a6dc7aae5e650c64763.png"></p>
<h4>5.2:自定义菜单:</h4>
<p>启用自定义菜单,并开启:</p>
<p><img src="https://www.pianshen.com/images/765/5172fb86dd780af7b951656c986b839d.png"></p>
<p>点击查看,进入设置界面:</p>
<p><img src="https://www.pianshen.com/images/851/6942ea86077f7b9d6477d0c518f6e1b3.png"></p>
<p><img src="https://www.pianshen.com/images/945/2d2020325c606236747d1b6ce56b1e81.png"></p>
<h4>5.3自动回复:</h4>
<p><img src="https://www.pianshen.com/images/349/de8e3ec6b95a3f677178318b14355b95.png"></p>
<p>上述讲述的主要是编辑模式的使用,我想很多人应该都会使用,其实和我们平常在论坛编辑文章和帖子差不多。</p>
<h2>6.开发者模式</h2>
<p>原理:</p>
<p><img src="https://www.pianshen.com/images/407/466ae6c771754e4d15e8783480db7e4f.png"></p>
<p> </p>
<h4>6.1第一步我们要开启开发者模式:</h4>
<p>注意:在开启开发者模式之后编辑模式中部分功能不能正常使用。即开发者模式跟编辑模式存在冲突。进入设置界面:</p>
<p><img src="https://www.pianshen.com/images/740/9f761358ccefaf3f0800c3784957910c.png"></p>
<p>修改配置:</p>
<p><img src="https://www.pianshen.com/images/151/3f46cb246d123f15b2bd540d655de83f.png"></p>
<p>设置结果如下图:填写上你的服务器文件地址,token,点击提交,验证即可。如果提交并验证通过,就进入到开发者模式</p>
<p><img src="https://www.pianshen.com/images/791/02f6b93ac5f1865d37cff837d3d95c87.png"></p>
<p><img src="https://www.pianshen.com/images/122/253f089ba9136f1720598b60e4f19972.png"></p>
<p> </p>
<h4>6.2我线上的验证代码如下:</h4>
<p> <img src="https://img2020.cnblogs.com/blog/2427663/202201/2427663-20220114074656388-948351877.png"></p>
<p> </p>
<p> <img src="https://img2020.cnblogs.com/blog/2427663/202201/2427663-20220114074919996-570587326.png"></p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> function valid(){
$signature </span>= $_GET[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">signature</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">];
$timestamp </span>= $_GET[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">timestamp</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">];
$nonce </span>= $_GET[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nonce</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">];
$token </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">yanbing</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
$tmpArr </span>=<span style="color: rgba(0, 0, 0, 1)"> array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr </span>=<span style="color: rgba(0, 0, 0, 1)"> implode( $tmpArr );
$tmpStr </span>=<span style="color: rgba(0, 0, 0, 1)"> sha1( $tmpStr );
</span><span style="color: rgba(0, 0, 255, 1)">if</span>( $tmpStr ==<span style="color: rgba(0, 0, 0, 1)"> $signature ){
exit($_GET[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">echostr</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]);
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
}
}</span></pre>
</div>
<p> </p>
<p><img src="https://img2020.cnblogs.com/blog/2427663/202201/2427663-20220114074841516-1203920307.png"></p>
<p> </p>
<p> </p>
<p> </p>
<div>
<div>public <em>function</em> valid(){</div>
<div> </div>
<div>//获取随机字符串</div>
<div>$echoStr = input("echostr");</div>
<div> </div>
<div>if($echoStr){</div>
<div>// 验证接口的有效性,由于接口有效性的验证必定会传递echostr 参数</div>
<div>if($this ->checkSignature()){</div>
<div>echo $echoStr;</div>
<div> </div>
<div>exit;</div>
<div>}</div>
<div>}else{</div>
<div>$this->responseMsg();</div>
<div>}</div>
<div>}</div>
<div>protected <em>function</em> checkSignature()</div>
<div>{</div>
<div>// 微信加密签名</div>
<div>$signature = input("signature");</div>
<div>$timestamp = input("timestamp");//时间戳</div>
<div>$nonce =input("nonce");//随机数</div>
<div>$token = "weixin"; //token值,必须和你设置的一样</div>
<div>$tmpArr =array($token,$timestamp,$nonce);</div>
<div>sort($tmpArr,SORT_STRING);</div>
<div>$tmpStr = implode($tmpArr);</div>
<div>$tmpStr =sha1($tmpStr);</div>
<div>if($tmpStr == $signature){</div>
<div>return true;</div>
<div>}else{</div>
<div>return false;</div>
<div>}</div>
<div>}</div>
</div>
<p>关于上述代码中的变量来源,微信都有详细的说明,我搭建的公众号使用的是PHP7.0版本,TP5.0框架。在这里说明一下。</p>
<p>上述代码只会执行一次,开启开发者模式之后,就不会在执行,只会执行上述代码中的</p>
<div>responseMsg</div>
<p>方法。</p>
<p>我们先上传一段测试代码试试,回复文本消息,是否有回复,代码如下:</p>
<p> </p>
<div>
<div>public <em>function</em> responseMsg()</div>
<div>{</div>
<div> //get post data, May be due to the different environments</div>
<div> $postStr = file_get_contents('php://input'); </div>
<div> //extract post data</div>
<div> if (!empty($postStr)){</div>
<div>/* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,</div>
<div>the best way is to check the validity of xml by yourself */</div>
<div>libxml_disable_entity_loader(true);</div>
<div> $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);</div>
<div>$fromUsername = $postObj->FromUserName;</div>
<div>$toUsername = $postObj->ToUserName;</div>
<div>$keyword = trim($postObj->Content);</div>
<div>$time = time();</div>
<div>$textTpl = "<xml></div>
<div> <ToUserName><!]></ToUserName></div>
<div> <FromUserName><!]></FromUserName></div>
<div> <CreateTime>%s</CreateTime></div>
<div> <MsgType><!]></MsgType></div>
<div> <Content><!]></Content></div>
<div> <FuncFlag>0</FuncFlag></div>
<div> </xml>";</div>
<div> if(!empty( $keyword ))</div>
<div>{</div>
<div> $msgType = "text";</div>
<div> $contentStr = "Welcome to wechat world!";</div>
<div> $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);</div>
<div> echo $resultStr;</div>
<div>}else{</div>
<div> echo "Input something...";</div>
<div>}</div>
<br>
<div>}else {</div>
<div> echo "";</div>
<div> exit;</div>
<div>}</div>
<div>}</div>
</div>
<p>结果如下:</p>
<p><img src="https://www.pianshen.com/images/967/3447316cfc7925fef8744101f8518ecf.png">,由于微信的网页授权的限制,所以我们可以申请测试账号,我这里使用的就是测试账号。上述的开启开发者模式是一样的。只需要去申请一个测试账号就好。申请的地方:</p>
<p><img src="https://www.pianshen.com/images/357/b796b339d6d6ed56d6dcd9630945358d.png"></p>
<p> </p>
<p>如果出现上述的代码,说明我们已经测试成功。接下来,我们开始获取access_token的值,这个参数对于我们来说很重要。因为</p>
<p>access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。access_token是身份认证 其他接口基本上都需要使用该值进行验证。</p>
<h2>7.access_token获取:(可以在本地测试)</h2>
<h4>7.1查看接口说明:</h4>
<p><img src="https://www.pianshen.com/images/966/68969e8847b431852725d39f32fc6aa6.png"></p>
<p> </p>
<h3>获取access_token方式一:</h3>
<p> </p>
<div><img src="https://www.pianshen.com/images/787/db544e28429467910893ce08721b0f3b.png"></div>
<p>结果如下:</p>
<p><img src="https://www.pianshen.com/images/343/0775194207f0d0600f50a45673c74b17.png"></p>
<p> </p>
<h3>获取access_token方式二:</h3>
<p> </p>
<div><img src="https://www.pianshen.com/images/315/fd07c4826bce4c74aca826cd0e516c2b.png"></div>
<p>结果如下:</p>
<p><img src="https://www.pianshen.com/images/93/794e6c1da134dfe074ca69eb9b4bf33d.png"></p>
<p>我们开始对上述的代码进行封装,因为access_token,每天只能调用2000次,所以我们要缓存起来,这样才能达到复用的效果,</p>
<h4>7.2:curl封装发送请求和获取access_token封装:</h4>
<div>
<div>
<div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取请求的地址的方法</span>
<span style="color: rgba(0, 0, 255, 1)">if</span>(!function_exists(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http_curl</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)){
function http_curl($url,$data </span>=array(),$method =<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">get</span><span style="color: rgba(128, 0, 0, 1)">"</span>,$returnType =<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">json</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">1.开启会话</span>
$ch =<span style="color: rgba(0, 0, 0, 1)"> curl_init();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">2.设置参数</span>
<span style="color: rgba(0, 0, 0, 1)">
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>($method!=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">get</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">){
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
}
curl_setopt($ch,CURLOPT_URL,$url);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">执行会话</span>
$json =<span style="color: rgba(0, 0, 0, 1)"> curl_exec($ch);
curl_close($ch);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>($returnType == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">json</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> json_decode($json,<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> $json;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!function_exists(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">get_access_token</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)){
function get_access_token()
{
$appid </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">wx1ba8f59d9e2c0be0</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">微信的appid</span>
$secret =<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">9e65155599fb9ec047455e197ff6e121</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">微信的开发者**
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 读取缓存中的内容</span>
include_once <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MyMemcache.php</span><span style="color: rgba(128, 0, 0, 1)">"</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">引入缓存方法文件</span>
$obj = <span style="color: rgba(0, 0, 255, 1)">new</span> \MyMemcache(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">47.104.71.253</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
$value </span>= $obj -><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">($appid);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">$value){
$url </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=</span><span style="color: rgba(128, 0, 0, 1)">"</span>.$appid.<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">&secret=</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">.$secret;
$result </span>=<span style="color: rgba(0, 0, 0, 1)"> http_curl($url);
$value </span>= $result[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">access_token</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
$obj</span>-><span style="color: rgba(0, 0, 255, 1)">set</span>($appid,$value,<span style="color: rgba(128, 0, 128, 1)">7000</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> $value;
}
}</span></pre>
</div>
<p> </p>
</div>
</div>
</div>
<p>上述代码就是我对这两个方法的封装,其中我们用到了缓存技术:缓存的方法如下:</p>
<p> </p>
<div>
<div>// memcache操作类</div>
<div><em>class</em> MyMemcache{</div>
<div>public $conn;</div>
<div>public $isMemcache =true;</div>
<div>public <em>function</em> __construct($host="127.0.0.1",$port='11211')</div>
<div>{</div>
<div>// 建立连接</div>
<div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">if</span>(class_exists(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">MyMemcache</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)){
$obj </span>=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> \Memcache();
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
$</span><span style="color: rgba(0, 0, 255, 1)">this</span> ->isMemcache =<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
$obj </span>=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> \Memcached();
}
$obj </span>-><span style="color: rgba(0, 0, 0, 1)">addServer($host,$port);
$</span><span style="color: rgba(0, 0, 255, 1)">this</span> ->conn =<span style="color: rgba(0, 0, 0, 1)">$obj;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取数据</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> function <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">($key)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> $<span style="color: rgba(0, 0, 255, 1)">this</span>->conn-><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">($key);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置数据</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> function <span style="color: rgba(0, 0, 255, 1)">set</span>($key,$value,$expire=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span>($<span style="color: rgba(0, 0, 255, 1)">this</span>-><span style="color: rgba(0, 0, 0, 1)">isMemcache){
$</span><span style="color: rgba(0, 0, 255, 1)">this</span>->conn-><span style="color: rgba(0, 0, 255, 1)">set</span>($key,$value,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">,$expire);
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Memcached扩展的操作方式</span>
$<span style="color: rgba(0, 0, 255, 1)">this</span>->conn-><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">($key,$value,$expire);
}
}
}</span></pre>
</div>
<p> </p>
</div>
</div>
<p>附加sftp与线上同步</p>
<p><img src="https://img2020.cnblogs.com/blog/2427663/202201/2427663-20220114075110832-346443754.png"></p>
<p> </p>
<p> </p>
<p><img src="https://img2020.cnblogs.com/blog/2427663/202201/2427663-20220114075158894-210883438.png"></p>
<p> </p>
<p> </p>
<p><img src="https://img2020.cnblogs.com/blog/2427663/202201/2427663-20220114075341666-413223324.png"></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
</div>
</div>
</div><br><br>
来源:https://www.cnblogs.com/xiaoyantongxue/p/15800406.html
頁:
[1]