Laravel学习记录--微信开发(day3)

2022-09-14 14:48:45 浏览数 (1)

微信开发第三天,利用Laravel做一个小项目----微分销

三级分佣,无限裂变,利用社交媒体的巨大流量做产品分销,分裂出成千上万个分销商,扩大销售规模,这是微信三级分销的核心价值之所在。 微信三级分销 平台,去掉了传统之间,为生产商带来分销商, 使得生产商与消费者直接沟通,不仅降低生产商交易成本,而且为商家带来更多精准用户。 同时,三级分销还 为消费者提供成为分销商的机会,为消费者带来额外收入,间接提高消费者与生产商之间的粘度

本项目通过第三方扩展进行开发 overtrue/wechat,官方网站https://www.easywechat.com/

一,部署项目

1.1composer创建项目 composer create-project laravel/laravel=5.5 fx;

1.2安装Wechat扩展 Laravel < 5.8 composer require "overtrue/laravel-wechat:~4.0"

Laravel >= 5.8 composer require "overtrue/laravel-wechat:~5.0"

开发文档:https://www.easywechat.com/docs 环境需求

  • PHP >= 7.0
  • PHP cURL 扩展
  • PHP OpenSSL 扩展
  • PHP SimpleXML 扩展
  • PHP fileinfo 拓展二,接入微信

2.1配置虚拟主机

代码语言:javascript复制
<VirtualHost *:80>
DocumentRoot "D:wamp64wwwpublicFx"
ServerName 590c1c9e.nat123.cc
</VirtualHost>

2.2添加路由并绑定控制器

代码语言:javascript复制
Route::get('wx','WxController@server');//get路由用于微信服务器验证
Route::post('wx','WxController@server')//post路由用于与微信服务器交互

2.3生成wechat类配置文件 php artisan vendor:publish --provider=OvertrueLaravelWeChatServiceProvider 2.4编写配置文件(config/wechat),设置api_key,api_secret

代码语言:javascript复制
'official_account' => [
        'default' => [
            'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', '你的api_id'),         // AppID
            'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', '你的api_secret'),    // AppSecret
            'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', 'your-token'),           // Token
            'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', ''),                 
        ],
    ],

编写控制器

代码语言:javascript复制
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
class WxController extends Controller
{
    public function server(){
      //通过app方法读取配置文件的信息并生成 
      //Factory::officialAccount实例
      $app = app('wechat.official_account');
      $app->server->push(function($message){
             //这里的message是微信服务器返回的xml数据
             //不过通过配置文件设置,这里直接转换为数组
            return "欢迎关注 overtrue!";
        });
        return $app->server->serve();
        //相对于返回微信GET过来的echostr
    }
}

为了使微信服务器与我们的服务器验证 我们还要设置appHttpMiddlewareVerifyCsrfToKen 设置except数组 移除关于微信的Token验证

代码语言:javascript复制
 protected $except = [
        'wx'
    ];

这样我们就可以在微信公众平台,配置信息

如果这里出现了”配置失败“,检查你的路由,以及是否没有移除关于微信的Token验证 完成上述操作后我们就可以开发了 1.测试关注事件

代码语言:javascript复制
<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use EasyWeChatFactory;
class WxController extends Controller
{
    public function server(){

      $app = app('wechat.official_account');
      $app->server->push(function($message){
            if($message['Event'] == 'subscribe'){
                //用户关注事件
                return "欢迎关注我的公众号";
            }
        });

        return $app->server->serve();
    }
}

消息

消息分为以下几种:文本图片视频声音链接坐标图文文章 和一种特殊的 原始消息。

另外还有一种特殊的消息类型:素材消息,用于群发或者客服时发送已有素材用。

注意:回复消息与客服消息里的图文类型为:图文,群发与素材中的图文为文章

这里以图片消息为例,引入“素材管理库”

在微信里的图片,音乐,视频等等都需要先上传到微信服务器作为素材才可以在消息中使用。

通过$app->material->uploadImage(path);上传图片,该方法会将图标上传至素材库并返回media_idurl 我们拿到media_id就可以使用素材管理库的图片了 如下案例(由于下面生成二维码的时候调用接口次数达到上限了,这里就将就二维码的图片算了)

