php --laravel 开发 微信公众号 服务号总结

22 篇文章 0 订阅
5 篇文章 0 订阅

一、首先启用 服务号中服务器配置。

注意:启用后  之前在服务号后台页面创建的菜单就没了,服务号下面所有菜单都只能通过api去创建。

 二、 服务器地址URL 其实就相当于一个回调地址,类似支付回调地址URL一样,这个接口要做两个事情,一个就是效验token签名,另一个就是事件处理。

原理:用户每在服务号做任何操作  微信都会异步请求我们配置的回调地址(就是上面的服务器地址URL),我们可以if判断用户在做某些操作后回复种种消息之类的事情。比如(用户关注、取消关注事件等)

回调接口代码:

public function index()
    {
        ownLogs('test.log', 123456);
        $timestamp = $_GET['timestamp'];//timestamp其实就是一个时间戳
        $nonce     = $_GET['nonce'];//nonce是一个随机参数
        $token     = "第一步配置的token";//这个token填写你在微信公众平台上写的那个值
        $signature = $_GET['signature'];//这个signature其实就是在微信公众平台已经加密好的字符串
        $echostr   = $_GET['echostr'] ?? '';
        $array     = array($timestamp, $nonce, $token);
        sort($array);
        $tmpstr = implode('', $array);
        $tmpstr = sha1($tmpstr);
        if ($tmpstr == $signature && $echostr) {
            //验签
            ob_clean();
            echo $echostr;
            exit;
        } else {
            //回调处理
            $this->responseMsg();

        }
    }
    public function responseMsg()
    {
        //get post data, May be due to the different environments

        $postStr = file_get_contents("php://input"); //php 7 以上版本
        //$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //php 7以下版本,php.ini开启;always_populate_raw_post_data = On

        //extract post data 请求数据
        if (!empty($postStr)) {

            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $keyword = trim($postObj->Content);
            $time    = time();
            $toUser   = $postObj->FromUserName;
            $fromUser = $postObj->ToUserName;
            $eventKey = $postObj->EventKey ?? '';
            $ticket   = $postObj->Ticket ?? '';
            if (strtolower($postObj->MsgType) == 'event') {
                //如果是关注事件(subscribe)
                if (strtolower($postObj->Event == 'subscribe')) {
                    //回复用户消息
                    $data     = [
                        'open_id'   => $toUser,
                        'event_key' => $eventKey,
                        'ticket'    => $ticket,
                    ];
                    //关注数据写入数据库
                    list($status,$res) = GzhFollow::updateGzhFollowInfo($data);
                    if(!$status){
                        ownLogs('test.log', $res);
                    }
//                    ownLogs('test.log', 'fromUser=' . $fromUser . '|toUser=' . $toUser . '|keyword=' . $keyword);

                }
                //取消关注事件(subscribe)
                if (strtolower($postObj->Event == 'unsubscribe')) {
                    //更新GzhFollow表status为取消关注
                    $open_id = $toUser;
                    $info = GzhFollow::getFollowInfoByOpenId($open_id);
                    if($info){
                        $info->status = GzhFollow::STATUS['off'];
                        $info->save();
                    }
                }
                //扫描带参数二维码事件
                if($eventKey && $ticket){
                    $msgType     = 'text';
                    $store_name  = '李伟';//测试数据先写死
                    $description = '【' . $store_name . "】的店铺!";
                    //文字消息处理成超链接(因为我现在需求要跳转到小程序)
                    $content     = '点击进入' . '<a data-miniprogram-appid="你的服务号openid" data-miniprogram-path="/pages/index/index">' . $description . '</a>';
                    $template    = "<xml>
                                  <ToUserName><![CDATA[%s]]></ToUserName>
                                  <FromUserName><![CDATA[%s]]></FromUserName>
                                  <CreateTime>%s</CreateTime>
                                  <MsgType><![CDATA[%s]]></MsgType>
                                  <Content><![CDATA[%s]]></Content>
                                </xml>";

                    $info = sprintf($template, $toUser, $fromUser, $time, $msgType, $content);
                    echo $info;
                }
            }

        } else {
            echo "";
            exit;
        }
    }

 下面主要思路是三步:(自己可以封装成方法,我为了看着方便故意从封装的方法中提取到一个方法了)

             1.需要先获取服务号对应的access_token

             2.根据上面的access_token 和 open_id 去请求微信接口拿用户数据(主要想拿union_id 和小程序用户做关联)

                请求成功可以拿到用户微信头像、昵称、open_id,union_id(需要先在开放平台绑定多项目(小程序/服务号),才会返回)

            3.写入数据库。

 

 /*
     * $params 里面必包含参数open_id,
     * 剩余两个参数event_key 和ticket 是识别带参数二维码进服务号的时候才会有的参数(根据自己需要是否存数据库)
     */
    public static function updateGzhFollowInfo($params){
        $app_id     = config('wechat.official_account.yff_gzh.app_id');
        $app_secret = config('wechat.official_account.yff_gzh.secret');
        if (!$app_id || !$app_secret) {
            return [false, '获取小程序配置失败!'];
        }

        $redisConfig = config('database.redis.default');
        $redis       = new Client($redisConfig);

        //1.需要先获取服务号对应的access_token
        $access_token = $redis->get('access_token_' . $app_id);
        if (!$access_token) {
            $third_api = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $app_id . "&secret=" . $app_secret;
            $result    = getHttpContent($third_api, 'GET');
            $json      = json_decode($result, true);
            if (!isset($json['access_token']) || !$json['access_token']) {
                return [false, '获取access_token失败'];
            }
            $access_token = $json['access_token'];
            $redis->set('access_token_' . $app_id, $access_token);
            $redis->expire('access_token_' . $app_id, 3600);
        }
        //2.根据上面的access_token 和 open_id 去请求微信接口拿用户数据(主要想拿union_id 和小程序用户做关联)
        $open_id = $params['open_id'];
        $url        = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" . $access_token . '&openid=' . $open_id . '&lang=' . 'zh_CN';
        $result     = WechatService::httpRequest($url);
        $result_arr = json_decode($result, true);

        if(!isset($result_arr['unionid']) || !$result_arr['unionid']){
            return [false,'获取微信信息失败!'];
        }

        //3.组合需要的数据,写入数据库
        $data = [
            'status'    => GzhFollow::STATUS['on'],
            'union_id'  => $result_arr['union_id'],
            'sex'       => $result_arr['sex'],
            'addInfo'   => json_encode($result_arr),
            'open_id'   => $open_id,
            'event_key' => $params['event_key'],//根据自己需要(这个是识别带参数二维码进服务号的时候才会有的参数)
            'ticket'    => $params['ticket'],//根据自己需要(这个是识别带参数二维码进服务号的时候才会有的参数)
        ];
        $res = GzhFollow::create($data);
        if(!$res){
            return [false,'创建记录失败!'];
        }
        return [true,'成功!'];

    }

 

