WeChatDeveloper for PHP
- WeChatDeveloper 是基于 wechat-php-sdk 重构,优化并完善;
- 运行最底要求 PHP 版本 5.4 , 建议在 PHP7 上运行以获取最佳性能;
- WeChatDeveloper 针对 access_token 失效增加了自动刷新机制;
- 微信的部分接口需要缓存数据在本地,因此对目录需要有写权限;
- 我们鼓励大家使用 composer 来管理您的第三方库,方便后期更新操作;
- WeChatDeveloper 已历经数个线上项目考验,欢迎 fork 或 star 此项目。
- 微信商户支持已经支持 v2 接口,组件开发版支持 v3 接口。
功能描述
- 微信小程序,服务端接口支持
- 微信认证服务号,服务端接口支持
- 微信支付(账单、卡券、红包、退款、转账、App支付、JSAPI支付、Web支付、扫码支付等)
- 支付宝支付(账单、转账、App支付、刷卡支付、扫码支付、Web支付、Wap支付等
- 在微信公众平台手动配置获取模板 ID
- 使用小程序api wx.requestSubscribeMessage 获取下发权限
- 再调用服务端接口 subscribeMessage.send 发送消息
选取图片或视频
小程序码传参
//传一个参数 或 多个参数
onLoad:function(options){
if(options.scene){
// options 中的 scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
var scene = decodeURIComponent(options.scene)
}
}
onLoad:function(options){
// options 中的 scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
var scene = decodeURIComponent(options.scene);
var obj = {};
for (var i = 0; i < scene.split('*').length;i++){
var arr = scene.split('*')[i].split('/');
obj[arr[0]] = arr[1];
}
return obj
}
小程序登录
先调用小程序api wx.login 获取code 传递给服务端接口 ,由服务端调用微信服务端接口code2Session 获取openid
wx.login({
success (res) {
if (res.code) {
//发起网络请求
wx.request({
url: 'https://example.com/onLogin',
data: {
code: res.code
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
$config = [
'appid' => 'xxx',
'appsecret' => 'xxx',
];
$code = input('get.code');
try {
$test = \WeMini\Crypt($config);
$test->session($code);
}catch (Exception $e) {
}
小程序授权
部分接口需要经过用户授权同意才能调用。我们把这些接口按使用范围分成多个 scope
,用户选择对 scope
来进行授权,当授权给一个 scope
之后,其对应的所有接口都可以直接使用
//检查用户是否授权wx.getSetting, 如果没有则使用wx.authorize 向用户发起授权
// 可以通过 wx.getSetting 先查询一下用户是否授权了 "scope.record" 这个 scope
wx.getSetting({
success(res) {
if (!res.authSetting['scope.record']) {
wx.authorize({
scope: 'scope.record',
success () {
// 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
wx.startRecord()
}
})
}
}
})
表单组件中button组件的open-type 属性 设置 openSetting 可打开授权设置页
获取用户信息
使用接口wx.getUserProfile 每次都需要用户授权,页面产生点击事件后才可以调用
getUserProfile(e) {
// 推荐使用 wx.getUserProfile 获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
// 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
wx.getUserProfile({
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
})
},
视频播放
使用媒体组件video,要求基础库版本在2.19.5 之后我选择的是2.25.4 版本,当路由跳转至下一页面或离开当前页面时触发小窗,客户端调试看不到小窗,需要真机调试才能看到小窗
index.wxml
<view class="page-body">
<view class="page-section tc">
<video
id="myVideo"
src="http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400"
binderror="videoErrorCallback"
danmu-list="{{danmuList}}"
enable-danmu
danmu-btn
show-center-play-btn='{{false}}'
show-play-btn="{{true}}"
controls
picture-in-picture-mode="{{['push', 'pop']}}"
bindenterpictureinpicture='bindVideoEnterPictureInPicture'
bindleavepictureinpicture='bindVideoLeavePictureInPicture'
></video>
<view style="margin: 30rpx auto" class="weui-label">弹幕内容</view>
<input bindblur="bindInputBlur" class="weui-input" type="text" placeholder="在此处输入弹幕内容" />
<button style="margin: 30rpx auto" bindtap="bindSendDanmu" class="page-body-button" type="primary" formType="submit">发送弹幕</button>
<navigator style="margin: 30rpx auto" url="/pages/test/test" hover-class="other-navigator-hover">
<button type="primary" class="page-body-button" bindtap="bindPlayVideo">小窗模式</button>
</navigator>
</view>
</view>
index.js
// index.js
// 获取应用实例
const app = getApp()
function getRandomColor() {
const rgb = []
for (let i = 0; i < 3; ++i) {
let color = Math.floor(Math.random() * 256).toString(16)
color = color.length === 1 ? '0' + color : color
rgb.push(color)
}
return '#' + rgb.join('')
}
Page({
onShareAppMessage() {
return {
title: 'video',
path: 'page/component/pages/video/video'
}
},
onReady() {
this.videoContext = wx.createVideoContext('myVideo')
},
onHide() {
},
inputValue: '',
data: {
src: '',
danmuList:
[{
text: '第 1s 出现的弹幕',
color: '#ff0000',
time: 1
}, {
text: '第 3s 出现的弹幕',
color: '#ff00ff',
time: 3
}],
},
bindInputBlur(e) {
this.inputValue = e.detail.value
},
bindButtonTap() {
const that = this
wx.chooseMedia({
sourceType: ['album', 'camera'],
maxDuration: 60,
camera: ['front', 'back'],
success(res) {
that.setData({
src: res.tempFilePath
})
}
})
},
bindVideoEnterPictureInPicture() {
console.log('进入小窗模式')
},
bindVideoLeavePictureInPicture() {
console.log('退出小窗模式')
},
bindPlayVideo() {
console.log('1')
this.videoContext.play()
},
bindSendDanmu() {
this.videoContext.sendDanmu({
text: this.inputValue,
color: getRandomColor()
})
},
videoErrorCallback(e) {
console.log('视频错误信息:')
console.log(e.detail.errMsg)
}
})