微信开发第三天,利用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
'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验证
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_id
及url
我们拿到media_id
就可以使用素材管理库的图片了 如下案例(由于下面生成二维码的时候调用接口次数达到上限了,这里就将就二维码的图片算了)
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
分别为一级代理,二级代理,三级代理
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
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
/*
* 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');//回调到用户认证页面
}
访问”商城链接“
这里我先前测试已经登录一次
登录成功