使用laravel开发微信公众的一个大坑,适合新手学习的laravel接入微信接口

最近使用laravel做微信公众号二次开发,发现网上能够参考的资料基本上很少,很多地方都讲的不够详细,致使许多新手采坑无数,所以这篇文章讲一下如何使用laravel接入微信接口,实现微信公众号二次开发,顺便也会穿插一些laravel基础知识的讲解。

首先学习之前我们得有一个已经认证过的微信公众号,当然如果你只是学习一下不想花钱的话,点击这里微信公众平台,即可获得一个测试微信号,已经开通了接口,直接用即可。

其它的还需要一台web服务器,已经备案的域名,这些我就不做赘述。

首先我强调一下,能有兴趣看我这篇文章的,一定是有一定的php基础的,并且对国产thinkphp框架也是有一定了解的。那么laravel相对于thinkphp,有一个明显的区别就是,在域名中访问某个域名,需要定义其所对应的控制器,这个需要在routes里面添加

Route::get('weixin/token', 'WeixinController@token');
Route::post('weixin/token', 'WeixinController@token');

重要的一点一定要定义发请求的方式是POST还是GET,要不然是无法正确响应请求的,这个地方坑过很多使用laravel开发微信的朋友们,而这些在thinkphp中是不用定义的。那么在这里有个坑就是微信验证默认token的请求是GET方式,但是真正接入微信服务器用以开发时采用的确实POST方式,所以我们在微信后台配置验证接口时,要使用GET方式,在验证成功配置完成后再改回POST方式。

另外laravel最主要的是引进了一个中间件的概念,所有通过URL发过来的请求都需要经过中间件一系列验证才能分发给相应的控制器。然后最重要的我们在所有post请求中必须包含一个crsfToken的字段用以防止跨域攻击。但是如果我们是用在微信开发接口中,显然微信服务器是不会发送包含这个字段的,那么就需要我们手动的关闭,关闭的方法后面会讲到。

下面开始,教你一步一步实现微信自动回复。

将laravel安装部署到服务器上面(composer或者从官网下载离线安装包都行),笔者这里用的是最新版的laravel5.4.

打开routes/web.php,在里面增加一行:

Route::any('weixin/api', 'WeixinController@api');

打开app\Http\Middleware\VerifyCsrfToken.php,将第14行

protected $except = [
//
];

双斜杠替换为

'weixin/api',

在app\Http\目录下面新建WeixinCntroller.php,替换内容为:

<?php

namespace App\Http\Controllers;
use DB;
use App\Http\Requests;
use Illuminate\Http\Request;
class weixinController extends Controller
{
    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */


     //验证消息

public function api()
     {
         $echoStr = $_GET["echostr"];
         if($this->checkSignature()){
             echo $echoStr;
             exit;
         }
     }
     //检查签名
     private function checkSignature()
     {
         $signature = $_GET["signature"];
         $timestamp = $_GET["timestamp"];
         $nonce = $_GET["nonce"];
         $token = "weixin";
         $tmpArr = array($token, $timestamp, $nonce);
         sort($tmpArr, SORT_STRING);
         $tmpStr = implode($tmpArr);
         $tmpStr = sha1($tmpStr);
         if($tmpStr == $signature){
             return true;

         }else{
             return false;
         }
     }
     //响应消息
}

在微信公众号后台配置接口如下

注意:token令牌应该与WeixinController.php中配置的令牌一致。点击提交,如果提示“提交成功”,那么第一步就大功告成。错了?很正常,仔细检查一下配置信息是否正确,代码是否复制完全?

接下来一步:将之前的api操作方法

public function api(){
.......
}

替换为:

public function api()
      {
        //get post data, May be due to the different environments
       $postStr = file_get_contents("php://input", 'r');//php:input
       //写入日志  在同级目录下建立php_log.txt
      //chmod 777php_log.txt(赋权) chown wwwphp_log.txt(修改主)
      error_log(var_export($postStr,1),3,'php_log.txt');
      //日志图片

         //extract post data
       if (!empty($postStr)){
               /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
                  the best way is to check the validity of xml by yourself */
               libxml_disable_entity_loader(true);
                 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
               $fromUsername = $postObj->FromUserName;
               $toUsername = $postObj->ToUserName;
               $keyword = trim($postObj->Content);
               $time = time();
               $textTpl = "<xml>
                           <ToUserName><![CDATA[%s]]></ToUserName>
                           <FromUserName><![CDATA[%s]]></FromUserName>
                           <CreateTime>%s</CreateTime>
                           <MsgType><![CDATA[%s]]></MsgType>
                           <Content><![CDATA[%s]]></Content>
                           <FuncFlag>0</FuncFlag>
                           </xml>";
               //订阅事件
               if($postObj->Event=="subscribe")
               {
                   $msgType = "text";
                   $contentStr = "欢迎关注安子尘,微信babyanzichen";
                   $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                   echo $resultStr;
               }


               //语音识别
               if($postObj->MsgType=="voice"){
                   $msgType = "text";
                   $contentStr = trim($postObj->Recognition,"。");
                   $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                   echo  $resultStr;
               }

               //自动回复
               if(!empty( $keyword ))
               {
                     $msgType = "text";
                   $contentStr = "小朋友你好!";
                   $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                   echo $resultStr;
               }else{
                   echo "Input something...";
               }

       }else {
           echo "";
           exit;
       }
    }

此时,打开微信公众号,即可开始愉快的开撩了

posted @ 2019-01-11 12:16  汀风说后端  阅读(274)  评论(0编辑  收藏  举报