课程概述: 本课程是一个小型的vue周边技术+以php为基础的+微信接口开发的小型项目。本项目以微信扫码关注公众号实现网站自动登陆这一功能为载体,将会讲解如下主要核心知识点:前端你将学习到: 一、vue-cli4进行前端项目的创建 二、如何使用vuex进行登陆信息的管理与同步 三、如何使用axios进行接口请求的封装与拦截 四、在脚手架里使用Element-UI 五、学习组件化编程的思想 六、如何解决接口前后端分离引起的跨域问题以及在跨域下使用cookie凭证进行会话维护 后端你讲学习到: 一、如何申请微信公众号测试账,如何进行相关参数的配置,如何进行微信相关接口的开发 二、如何使用微信接口开发,如获取临时二维码,获取用户基础信息,监听公众号关注以及扫描事件 三、如何使用redis对数据进行缓存 四、如何使用php原生代码进行接口的开发 五、如何使用laralvel 7.x 框架进行接口的开发 六、学习到laravel 中核心概念的使用方法,如什么是依赖注入,如何使用服务容器解决依赖注入、服务提供者、中间件的使用,如何处理请求数据,如何进行用户认证,以及如何使用Eloquent ORM进行数据库操作 七、开发过程中遇到的问题,如何进行排查 八、git远端仓库的建立与配置,如何在配置多仓库下的公钥,服务器端部署公钥的配置,如何进行代码部署,本地与服务器代码的开发实时同步 九、如何使用composer帮助我们进行第三方依赖包的安装 本课程的设计思路随笔: 从业务层面上来讲,扫码关注公众号,实现网站端自动登陆是一个非常实用的功能,可以为微信公众号引流。 技术层面上来说,使用前后端分离进行制作,可以将前端以及后端的知识都涵盖到。对于前端的路由,信息维护,脚手架的搭建,ui组件的使用,接口的请求与封装都能够讲解到。 对于后端,本课程对php原生代码以及工作中使用频率比较高的同时也很优雅的laravel框架都会进行讲解,分别予以代码的实现。让同学们能够看到原生开发与框架开发的区别,原生开发使得基础比较弱的同学能够慢慢上手,也知道此功能实现的核心要点,在进行原生代码开发后,再进行框架开发,会有个循序渐进的过程,同时在框架里面我们会降到主流框架都会用到的一些核心思想,比如依赖注入,服务容器,中间件等等,同时对于想学习laravel框架的同学,学习过这个案例后,再去看文档就知道该如何去看,如何去学了。 对于整个代码的管理与部署,我们也会引入git仓库进行项目代码管理,如何在服务器进行网站环境的搭建与代码部署等等实用技巧。 相信本课程会给大家带来十足的收获,大家加油。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值