代码语言:javascript复制
    if($message['Content'] == '图片'){

            //如果接口正常-----
            // $result = $this->app->material->uploadImage(public_path()."/img/1.jpg");
            // $media_id = $result['media_id'];
            //-----

            $media_id = '1WjY_rem_APMR2-qckRNN3n4becBU6RawAp-WFSNi_g';
            return new Image($media_id);//发送图片

        }

获取用户信息

在微信里面昵称是可以相同的,所以我们要找到一个唯一标识用户的东西。

在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID即xml数据包的FromUsername(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。)

通过以下方式获取

获取单个用户信息

app->user-get(openid)

获取多个用户信息

app->user->select(openid1,openid2)

返回数组类型

如下案例;

代码语言:javascript复制
  public function event($message){
        $openId = $message['FromUserName'];//获取OpenID
        $user = $this->app->user->get($openId);//根据openId获取用户信息
        if($message['Event'] == 'subscribe'){
            $sel = User::where('openId',$openId)->first();//根据openid查询是否已经有此用户
            if($sel){
                //如果有此用户 ,则恢复”软删除“
                User::where("openId",$openId)->update(['status'=>1]);
                return "欢迎关注";
            }else{
                //没有此用户则将用户存进数据库
                User::create(['name'=>$user['nickname'],'openId'=>$openId]);
                return "欢迎关注";
            }    

        }elseif($message['Event'] == 'unsubscribe'){
            //如果用户取消关注 软删除用户
            User::where("openId",$openId)->update(['status',0]);
        }
    }

生成带参数的二维码 由于我们这个系统是微信分销,就涉及到代理的问题,代理一共三级,如何绑定代理与上级代理的关系变得非常重要,这里就可以通过带参数的二维码的形式,用户点击‘代理推广’生成二维码,不过这个二维码是以该用户的openid生成的,这样当其他用户扫码成为二级/三级代理后,我们就能轻易的知道一/二/三级代理的关系了 目前有 2 种类型的二维码:

临时二维码,是有过期时间的,最长可以设置为在二维码生成后的 30天后过期,但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景

永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景

生成二维码步骤(微信官方文档—-“账号管理”—-生成带参数的二维码)

先创建二维码ticket,然后凭借ticket到指定URL换取二维码

easywechat中为我们提供了更方便的方法

创建临时二维码

$result = $app->qrcode->temporary('foo', 6 * 24 * 3600);

第一个参数为:二维码参数

第二个参数为:过期时间

返回值:

ticket:二维码ticket用于换取二维码

expire_seconds:过期时间

url:二维码url(通过该url获取二维码)

创建永久二维码

$result = $app->->qrcode->forever(56)

只有一个参数:二维码参数

返回值

ticket:二维码ticket用于换取二维码

url:二维码url(通过该url获取二维码)

获取二维码网址

$url = $app->qrcode->url($ticket)

获取二维码内容

代码语言:javascript复制
$url = $app->qrcode->url($ticket)
$content = file_get_contents($url); // 得到二进制图片内容
file_put_contents(__DIR__ . '/code.jpg', $content); // 写入文件

获取二维码完整代码

代码语言:javascript复制
if($message['Event'] =='CLICK'){
    if($message['EventKey']=='ewm'){
         //如果二维码按钮被点击
         //创建ticket
         $result = $this->app->qrcode->forever($openId);
         $ticket = $result['ticket'];
         //获取二维码网址
         $url = $this->app->qrcode->url($ticket);
         //获取二维码
         $content = file_get_contents($url);
         //二维码写入文件
         file_put_contents(public_path().'/img/'.$openId.'.png',$content);
         $imgpath = "http://590c1c9e.nat123.cc/img/".$openId.".png";
          //将二维码上传至素材库
         $result = $this->app->material->uploadImage("D:/wamp64/www/Fx/public/img/".$openId.".png");
         //二维码发送给用户
         return new Image($result['media_id']);
            }
        }

建立三级分销关系 通过带参数的二维码获取代理关系 1.数据表增加“代理字段” p1,p2,p3分别为一级代理,二级代理,三级代理

代码语言:javascript复制
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->integer('p1')->default(0);//一级代理
        $table->integer('p2')->default(0);//二级代理
        $table->integer('p3')->default(0);//三级代理
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->DropCloumn('p1');
        $table->DropColumn('p2');
        $table->DropCloumn('p3');
    });
}

更新关注事件代码

代码语言:javascript复制
  public function event($message){
        $openId = $message['FromUserName'];//获取OpenID
        $user = $this->app->user->get($openId);//根据openId获取用户信息
        if($message['Event'] == 'subscribe'){
            //触发关注事件
            $sel = User::where('openId',$openId)->first();//根据openid查询是否已经有此用户
            if($sel){
                //如果有此用户 ,则恢复”软删除“
                User::where("openId",$openId)->update(['status'=>1]);
                return "欢迎关注";
            }else{
                //没有此用户则将用户存进数据库
                User::create(['name'=>$user['nickname'],'openId'=>$openId]);//用户直接关注默认为一级代理
                if($message['EventKey']){
                    //如果用户通过扫描代理二维码关注,生成代理关系
                    $oUserId = str_replace('qrscene_','',$message['EventKey']);    
                    //获取二维码信息(存储在二维码的Openid)
                    //二维码信息由前缀 “qrscne_” openid构成
                    $oUser = User::where('openId',$oUserId)->first();//获取代理人信息
                    User::where('openId',$openId)->update(['p1'=>$oUser->id,'p2'=>$oUser->p1,'p3'=>$oUser->p2]);//更新代理关系
                    return "你通过代理人".$oUser->name.'成为本平台用户';
                }
                return "欢迎关注";
            }    

        }elseif($message['Event'] == 'unsubscribe'){
            //如果用户取消关注 软删除用户
            User::where("openId",$openId)->update(['status'=>0]);
        }

第三方授权登录 这个系统是“微分销”系统,代理人需要要通过本系统购买货物,这里肯定会通过公众号链接到第三方购物平台,问题是在第三方平台,我们如何获取用户信息?,答案通过微信授权登录,第三方购物平台通过用户微信登录可获取用户信息,现在的授权登录都遵循OAuth2.0协议 OAuth2.0协议官方流程图

我们将 AB,CD,EF分成三步,来理解(以微博登录为例) 假设你的网站需要接入第三方微博登录。

  • 第一步:客户端请求微博服务器(也就是用户点击第三方微博登录),用户登录后,此时用户的信息是存放在微博服务器的,微博服务器会返回一个code值给客户端,这里是AB;
  • 第二步:客户端拿到这个code值后,会再次请求微博服务器,微博服务器根据code值返回给客户端一个ACCESS_TOKEN令牌,这里就是CD。
  • 第三步:客户端获取到令牌后,会再次请求微博服务器以获取用户信息,这里会把令牌发送给微博服务器,微博服务器经检测令牌合法,将用户信息返回给客户端,至此已经完成了第三方平台登录 完成一个案例,更好的理解第三方授权登录,这里还是以微博登录为例

1.注册微博开放平台

注册认证后点击微连接--网站接入--创建应用

由于审核较为麻烦,微博为我们提供了测试账号 点击“应用信息--测试信息--绑定你的微博昵称”

点击应用信息---高级信息

设置登录成功的回调地址以及取消授权的回调地址 设置完成后,点击文档---微博登录

找到Web网站,列出以下调用接口

点击第一个引导用户登录的接口 1.获取code Url:https://api.weibo.com/oauth2/authorize HTTP请求方式 GET/POST

编写模板

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>微博登录</title>
</head>
<body>
    <form action="https://api.weibo.com/oauth2/authorize" method="post">
    //请求地址
        <input type="hidden" name="client_id" value='1553894068'>
        <input type="hidden" name="redirect_uri" value="http://590c1c9e.nat123.cc/weibo/center">
        <input type="submit" value="微博登录">
    </form>
</body>
</html>

点击登录

点击二维码登录,会跳转到我们的回调地址

可以看到地址栏,出现了code值,我们需要根据这个code值获取ACCESS_TOKEN令牌

2.获取令牌

调用第二个接口

Url

https://api.weibo.com/oauth2/access_token

HTTP请求方式

POST

代码语言:javascript复制
 public function center(){
        if(!empty($_GET)){
            $code = $_GET['code'];//获取微博服务器返回的code值
            $url = 'https://api.weibo.com/oauth2/access_token';
            $data = [
                'client_id' => '1553894068',
                'client_secret'=>'b99b5c86e01ed71e3f58dd5b2cd1db1a',
                'grant_type'=>'authorization_code',
                'code'=>$code,
                'redirect_uri'=>'http://590c1c9e.nat123.cc/weibo/center'//回调地址
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_POST, 1);
            //post变量.一定要用http_build_query处理下请求
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            curl_setopt($ch,CURLOPT_RETURNTRANSFER ,1);
            $output = curl_exec($ch);
            curl_close($ch);
            dump($output);

        }
    }

点击登录打印返回值

3.查询用户信息 点击 “文档--微博API”找到获取用户信息接口

URL https://api.weibo.com/2/users/show.json 支持格式 JSON

HTTP请求方式 GET

代码语言:javascript复制
public function center(){
        if(!empty($_GET)){
            $code = $_GET['code'];//获取微博服务器返回的code值
            $url = 'https://api.weibo.com/oauth2/access_token';
            $data = [
                'client_id' => '1553894068',
                'client_secret'=>'b99b5c86e01ed71e3f58dd5b2cd1db1a',
                'grant_type'=>'authorization_code',
                'code'=>$code,
                'redirect_uri'=>'http://590c1c9e.nat123.cc/weibo/center'//回调地址
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_POST, 1);
            //post变量.一定要用http_build_query处理下请求
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            curl_setopt($ch,CURLOPT_RETURNTRANSFER ,1);
            $output = curl_exec($ch);
            curl_close($ch);
           $usermes = json_decode($output);
           //查询用户信息
           $access_token = $usermes->access_token;
           $uid = $usermes->uid;
           $res = file_get_contents('https://api.weibo.com/2/users/show.json?access_token='.$access_token.'&uid='.$uid);
           dump($res);

        }
    }

返回json格式数据,至此已经完成第三方授权登录 上面的案例只是为了更好的理解Oauth2.0协议,接下来将第三方授权登录应用到我们的项目上,微信授权登录不过这里使用了easywechat,实现更简单 阅读文档微信网页开发----微信授权 1.测试账号设置登录回调地址---网页账号----网页授权获取用户基本信息---修改

2.使用easywechat实现授权登录 配置文件设置oauth

代码语言:javascript复制
 /*
             * OAuth 配置
             *
             * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
             * callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。)
             */
    'oauth' => [
                'scopes'   => array_map('trim', explode(',', env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES', 'snsapi_userinfo'))),
                'callback' => env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK', '/wechat/login'),
            ],

2.创建用户控制器

代码语言:javascript复制
<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use EasyWeChatFactory;
use AppUser;
class UserController extends Controller
{
    public $app = null;

    public function __construct(){
    $this->app = app('wechat.official_account');
    }

3.easywechat文档 ”网页授权“

在 SDK 中,我们使用名称为 oauth 的模块来完成授权服务

使用easywechatSDK完成用户授权并获取信息非常简单,你只需使用下面这两个方法即可

代码语言:javascript复制
$oauth = $this->app->oauth;//
 return $oauth->redirect();//用户未登录回调到用户登录界面
代码语言:javascript复制
//用户登录界面
$user = $this->app->oauth->user();//获取用户信息
//调用这个方法自动完成用户登录授权

3.1控制器准备两个方法,用户登录,和用户以授权方法

代码语言:javascript复制
public function center(){
        //判断用户是否登录
        if(!session()->has('wechat_user')){
            //如果用户没有登录
            //获取oauth实例
            $oauth = $this->app->oauth;
            return $oauth->redirect();//如果用户没有登录回调到配置文件的oauth的callback
        }
        return "Hello word";
    }
    public function login(){
        //
        $user = $this->app->oauth->user();//获取用户信息,这里已经完成用户登录授权了
        session(['wechat_user'=>$user->getId()]);//用户Openid信息存储到session
        return redirect('wechat/center');//回调到用户认证页面
    }

访问”商城链接“

这里我先前测试已经登录一次

登录成功

0 人点赞