Compare commits

...

126 Commits
main ... src

Author SHA1 Message Date
pvfho47bq 41886c17e8 Update wxbizmsgcrypt.lib.php
7 months ago
pvfho47bq 602990fcd6 Update wechatrequest.lib.php
7 months ago
pvfho47bq 598fef975e Update wechatoauth.lib.php
7 months ago
pvfho47bq caf5d39b47 Update usermanage.lib.php
7 months ago
pvfho47bq 8413a268a1 Update responseinitiative.lib.php
7 months ago
pvfho47bq 95feafe25d Update msg.lib.php
7 months ago
pvfho47bq 2686a9c0f8 Update curl.lib.php
7 months ago
pvfho47bq d69096f2f2 Update autoreply.lib.php
7 months ago
pvfho47bq ca36fb5e17 Update auth.lib.php
7 months ago
pvfho47bq 68fb159be6 Update advancedbroadcast.lib.php
7 months ago
pvfho47bq 398209864c Update accesstoken.lib.php
7 months ago
pvfho47bq f8fd1083f4 Update wechat.php
7 months ago
pvfho47bq 7d118bb23f Update config.php
7 months ago
pvfho47bq 92df45ce66 Update autoloader.php
7 months ago
mlg6veufz c71fdaaa70 添加README.md的总结与摘要
7 months ago
pfspx4a7z dfdaa15be9 Update wechat.php
7 months ago
pfspx4a7z 63e373c3a6 Update demo.php
7 months ago
mlg6veufz 2cdb8db004 补充总结autoreply.lib.php
7 months ago
pfspx4a7z 8077c40a06 Update autoloader.php
7 months ago
pfspx4a7z 0841725b98 Update demo.php
7 months ago
pfspx4a7z 8b77cea77e Update popularize.lib.php
7 months ago
pfspx4a7z 10c9d524e2 Update msgconstant.lib.php
7 months ago
pfspx4a7z 01b4522789 Update config.php
7 months ago
mlg6veufz 8735e8c142 Update responsepassive.lib.php
7 months ago
pfspx4a7z fbae62df85 Update demo.php
7 months ago
pfspx4a7z 930bdb2da0 Update lanewechat.php
7 months ago
pfspx4a7z 4d71e8d334 Update wechat.php
7 months ago
pfspx4a7z 395b05b151 Update media.lib.php
7 months ago
pfspx4a7z d34e6051df Update customservice.lib.php
7 months ago
pfspx4a7z c2fa6464ed Update demo.php
7 months ago
mlg6veufz 5202155799 补充注释usermanage.lib.php
7 months ago
pfspx4a7z 5b063af014 Update curl.lib.php
7 months ago
pfspx4a7z 83ba899c3d Update .gitignore
7 months ago
pfspx4a7z 32026197ce Update demo.php
7 months ago
pfspx4a7z 4b307cce91 Update sha1.lib.php
7 months ago
pfspx4a7z 551a2dcc50 Update pkcs7encoder.lib.php
7 months ago
pfspx4a7z d6fb62e511 Update prpcrypt.lib.php
7 months ago
pfspx4a7z 3c0db1d786 Update errorcode.lib.php
7 months ago
pfspx4a7z 05f1922108 Update autoloader.php
7 months ago
pfspx4a7z a1fd22b704 Update config.php
7 months ago
pfspx4a7z b332314b10 Update lanewechat.php
7 months ago
pfspx4a7z dd123bafcd Update wechat.php
7 months ago
pfspx4a7z be7dac4412 Update wxbizmsgcrypt.lib.php
7 months ago
pfspx4a7z 2822c864f7 Update demo.php
7 months ago
pfspx4a7z 953d0400e8 Update xmlparse.lib.php
7 months ago
pfspx4a7z d769617905 Update customservice.lib.php
7 months ago
pfspx4a7z 8c639a6fe3 Update media.lib.php
7 months ago
pfspx4a7z 26722ce148 Update menu.lib.php
7 months ago
pfspx4a7z 451db28d24 Update msgconstant.lib.php
7 months ago
pfspx4a7z 56affb386d Update popularize.lib.php
7 months ago
mlg6veufz c6a8da3dbc 补充wechatoauth.lib.php
7 months ago
pfspx4a7z fc93464211 Update responsepassive.lib.php
7 months ago
mlg6veufz 82d49db4b9 对于核心类wechatrequest进行补充总结
7 months ago
pfspx4a7z 3c4f67fbd5 Update templatemessage.lib.php
7 months ago
pfspx4a7z 89c91a1f7c Update usermanage.lib.php
7 months ago
mlg6veufz 3dc34cea48 进一步详细注释 responseinitiative.lib.php
7 months ago
pfspx4a7z 6e32234adf Update wechat.lib.php
7 months ago
p9x75mskn ea45a97354 Update curl.lib.php
7 months ago
pfspx4a7z 64fc89851c Update wechatoauth.lib.php
7 months ago
pfspx4a7z 0b861dbf90 Update wechatrequest.lib.php
7 months ago
mlg6veufz 6831003a82 对于popularize.lib.php的进一步详细注释
7 months ago
pvfho47bq 0110dde36d Update sha1.lib.php
7 months ago
pvfho47bq 581a87a1d2 Update wechatoauth.lib.php
7 months ago
pvfho47bq 85b1a28e52 Update media.lib.php
7 months ago
p9x75mskn 0e3179819f Update responseinitiative.lib.php
7 months ago
pfspx4a7z 0d700e5ccd Update intelligentinterface.lib.php
7 months ago
pvfho47bq ede1deaffd Update auth.lib.php
7 months ago
pfspx4a7z b6e66bacf9 Update customservice.lib.php
7 months ago
pfspx4a7z 3439c005e8 Update curl.lib.php
7 months ago
pfspx4a7z 7b529c7fca Update autoreply.lib.php
7 months ago
pfspx4a7z fe588f69bd Update auth.lib.php
7 months ago
pfspx4a7z 3253d4f339 Update advancedbroadcast.lib.php
7 months ago
pfspx4a7z 2be7e3d181 Update accesstoken.lib.php
7 months ago
fanbo becdac8a66 对advancedbroadcast.lib和usermanage.lib做注释
7 months ago
pvfho47bq 488df14ba4 Update demo.php
7 months ago
pvfho47bq 437a31879c Update lanewechat.php
7 months ago
p9x75mskn 0dec770ce8 Update wechat.php
7 months ago
pvfho47bq 491d108cb6 Update config.php
7 months ago
p9x75mskn a641202682 Update wechatoauth.lib.php
7 months ago
fanbo 40c58d749f 将readme从doc转移到src
7 months ago
p9x75mskn 38d9717a6c Update wechat.lib.php注释
7 months ago
mlg6veufz c1eb3c2b85 注释responsepassive.lib.php
7 months ago
fanbo 9cef04db85 对errorcode.lib代码文件做注释
7 months ago
fanbo 4e964c25df 对pkcs7encoder.lib、sha1.lib、wxbizmsgcrypt.lib、xmlparse.lib代码文件做注释
7 months ago
fanbo b88beea067 对prpcrypt.lib.php代码进行注释
7 months ago
fanbo 0277f75d29 对demo.php进行注释
7 months ago
pf7lbvaho bf8ec9142b Update intelligentinterface.lib.php
7 months ago
pf7lbvaho 11404e174b Update customservice.lib.php
7 months ago
pf7lbvaho 6a4de7e2b6 Update curl.lib.php
7 months ago
fanbo 25d3fcc167 Merge branch 'src' of https://bdgit.educoder.net/pfspx4a7z/git-test into src
7 months ago
fanbo c20f8cb9ed 对templatemessage.lib.php代码文件进行注释
7 months ago
pfspx4a7z 841ef34f14 Update accesstoken.lib.php
7 months ago
pfspx4a7z 15758708ab Update auth.lib.php
7 months ago
fanbo 8c107f4bbf 对core文件夹中的autoreply.lib.php和curl.lib.php作标记注释
7 months ago
fanbo be5b58387c 对core文件夹中的代码文件msg.lib.php和msgconstant.lib.php做标记注释
7 months ago
fanbo a83b65e7f2 增加了新的代码文件,以完善软件功能
7 months ago
fanbo 95742fda2f menu.lib.php的注释修改
7 months ago
fanbo 70a75cfdf2 Merge branch 'src' of https://bdgit.educoder.net/pfspx4a7z/git-test into fanbo
8 months ago
fanbo 01485ff0ec 范博的代码
8 months ago
pvfho47bq 1576a8ce9c Update autoloader.php
8 months ago
p9x75mskn f1b41ef8c7 Update wechatrequest.lib.php
8 months ago
mlg6veufz 5036cf6ca7 Update responseinitiative.lib.php
8 months ago
pfspx4a7z 18cb74a836 Delete 'LaneWeChat-master.zip'
8 months ago
pfspx4a7z 2596ceda7f Update popularize.lib.php
8 months ago
fanbo e426c0f308 代码
8 months ago
mlg6veufz 0be0f0bb26 注释文件popularize
8 months ago
pzoxq8uvb 166c74733c ADD file via upload
8 months ago
pfspx4a7z 2f3b3af397 ADD file via upload
8 months ago
pfspx4a7z dd1e9658cb ADD file via upload
8 months ago
pzoxq8uvb fad75a5679 ADD file via upload
8 months ago
pfspx4a7z b43523fa5d ADD file via upload
8 months ago
pfspx4a7z 9c05108dac ADD file via upload
8 months ago
mlg6veufz 3e75813656 Update README.md
8 months ago
pf7lbvaho d1b13f3c9e Delete 'intelligentinterface.lib.php'
8 months ago
pf7lbvaho 9eb5f87e9c Delete 'customservice.lib.php'
8 months ago
pf7lbvaho 8d042c4b2b Delete 'curl.lib.php'
8 months ago
pf7lbvaho 50e632e202 ADD file via upload
8 months ago
pf7lbvaho c1aece466d ADD file via upload
8 months ago
pf7lbvaho d940c21c6a ADD file via upload
8 months ago
pf7lbvaho be32afb087 Delete 'src'
8 months ago
pf7lbvaho 521323b256 jyp 注释
8 months ago
pvfho47bq ee56594144 Update README.md
8 months ago
p9x75mskn d99b3c5326 Update README.md
8 months ago
pfspx4a7z c06c453329 Update README.md
8 months ago
pf7lbvaho 382480880f Update README.md
8 months ago
pfspx4a7z b7586fa1d6 ADD file via upload
9 months ago

2
.gitignore vendored

@ -0,0 +1,2 @@
LmlkZWEKLmdpdGlnbm9yZQouc3ZuCmNvbmZpZy55YW1sCi5EU19TdG9yZQpjb3JlLy5EU19TdG9yZQo=
https://code.educoder.net/pfspx4a7z/git-test/tree/src/.gitignore

@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2014 Lane
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

@ -1,2 +1,942 @@
# git-test
阅读总结与摘要
框架名称
LaneWeChat
框架简介
简介这是一个为快速开发微信应用而生的PHP框架。将微信的开发者功能根据文档进行了封装。为了快速开发的目的开发者完全不需要要知道具体是如何实现的只需要简单的调用方法即可。
开发语言
语言PHP
版本要求
要求原则PHP5.3以上
版本规避
规避若版本低于PHP5.3则删除本框架所有页面开头“namespace”的行、删除本框架中所有的“use LaneWeChat”开头的行删除“LaneWeChat\Core”修改Autoloader::NAMESPACE_PREFIX=''修改curl.lib.php的\Exception为Exception即可。
命名空间
命名空间本框架的命名空间均为LaneWeChat开头。
开源协议
协议Do What The Fuck You Want To Public License
开发者博客
博客http://www.lanecn.com
文档地址
地址http://lanewechat.lanecn.com/
更新日志
2015-04-29 1.5.1
新增获取微信服务器IP列表接口、接收消息类型小视频、模板消息-设置行业和获取模板ID等。
2014-12-04 1.4.2
解决CURL的GET调用在php5.3以下时出现errno=60(CA证书无效)的BUG等。
2014-11-051.4版本
兼容性升级、安全性升级、新增消息体签名加解密验证等。
2014-10-141.2.2版本。
新增自动载入函数。
2014-08-171.2版本。
新增自定义菜单功能、新增多媒体上传下载功能。
2014-08-071.0版本
文档目录
目录:
常识普及
如何安装
初出茅庐
流程分析
牛刀小试
函数详解
实例示范
常识普及
微信公众账号:分订阅号和服务号,订阅号每天推送一条消息,服务号每月推送一条消息。
专业术语OpenId、Access_Token等。
如何安装
安装步骤:
将框架以代码包的插件形式放在项目的目录中。
修改配置项如WECHAT_APPID、WECHAT_APPSECRET、WECHAT_URL等。
设置微信开发者-填写服务器配置页面的URL和Token。
初出茅庐
初试:给微信公众号发送一条文本消息,验证被动响应功能。
流程分析
流程:用户发送消息 -> 微信服务器处理 -> 调用框架入口文件 -> 解析消息 -> 调用相应方法 -> 返回响应给用户。
牛刀小试
修改代码:修改被动响应文本消息的内容,验证修改效果。
函数详解
被动给用户发送消息:如文本、图片、语音等。
AccessToken授权获取AccessToken用于主动操作。
主动给用户发送消息:如文本、图片、语音等。
用户及用户组管理:如获取用户信息、创建用户组等。
网页授权:获取用户数据。
多媒体上传下载:上传和下载多媒体文件。
自定义菜单:添加和管理自定义菜单。
高级群发接口根据分组或OpenID列表进行群发。
多客服接口:获取客服聊天记录、转发消息到客服等。
智能接口:语义理解等。
推广支持:生成二维码、长链接转短链接等。
模板消息接口:推送模板消息等。
安全性获取微信服务器IP列表等。
自动回复:获取自动回复规则等。
实例示范
通过网页授权获得用户信息:展示如何通过网页授权获取用户信息的完整流程。
被动响应用户 - 发送图文消息:展示如何被动响应用户发送图文消息的代码示例。
群发图文消息:展示如何群发图文消息的代码示例。
推送模板消息:展示如何推送模板消息的代码示例。
添加自定义菜单:展示如何添加自定义菜单的代码示例。
页面展示二维码:展示如何在页面中展示微信公众号二维码的代码示例。
框架名称LaneWeChat
框架简介这是一个为快速开发微信应用而生的PHP框架。将微信的开发者功能根据文档进行了封装。为了快速开发的目的开发者完全不需要要知道具体是如何实现的只需要简单的调用方法即可
开发语言PHP
版本要求原则PHP5.3以上
版本规避若版本低于PHP5.3则删除本框架所有页面开头“namespace”的行、删除本框架中所有的“use LaneWeChat”开头的行删除“LaneWeChat\Core”修改Autoloader::NAMESPACE_PREFIX=''修改curl.lib.php的\Exception为Exception即可。
命名空间本框架的命名空间均为LaneWeChat开头。
开源协议Do What The Fuck You Want To Public License
开发者博客http://www.lanecn.com
文档地址:<a href="http://lanewechat.lanecn.com/">http://lanewechat.lanecn.com/</a>
更新日志:
2015-04-29 1.5.1
1、新增获取微信服务器IP列表接口。如果需要安全性校验可以每次判断请求的来源IP。
2、新增接收消息类型小视频
3、新增 模板消息-设置行业 和 模板消息-获取模板ID
4、高级群发接口-根据分组群发 新增参数is_to_all使用is_to_all为true且成功群发会使得此次群发进入历史消息列表。
5、新增 高级群发接口-预览接口【订阅号与服务号认证后均可用】 和 高级群发接口-查询群发消息发送状态【订阅号与服务号认证后均可用】
6、新增 客服帐号管理-获取所有客服账号列表/添加客服账号/修改客服账号/删除客服账号/设置客服头像
7、新增 自动回复-获取自动回复 接口
2014-12-04 1.4.2
1、解决CURL的GET调用在php5.3以下时出现errno=60(CA证书无效)的BUG。解决人大志<229417598@qq.com>
2、文档、注释优化。zhulin3141
3、实战演练 - 添加微信自定义菜单 文档场景描述错误
2014-11-051.4版本
兼容性:
设置菜单Menu::setMenu($menuList)参数结构和返回值重写,不向下兼容。
根目录下新增lanewechat.php
在项目用需要使用本SDK的地方只需要include 'lanewechat/lanewechat.php'然后可以直接ClassName::method()调用即可。
安全性升级:
因为SSL爆出高危漏洞公众平台在2014.11.30起将关闭SSLv2SSLv3版本的支持。根据官方实例LaneWeChat的CURL类中也将使用curl_setopt($curl, CURLOPT_SSLVERSION, 1)
新增消息体签名加解密验证EncodingAESKey默认为空为空时微信公众号平台会自动生成。也可以开发者自行手动指定。
新增语音消息识别
新增高级群发接口:
1 上传图文消息素材
2 根据分组进行群发,可发送图文消息,文本消息,图片消息,语音消息,视频消息。
3 根据OpenID列表群发可发送图文消息文本消息图片消息语音消息视频消息。
4 删除群发
5 事件推送群发结果
新增模板消息接口:
1、主动推送给用户模板消息的接口
2、被动接收微信服务器发送的关于主动推送模板消息的结果通知。
用户管理接口:
1、新增设置备注名。开发者可以通过该接口对指定用户设置备注名该接口暂时开放给微信认证的服务号。
网页授权接口:
注意此access_token与基础支持的access_token不同。
1、新增刷新access_token。由于access_token拥有较短的有效期当access_token超时后可以使用refresh_token进行刷新refresh_token拥有较长的有效期7天、30天、60天、90天当refresh_token失效的后需要用户重新授权。
2、新增scope为snsapi_userinfo的模式下会在网页弹出一个授权框拉取用户信息的接口。
3、新增检验授权凭证access_token是否有效接口
新增多客服功能:
1、新增将消息转发到多客服接口在接收到用户发送的消息时调用ResponsePassive::forwardToCustomService($fromusername, $tousername),微信服务器在收到这条消息时,会把这次发送的消息转到多客服系统。用户被客服接入以后,客服关闭会话以前,处于会话过程中,用户发送的消息均会被直接转发至客服系统。
2、新增获取客服聊天记录接口在需要时开发者可以通过获取客服聊天记录接口获取多客服的会话记录包括客服和用户会话的所有消息记录和会话的创建、关闭等操作记录。利用此接口可以开发如“消息记录”、“工作监控”、“客服绩效考核”等功能。
自定义菜单:
警告设置菜单Menu::setMenu($menuList)参数结构和返回值重写自1.4版本起不向下兼容。
注意所有新增的菜单类型仅支持微信iPhone5.4.1以上版本和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。
1、新增“scancode_push扫码推事件”类型菜单
用户点击按钮后微信客户端将调起扫一扫工具完成扫码操作后显示扫描结果如果是URL将进入URL且会将扫码的结果传给开发者开发者可以下发消息。
2、新增“scancode_waitmsg扫码推事件且弹出消息接收中提示框”类型菜单
用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。
3、新增“pic_sysphoto弹出系统拍照发图”类型菜单
用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。
4、新增“pic_photo_or_album弹出拍照或者相册发图”类型菜单
用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。
5、新增“pic_weixin弹出微信相册发图器”类型菜单
用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。
6、新增“location_select弹出地理位置选择器”类型菜单
用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。
7、新增了以上6种菜单类型、view点击跳转链接的菜单类型的被动响应的支持。默认讲点击菜单的事件推送数据发送文本消息返回给用户。开发者请自行修改。
新增语义理解接口
1、如输入“查一下明天从北京到上海的南航机票”类型为“flight,hotel”则返回机票信息。
新增推广支持:
1、新增获取二维码接口。二维码分临时二维码和永久二维码。第一步先获取ticket第二部是拿ticket获取二维码图片。二维码可以保存为文件也可以展示预览。
2、新增长链接转短链接接口。
新增实例示范:
1、被动响应用户 - 发送图文消息
2、群发图文消息
3、推送模板消息
4、添加自定义菜单
5、页面展示二维码
关于获取用户信息的新亮点 - unionId
获取用户信息是根据openId获取同一个微信用户对于不同的公众号是不同的openId。那问题就来了如果你有多个公众号想要共享一份用户数据可是同一个用户在不同的公众号是不同的openId我们无法判断是否是同一个用户现在微信引入了UnionId的概念。
如果开发者有在多个公众号或在公众号、移动应用之间统一用户帐号的需求需要前往微信开放平台open.weixin.qq.com绑定公众号后才可利用UnionID机制来满足上述需求。
在绑定了公众号后我们根据openId获取用户信息的时候会新增一个字段“unionid”只要是同一个用户在不同的公众号用不同的openId获取用户信息的时候unionid是相同的。
此功能不需要新增/修改代码只需要在微信开放平台绑定公众号就可以了。仍旧使用获取用户信息接口UserManage::getUserInfo($openId);
2014-10-141.2.2版本。新增自动载入函数
2014-08-171.2版本。新增自定义菜单功能、新增多媒体上传下载功能。
2014-08-071.0版本
文档目录:
1、常识普及。
2、如何安装。
3、初出茅庐。
4、流程分析。
5、牛刀小试。
6、函数详解。
7、实例示范。
常识普及:
一、微信公众账号分两种,一种是订阅号,一种是服务号。
1、订阅号是被动响应用户消息功能并且每天推送一条消息。
2、服务号是300元/每年认证,被动响应用户消息,主动给用户发送消息,自定义菜单按钮,网页授权等功能,并且每月推送一条消息。
3、订阅号适合消息类新闻类应用常常需要推送文章给用户的服务号适合自助查询等。
4、订阅号被认证后也享用自定义菜单等功能仍旧是300元/每年
二、专业术语:
1、OpenId微信服务器并不会告诉公众号用户的微信ID即使是你的关注者也不行为了解决开发中唯一标识的问题微信使用了OpenId所谓的OpenId就是用户和微信公众号之间的一种唯一关系。一个用户在一个公众号面前享用唯一的OpenId不会和别人重复。换言之同一个用户在另一个公众号面前是拥有另一个OpenId的。再直白些就是$openId = md5('用户微信ID+公众号ID')
2、Access_Token此项只有认证号的功能才会使用的到Access_token是一个授权标识即一个授权验证码一个标识10分钟内有效10分钟的有效期内公众号的多个关注者可以使用同一个Access_Token。在使用主动给指定用户发送消息、自定义菜单、用户管理和用户组管理等功能的时候每次操作需要给微信服务器以参数的形式附带Access_token。
3、Access_Token网页版本Access_Token网页版授权时会使用到和2中的Access_Toekn是不同的东西不过使用我们的LaneWeChat微信快速开发框架是不需要了解这些的。Access_Token网页版是说在用户打开你的公众号提供的网页的时候你的网页需要获取用户的OpenId、昵称、头像等信息的时候授权用的。同时本Access_Token网页版有两种用法一种是打开网页后弹出一个授权框让用户点击是否授权界面像主流的开放平台授权界面比如QQ登陆某网站支付宝账号登陆某网站等另一种是不需要弹出授权框仍旧可以获取用户信息用法可以在实例中看到。
如何安装:
1、本框架以代码包的插件形式放在项目的目录中即可。调用时只需要include 'lanewechat/lanewechat.php'即可。如:
<?php
include 'lanewechat/lanewechat.php';
//获取自定义菜单列表
$menuList = Menu::getMenu();
2、配置项打开根目录下的config.php修改定义常量WECHAT_APPIDWECHAT_APPSECRETWECHAT_URL。其中前两项可以在微信公众号官网的开发者页面中找到而WECHAT_URL是你微信项目的URL以http://开头
3、本框架的外部访问唯一入口为根目录下的wechat.php本框架的内部调用唯一入口为根目录下的lanewechat.php。两者的区别是wechat.php是通过http://www.abc.com/lanewechat/wechat.php访问是留给微信平台调用的入口。而lanewechat.php是我们项目内部调用时需要include 'lanewechat/lanewechat.php';
4、首次使用时请打开根目录下的wechat.php注释掉26行并且打开注释第29行。
5、在微信开发者-填写服务器配置页面填写URL为http://www.lanecn.com/wechat.php保证该URL可以通过80端口正常访问微信服务器目前只支持80端口并且将Token填写为config.php中的WECHAT_TOKEN常量的内容可以修改
6、微信服务器在第4步验证通过后反向操作第4步即注释掉第27行打开注释第26行。至此安装配置完成。
初出茅庐:
1、给你的微信公众号发送一条文本消息比如hello world或者其他什么的。这个时候你应该会收到一条“收到文本”的服务器反馈的被动响应的消息。
2、这个时候你需要先为自己鼓掌。
流程分析:
1、我们给微信服务器发送了一条“hello world”的文本消息。
2、微信服务器收到我们的消息后查找该公众账号所配置的服务器信息中的URL如何安装部分 - 第5步
3、微信服务器向第二步获取的URL发送请求参数是微信服务器自己拼接过的XML格式。
4、根目录下的wechat.php引入了我们的配置文件和所需的类后进入了类WeChat的方法run()。该类位于core/wechat.lib.php。微信的XML数据此时已经被解析为数组变量名为$request。
5、然后我们进入了类WechatRequest的方法switchType(),根据不同的消息类型,给予不同的响应。比如用户发送文本消息和关注事件,给出的返回应该是不同的。当然,你要给出同样的提示也不能说是错的。
6、在第5步中的方法中是一个switch根据消息类型此时是文本类型微信服务器给我的是text选择了一个处理文本消息的方法类WechatRequest中的方法text()。该方法的功能是发送文本消息,文本内容是“收到文本”。
7、此时我们return了一个数据返回给了上层调用层层return就到了我们根目录的下的唯一入口文件wechat.php此时我们返回的数据被echo出来了。
8、微信服务器拿到了输出的数据微信服务器进行分析和处理将文本发送给了用户的微信客户端。我们就在手机上看到了微信输出的“收到文本”。
9、流程结束这就是发送“hello world”然后返回给用户“收到文本”。
牛刀小试:
1、打开core/wechatrequest.php文件讲方法text()中的变量修改为$content = '收到文本消息'.$request['content'];
2、保存并且上传到你的服务器。
3、在微信中打开你的公众号输入文本消息“hello world”。见证奇迹的时刻到了。这个时候你的手机微信客户端中现实的是“收到文本消息hello world”。
函数详解:
一、被动给用户发送消息。
1、类简介用户输入文本、图片、语音、音乐、视频等消息以及关注、取消关注上报地理位置等事件后服务器被动给出应答。
2、使用命名空间use LaneWeChat\Core\ResponsePassive;
3、参数 $fromusername = "谁发给你的用户的openId" 在变量$request['fromusername']中
$tousername = "你的公众号Id"; 在变量$require['tousername']中
$mediaId = "通过上传多媒体文件得到的id。";
4、发送文本
ResponsePassive::text($fromusername, $tousername, '文本消息内容');
5、发送图片
ResponsePassive::image($fromusername, $tousername, $mediaId);
6、发送语音
ResponsePassive::voice($fromusername, $tousername, $mediaId);
7、发送视频
ResponsePassive::video($fromusername, $tousername, $mediaId, '视频标题', '视频描述');
8、发送音乐
ResponsePassive::music($fromusername, $tousername, '音乐标题', '音乐描述', '音乐链接', '高质量音乐链接WIFI环境优先使用该链接播放音乐', '缩略图的媒体id通过上传多媒体文件得到的id');
9、发送图文
1创建图文消息内容
$tuwenList = array();
$tuwenList[] = array('title'=>'标题1', 'description'=>'描述1', 'pic_url'=>'图片URL1', 'url'=>'点击跳转URL1');
$tuwenList[] = array('title'=>'标题2', 'description'=>'描述2', 'pic_url'=>'图片URL2', 'url'=>'点击跳转URL2');
2构建图文消息格式
$itemList = array();
foreach($tuwenList as $tuwen){
$itemList[] = ResponsePassive::newsItem($tuwen['title'], $tuwen['description'], $tuwen['pic_url'], $tuwen['url']);
}
3发送图文消息
ResponsePassive::news($fromusername, $tousername, $itemList);
二、AccessToken授权。
1、类简介除了被动相应用户之外在主动给用户发送消息用户组管理等高级操作是需要AccessToken授权的我们调用一个URL给微信服务器微信服务器会返回给我们一个散列字符串在高级操作的时候需要将此串以参数的形式发送。散列字符串10分钟内有效过期需要重新获取获取新的后之前的全部失效。
2、使用命名空间use LaneWeChat\Core\AccessToken;
3、参数
4、获取AccessToken
AccessToken::getAccessToken(); 该调用会返回微信服务器散列后的AccessToken字符串。
5、温馨提示
如果暂且用不到此功能,请跳过。最后来看这里!
6、功能补充
有一个地方需要用户自行完善根据介绍我们已经知道了获取AccessToken只有10分钟的有效期过期需要重新获取。因此我们需要存储这个AccessToken。
由于大家的存储方式各不相同有Mysql的有Redis的有MongoDB的还有Session的。所以这里我讲存储和读取给留空了。
流程AccessToken类public方法只有一个就是getAccessToken()。这个方法会调用一个私有方法_checkAccessToken()来检测AccessToken是否存在并且是否过期如果不存在或过期则调用私有方法_getAccessToken()
完善步骤:
1、打开core/accesstoken.lib.php文件。
2、私有方法_getAccessToken()的倒数第二行return是倒数第一行在这个地方请讲变量$accessTokenJson存储起来变量$accessTokenJson是一个字符串。
3、私有方法_checkAccessToken()的第一行就是读取操作(有一行伪代码$accessToken = YourDatabase::get('access_token');),将刚才第二步的存储的东西给读出来,并且赋值给$accessToken。
4、在第二步的存储第三部的读取的时候请不要修改数据仅仅完善一个读和存的操作就可以了。
三、主动给用户发送消息。
1、类简介用户输入文本、图片、语音、音乐、视频等消息以及关注、取消关注上报地理位置等事件后服务器被动给出应答。
2、使用命名空间use LaneWeChat\Core\ResponsePassive;
3、参数 $tousername = "你的公众号Id"; 在变量$require['tousername']中
$mediaId = "通过上传多媒体文件得到的id。";
4、发送文本内容
ResponseInitiative::text($tousername, '文本消息内容');
5、发送图片
ResponseInitiative::image($tousername, $mediaId);
6、发送语音
ResponseInitiative::voice($tousername, $mediaId);
7、发送视频
ResponseInitiative::video($tousername, $mediaId, '视频描述', '视频标题');
8、发送地理位置
ResponseInitiative::music($tousername, '音乐标题', '音乐描述', '音乐链接', '高质量音乐链接WIFI环境优先使用该链接播放音乐', '缩略图的媒体id通过上传多媒体文件得到的id');
9、发送图文消息
1创建图文消息内容
$tuwenList = array();
$tuwenList[] = array('title'=>'标题1', 'description'=>'描述1', 'pic_url'=>'图片URL1', 'url'=>'点击跳转URL1');
$tuwenList[] = array('title'=>'标题2', 'description'=>'描述2', 'pic_url'=>'图片URL2', 'url'=>'点击跳转URL2');
2构建图文消息格式
$itemList = array();
foreach($tuwenList as $tuwen){
$itemList[] = ResponseInitiative::newsItem($tuwen['title'], $tuwen['description'], $tuwen['pic_url'], $tuwen['url']);
}
3发送图文消息
ResponseInitiative::news($tousername, $itemList);
四、用户及用户组管理。
1、类简介获取粉丝列表创建\修改用户组,讲用户添加\移除到用户组。
2、使用命名空间use LaneWeChat\Core\UserManage;
3、参数 $openId = '用户和微信公众号的唯一ID'; 在变量$require['openid']中
$mediaId = "通过上传多媒体文件得到的id。";
$groupId = '分组ID'; 在添加新分组、获取分组列表的时候可以得到
4、分组管理 - 创建分组
UserManage::createGroup('分组名');
5、分组管理 - 获取分组列表
UserManage::getGroupList();
6、分组管理 - 查询用户所在分组
UserManage::getGroupByOpenId($openId);
7、分组管理 - 修改分组名
UserManage::editGroupName($groupId, '新的组名');
8、分组管理 - 移动用户分组
UserManage::editUserGroup($openId, $groupId);
9、用户管理 - 获取用户基本信息
UserManage::getUserInfo($openId);
10、用户管理 - 获取关注者列表
UserManage::getFansList($next_openId='');
11、用户管理 - 获取网络状态
UserManage::getNetworkState();
12、设置备注名 开发者可以通过该接口对指定用户设置备注名,该接口暂时开放给微信认证的服务号。
UserManage::setRemark($openId, $remark);
$openId用户的openId
$remark新的昵称
13、关于获取用户信息的新亮点 - unionId
获取用户信息是根据openId获取同一个微信用户对于不同的公众号是不同的openId。那问题就来了如果你有多个公众号想要共享一份用户数据可是同一个用户在不同的公众号是不同的openId我们无法判断是否是同一个用户现在微信引入了UnionId的概念。
如果开发者有在多个公众号或在公众号、移动应用之间统一用户帐号的需求需要前往微信开放平台open.weixin.qq.com绑定公众号后才可利用UnionID机制来满足上述需求。
在绑定了公众号后我们根据openId获取用户信息的时候会新增一个字段“unionid”只要是同一个用户在不同的公众号用不同的openId获取用户信息的时候unionid是相同的。
此功能不需要新增/修改代码只需要在微信开放平台绑定公众号就可以了。仍旧使用获取用户信息接口UserManage::getUserInfo($openId);
五、网页授权。
1、类简介在网页中获取来访用户的数据。
2、使用命名空间use LaneWeChat\Core\WeChatOAuth;
3、参数 $openId = '用户和微信公众号的唯一ID'; 在变量$require['openid']中
$mediaId = "通过上传多媒体文件得到的id。";
$groupId = '分组ID'; 在添加新分组、获取分组列表的时候可以得到
4、获取CODE。
参数:$scopesnsapi_base不弹出授权页面只能获得OpenId;snsapi_userinfo弹出授权页面可以获得所有信息
参数:$redirect_uri将会跳转到redirect_uri/?code=CODE&state=STATE 通过GET方式获取code和state。获取CODE时发送请求和参数给微信服务器微信服务器会处理后将跳转到本参数指定的URL页面
WeChatOAuth::getCode($redirect_uri, $state=1, $scope='snsapi_base');
5、通过code换取网页授权access_tokenaccess_token网页版。首先请注意这里通过code换取的网页授权access_token,与基础支持中的access_token不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base则本步骤中获取到网页授权access_token的同时也获取到了openidsnsapi_base式的网页授权流程即到此为止。
参数:$code getCode()获取的code参数。$code = $_GET['code'];
WeChatOAuth::getAccessTokenAndOpenId($code);
6、刷新access_token如果需要
由于access_token拥有较短的有效期当access_token超时后可以使用refresh_token进行刷新refresh_token拥有较长的有效期7天、30天、60天、90天当refresh_token失效的后需要用户重新授权。
WeChatOAuth::refreshToken($refreshToken);
$refreshToken通过本类的第二个方法getAccessTokenAndOpenId可以获得一个数组数组中有一个字段是refresh_token就是这里的参数
7、拉取用户信息(需scope为 snsapi_userinfo)
如果网页授权作用域为snsapi_userinfo则此时开发者可以通过access_token和openid拉取用户信息了。
WeChatOAuth::getUserInfo($accessToken, $openId, $lang='zh_CN');
$accessToken:网页授权接口调用凭证。通过本类的第二个方法getAccessTokenAndOpenId可以获得一个数组数组中有一个字段是access_token就是这里的参数。注意此access_token与基础支持的access_token不同。
$openId:用户的唯一标识
$lang:返回国家地区语言版本zh_CN 简体zh_TW 繁体en 英语
8、检验授权凭证access_token是否有效
WeChatOAuth::checkAccessToken($accessToken, $openId){
$accessToken网页授权接口调用凭证。通过本类的第二个方法getAccessTokenAndOpenId可以获得一个数组数组中有一个字段是access_token就是这里的参数。注意此access_token与基础支持的access_token不同。
六、多媒体上传下载
1、类简介在网页中获取来访用户的数据。上传的多媒体文件有格式和大小限制如下
* 图片image: 1M支持JPG格式
* 语音voice2M播放长度不超过60s支持AMR\MP3格式
* 视频video10MB支持MP4格式
* 缩略图thumb64KB支持JPG格式
* 媒体文件在后台保存时间为3天即3天后media_id失效
2、使用命名空间use LaneWeChat\Core\Media;
3、参数 $filename 上传的文件的绝对路径
$type 媒体文件类型分别有图片image、语音voice、视频video和缩略图thumb
$mediaId = "通过上传多媒体文件得到的id。";
$groupId = '分组ID'; 在添加新分组、获取分组列表的时候可以得到
4、上传上传后微信服务器会返回一个mediaId。
Media::upload($filename, $type);
5、下载根据mediaId下载一个多媒体文件。
Media::download($mediaId);
七、自定义菜单
1、类简介添加自定义菜单。最多可以有三个一级菜单每个一级菜单最多可以有五个菜单。一级菜单最多4个汉字二级菜单最多7个汉字。创建自定义菜单后由于微信客户端缓存需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后再次关注则可以看到创建后的效果。
警告设置菜单Menu::setMenu($menuList)参数结构和返回值重写自1.4版本起不向下兼容。
注意所有新增的菜单类型除了click类型和view类型仅支持微信iPhone5.4.1以上版本和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。
摘自微信官方网站:目前自定义菜单接口可实现两种类型按钮,如下:
click
用户点击click类型按钮后微信服务器会通过消息接口推送消息类型为event的结构给开发者并且带上按钮中开发者填写的key值开发者可以通过自定义的key值与用户进行交互
view
用户点击view类型按钮后微信客户端将会打开开发者在按钮中填写的url值即网页链接达到打开网页的目的建议与网页授权获取用户基本信息接口结合获得用户的登入个人信息。
总结一下哦就是微信的菜单分两种一种是view型就是你设置一个网址点了这个菜单之后就跳到你设置的网址去了。另一种就是click型你设置一个key然后用户点击的时候会通过本框架唯一入口wechat.php发送一个消息类型为event的请求在wechatrequest.lib.php文件下的eventClick方法中可以使用。
1、新增“scancode_push扫码推事件”类型菜单
用户点击按钮后微信客户端将调起扫一扫工具完成扫码操作后显示扫描结果如果是URL将进入URL且会将扫码的结果传给开发者开发者可以下发消息。
2、新增“scancode_waitmsg扫码推事件且弹出消息接收中提示框”类型菜单
用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。
3、新增“pic_sysphoto弹出系统拍照发图”类型菜单
用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。
4、新增“pic_photo_or_album弹出拍照或者相册发图”类型菜单
用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。
5、新增“pic_weixin弹出微信相册发图器”类型菜单
用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。
6、新增“location_select弹出地理位置选择器”类型菜单
用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。
7、新增了以上6种菜单类型、view点击跳转链接的菜单类型的被动响应的支持。默认讲点击菜单的事件推送数据发送文本消息返回给用户。开发者请自行修改。
2、使用命名空间use LaneWeChat\Core\Menu;
3、设置菜单是所有的菜单数据全部发送一次可不是每新增一个只发一个菜单。
Menu::setMenu($menuList);
$menuLis 是菜单列表,结构如下:
$menuList array(
array('id'=>'1', 'pid'=>'0', 'name'=>'顶级分类一', 'type'=>'', 'code'=>''),
array('id'=>'2', 'pid'=>'1', 'name'=>'分类一子分类一', 'type'=>'click', 'code'=>'lane_wechat_menu_1_1'),
array('id'=>'3', 'pid'=>'1', 'name'=>'分类一子分类二', 'type'=>'1', 'code'=>'http://www.lanecn.com'),
array('id'=>'4', 'pid'=>'0', 'name'=>'顶级分类二', 'type'=>'1', 'code'=>'http://www.php.net/'),
array('id'=>'5', 'pid'=>'0', 'name'=>'顶级分类三', 'type'=>'2', 'code'=>'lane_wechat_menu_3'),
);
'id'是您的系统中对分类的唯一编号;
'pid'是该分类的上级分类顶级分类则填写0
'name'是分类名称;
'type'是菜单类型,如果该分类下有子分类请务必留空;
'type'的值从以下类型中选择click、view、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album、pic_weixin、location_select。
'code'是view类型的URL或者其他类型的自定义key如果该分类下有子分类请务必留空。
4、获取微信菜单获取到的是已经设置过的菜单列表格式为Json是微信服务器返回的原始数据。
Menu::getMenu();
5、删除微信菜单将会删除设置过的所有菜单一键清空
Menu::delMenu();
八、高级群发接口
1、类简介根据分组、openId列表进行群发推送。图文消息需要先将图文消息当作一个素材上传然后再群发其他类型的消息直接群发即可。
注意推送后用户到底是否成功接受微信会向公众号推送一个消息。消息类型为事件消息可以在lanewechat/wechatrequest.lib.php文件中的方法eventMassSendJobFinish(&$request)中收到这条消息。
2、使用命名空间use LaneWeChat\Core\AdvancedBroadcast;
3、上传图文消息。创建一个图文消息保存到微信服务器可以得到一个id代表这个图文消息发送的时候根据这个id发送就可以了。
Menu::uploadNews($articles);
$articles 是图文消息列表,结构如下:
$articles = array(
array('thumb_media_id'=>'多媒体ID由多媒体上传接口获得' , 'author'=>'作者', 'title'=>'标题', 'content_source_url'=>'www.lanecn.com', 'digest'=>'摘要', 'show_cover_pic'=>'是否设置为封面0或者1'),
array('thumb_media_id'=>'多媒体ID由多媒体上传接口获得' , 'author'=>'作者', 'title'=>'标题', 'content_source_url'=>'www.lanecn.com', 'digest'=>'摘要', 'show_cover_pic'=>'是否设置为封面0或者1'),
);
'thumb_media_id'多媒体ID由多媒体上传接口获得Media::upload($filename, $type);
'author'作者
'title'标题
'content_source_url'一个URL点击“阅读全文”跳转的地址
'digest'摘要
'show_cover_pic'0或1是否设置为封面。
下面的方法图文消息的参数mediaId是由上面这个方法3Menu::uploadNews($articles);获得的其他的mediaId是多媒体上传获得的Media::upload($filename, $type);
根据分组群发的所有接口最后一个参数,$isToAll默认未false。使用true且成功群发会使得此次群发进入历史消息列表。
4、根据分组进行群发 - 发送图文消息:
AdvancedBroadcast::sentNewsByGroup($groupId, $mediaId, $isToAll=false);
5、根据分组进行群发 - 发送文本消息
AdvancedBroadcast::sentTextByGroup($groupId, $content, $isToAll=false);
6、根据分组进行群发 - 发送语音消息
AdvancedBroadcast::sentVoiceByGroup($groupId, $mediaId, $isToAll=false);
7、根据分组进行群发 - 发送图片消息
AdvancedBroadcast::sentImageByGroup($groupId, $mediaId, $isToAll=false);
8、根据分组进行群发 - 发送视频消息
AdvancedBroadcast::sentVideoByGroup($mediaId, $title, $description, $groupId, $isToAll=false);
9、根据OpenID列表群发 - 发送图文消息
AdvancedBroadcast::sentNewsByOpenId($toUserList, $mediaId);
10、根据OpenID列表群发 - 发送文本消息
AdvancedBroadcast::sentTextByOpenId($toUserList, $content);
11、根据OpenID列表群发 - 发送语音消息
AdvancedBroadcast::sentVoiceByOpenId($toUserList, $mediaId);
12、根据OpenID列表群发 - 发送图片消息
AdvancedBroadcast::sentImageByOpenId($toUserList, $mediaId);
13、根据OpenID列表群发 - 发送视频消息
AdvancedBroadcast::sentVideoByOpenId($toUserList, $mediaId, $title, $description);
14、删除群发
请注意,只有已经发送成功的消息才能删除删除消息只是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片。 另外,删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。
AdvancedBroadcast::delete($msgId);
$msgId:以上的群发接口成功时都会返回msg_id这个字段
15、预览图文消息
AdvancedBroadcast::previewNewsByGroup($openId, $mediaId);
16、预览文本消息
AdvancedBroadcast::previewTextByGroup($openId, $content);
17、预览语音消息
AdvancedBroadcast::previewVoiceByGroup($openId, $mediaId);
18、预览图片消息
AdvancedBroadcast::previewImageByGroup($openId, $mediaId);
19、预览视频消息
AdvancedBroadcast::previewVideoByGroup($mediaId, $title, $description, $openId);
20、查询群发消息发送状态【订阅号与服务号认证后均可用】
AdvancedBroadcast::getStatus($openId, $mediaId);
九、多客服接口
1、类简介客服功能接口。
2、使用命名空间use LaneWeChat\Core\CustomService;
3、获取客服聊天记录接口有分页一次获取一页一页最多1000条。不能跨日。
在需要时,开发者可以通过获取客服聊天记录接口,获取多客服的会话记录,包括客服和用户会话的所有消息记录和会话的创建、关闭等操作记录。利用此接口可以开发如“消息记录”、“工作监控”、“客服绩效考核”等功能。
CustomService::getRecord($startTime, $endTime, $pageIndex=1, $pageSize=1000, $openId='')
'startTime':查询开始时间UNIX时间戳
'startTime':查询结束时间UNIX时间戳每次查询不能跨日查询
4、将用户发送的消息转发到客服
调用ResponsePassive::forwardToCustomService($fromusername, $tousername)。
如用户在微信给公众号发送一条文本消息“iphone 6 多少钱我们就可以在lanewechat/wechatrequest.lib.php文件中的方法text(&$request)中收到这条消息(如果不了解为什么会在这里收到文本消息,请重头再看文档)。
然后在text(&$request)方法中我们可以调用ResponsePassive::forwardToCustomService($request['fromusername'], $request['tousername'])。那么刚才用户发的“iphone 6 多少钱?”就会被转发到客服系统,在微信的客服客户端中就可以收到了。
5、添加客服帐号
必须先在公众平台官网为公众号设置微信号后才能使用该能力。
开发者可以通过本接口为公众号添加客服账号每个公众号最多添加10个客服账号。
CustomService::addAccount($kfAccount, $nickname, $password)
$kfAccount String 完整客服账号,格式为:账号前缀@公众号微信号
$nickname String 昵称
$password String 密码
6、修改客服帐号
必须先在公众平台官网为公众号设置微信号后才能使用该能力。
CustomService::editAccount($kfAccount, $nickname, $password)
$kfAccount String 完整客服账号,格式为:账号前缀@公众号微信号
$nickname String 昵称
$password String 密码
7、删除客服帐号
必须先在公众平台官网为公众号设置微信号后才能使用该能力。
CustomService::delAccount($kfAccount, $nickname, $password)
$kfAccount String 完整客服账号,格式为:账号前缀@公众号微信号
$nickname String 昵称
$password String 密码
8、获取所有客服账号
必须先在公众平台官网为公众号设置微信号后才能使用该能力。
CustomService::getAccountList($kfAccount, $nickname, $password)
$kfAccount String 完整客服账号,格式为:账号前缀@公众号微信号
$nickname String 昵称
$password String 密码
9、设置客服帐号的头像
必须先在公众平台官网为公众号设置微信号后才能使用该能力。
CustomService::setAccountImage($kfAccount, $imagePath)
$kfAccount String 完整客服账号,格式为:账号前缀@公众号微信号
$imagePath String 待上传的头像文件路径
十、智能接口
1、类简介智能接口。
2、使用命名空间use LaneWeChat\Core\IntelligentInterface;
3、语义理解比如输入文本串如“查一下明天从北京到上海的南航机票”就可以收到关于这个问题的答案。
单类别意图比较明确识别的覆盖率比较大所以如果只要使用特定某个类别建议将category只设置为该类别。
IntelligentInterface::semanticSemproxy($query, $category, $openId, $latitude='', $longitude='', $region='', $city=''){
$query 输入文本串,如“查一下明天从北京到上海的南航机票"
$category String 需要使用的服务类型如“flight,hotel”多个用“,”隔开,不能为空。详见《接口协议文档》
$latitude Float 纬度坐标,与经度同时传入;与城市二选一传入。详见《接口协议文档》
$longitude Float 经度坐标,与纬度同时传入;与城市二选一传入。详见《接口协议文档》
$region String 区域名称,在城市存在的情况下可省;与经纬度二选一传入。详见《接口协议文档》
$city 城市名称,如“北京”,与经纬度二选一传入
$openId
《接口协议文档》http://mp.weixin.qq.com/wiki/images/1/1f/微信语义理解协议文档.zip
十一、推广支持
1、类简介推广支持。
2、使用命名空间use LaneWeChat\Core\Popularize;
3、生成带参数的二维码 - 第一步 创建二维码ticket
获取带参数的二维码的过程包括两步首先创建二维码ticket然后凭借ticket到指定URL换取二维码。
目前有2种类型的二维码分别是临时二维码和永久二维码
前者有过期时间最大为1800秒但能够生成较多数量后者无过期时间数量较少目前参数只支持1--100000
两种二维码分别适用于帐号绑定、用户来源统计等场景。
Popularize::createTicket($type, $expireSeconds, $sceneId);
$type Int 临时二维码类型为1永久二维码类型为2
$expireSeconds Int 过期时间只在类型为临时二维码时有效。最大为1800单位秒
$sceneId Int 场景值ID临时二维码时为32位非0整型永久二维码时最大值为100000目前参数只支持1--100000
4、生成带参数的二维码 - 第二步 通过ticket换取二维码
public static function getQrcode($ticket, $filename='');
$ticket Popularize::createTicket()获得的
$filename String 文件路径如果不为空则会创建一个图片文件二维码文件为jpg格式保存到指定的路径
返回值如果传递了第二个参数filename则会在filename指定的路径生成一个二维码的图片。如果第二个参数filename为空则直接echo本函数的返回值并在调用页面添加header('Content-type: image/jpg');,将会展示出一个二维码的图片。
5、将一条长链接转成短链接。
主要使用场景:开发者用于生成二维码的原链接(商品、支付二维码等)太长导致扫码速度和成功率下降,将原长链接通过此接口转成短链接再生成二维码将大大提升扫码速度和成功率。
Popularize::long2short($longUrl);
$longUrl String 需要转换的长链接支持http://、https://、weixin://wxpay 格式的url
十二、模板消息接口
1、类简介模板消息仅用于公众号向用户发送重要的服务通知只能用于符合其要求的服务场景中如信用卡刷卡通知商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。
关于使用规则,请注意:
1、所有服务号都可以在功能->添加功能插件处看到申请模板消息功能的入口,但只有认证后的服务号才可以申请模板消息的使用权限并获得该权限;
2、需要选择公众账号服务所处的2个行业每月可更改1次所选行业
3、在所选择行业的模板库中选用已有的模板进行调用
4、每个账号可以同时使用15个模板。
5、当前每个模板的日调用上限为10000次。
关于接口文档,请注意:
1、模板消息调用时主要需要模板ID和模板中各参数的赋值内容
2、模板中参数内容必须以".DATA"结尾,否则视为保留字;
3、模板保留符号"{{ }}"。
2、使用命名空间use LaneWeChat\Core\TemplateMessage;
3、向用户推送模板消息
TemplateMessage::sendTemplateMessage($data, $touser, $templateId, $url, $topcolor='#FF0000'){
$data = array(
'first'=>array('value'=>'您好,您已成功消费。', 'color'=>'#0A0A0A')
'keynote1'=>array('value'=>'巧克力', 'color'=>'#CCCCCC')
'keynote2'=>array('value'=>'39.8元', 'color'=>'#CCCCCC')
'keynote3'=>array('value'=>'2014年9月16日', 'color'=>'#CCCCCC')
'keynote3'=>array('value'=>'欢迎再次购买。', 'color'=>'#173177')
);
$touser 接收方的OpenId。
$templateId 模板Id。在公众平台线上模板库中选用模板获得ID
$url URL
$topcolor 顶部颜色,可以为空。默认是红色
注意推送后用户到底是否成功接受微信会向公众号推送一个消息。消息类型为事件消息可以在lanewechat/wechatrequest.lib.php文件中的方法eventTemplateSendJobFinish(&$request)中收到这条消息。
4、设置行业
TemplateMessage::setIndustry($industryId1, $industryId2){
$industryId1 公众号模板消息所属行业编号 请打开连接查看行业编号 http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html#.E8.AE.BE.E7.BD.AE.E6.89.80.E5.B1.9E.E8.A1.8C.E4.B8.9A
$industryId2 公众号模板消息所属行业编号。在公众平台线上模板库中选用模板获得ID
5、获得模板ID
TemplateMessage::getTemplateId($templateIdShort)
$templateIdShort 模板库中模板的编号有“TM**”和“OPENTMTM**”等形式
十三、安全性
1、类简介安全性相关接口
2、使用命名空间use LaneWeChat\Core\Auth;
3、获取微信服务器IP列表用于验证每次的请求来源是否是微信服务器。
Auth::getWeChatIPList();
十四、自动回复
1、类简介自动回复
2、使用命名空间use LaneWeChat\Core\AutoReply;
3、获取自动回复规则
AutoReply::getRole($industryId1, $industryId2);
返回结果与字段说明请查看http://mp.weixin.qq.com/wiki/7/7b5789bb1262fb866d01b4b40b0efecb.html
实例示范:
一、通过网页授权获得用户信息
场景用户点击了我的自定义菜单或者我发送的文本消息中包含一个URL用户打开了我的微信公众号的网页版我需要获取用户的信息。
代码:
<?php
use LaneWeChat\Core\WeChatOAuth;
use LaneWeChat\Core\UserManage;
//第一步获取CODE
WeChatOAuth::getCode('http://www.lanecn.com/index.php', 1, 'snsapi_base');
//此时页面跳转到了http://www.lanecn.com/index.phpcode和state在GET参数中。
$code = $_GET['code'];
//第二步获取access_token网页版
$openId = WeChatOAuth::getAccessTokenAndOpenId($code);
//第三步,获取用户信息
$userInfo = UserManage::getUserInfo($openId['openid']);
?>
二、被动响应用户 - 发送图文消息
场景描述:用户给我们的公众号发送了一条消息,我们的公众号被动响应,给用户回复一条图文消息。
场景举例:用户给我们的公众号发送了“周末聚会”,我们的公众号给用户回复了一条图文消息,有十条,每一条都是一个标题和图片,点击可以连接到一个地址。
代码:
//图文列表逐条放入数组
$tuwenList = array();
$tuwenList[] = array(
'title' => '标题:聚会地点一故宫',
'description' => '描述:还有人去故宫聚会啊',
'pic_url' => 'http://www.gugong.com/logo.jpg',
'url' => 'http://www.lanecn.com/',
);
$tuwenList[] = array(
'title' => '标题:聚会地点一八达岭',
'description' => '描述:八达岭是聚会的吗?是去看人挤人的!',
'pic_url' => 'http://www.badaling.com/logo.jpg',
'url' => 'http://www.lanecn.com/',
);
$item = array();
//构建图文列表
foreach($tuwenList as $tuwen){
$item[] = ResponsePassive::newsItem($tuwen['title'], $tuwen['description'], $tuwen['pic_url'], $tuwen['url']);
}
//发送图文列表
ResponsePassive::news($request['fromusername'], $request['tousername'], $item);
三、群发图文消息
场景描述:用户给我们的公众号发送了一条消息,我们的公众号被动响应,给用户回复一条图文消息。
场景举例:用户给我们的公众号发送了“周末聚会”,我们的公众号给用户回复了一条图文消息,有十条,每一条都是一个标题和图片,点击可以连接到一个地址。
代码:
$fansList = \LaneWeChat\Core\UserManage::getFansList();
//上传图片
$menuId = \LaneWeChat\Core\Media::upload('/var/www/baidu_jgylogo3.jpg', 'image');
if(empty($menuId['media_id'])){
die('error');
}
//上传图文消息
$list = array();
$list[] = array('thumb_media_id'=>$menuId['media_id'] , 'author'=>'作者', 'title'=>'标题', 'content_source_url'=>'www.lanecn.com', 'digest'=>'摘要', 'show_cover_pic'=>'1');
$list[] = array('thumb_media_id'=>$menuId['media_id'] , 'author'=>'作者', 'title'=>'标题', 'content_source_url'=>'www.lanecn.com', 'digest'=>'摘要', 'show_cover_pic'=>'0');
$list[] = array('thumb_media_id'=>$menuId['media_id'] , 'author'=>'作者', 'title'=>'标题', 'content_source_url'=>'www.lanecn.com', 'digest'=>'摘要', 'show_cover_pic'=>'0');
$mediaId = \LaneWeChat\Core\AdvancedBroadcast::uploadNews($list);
//给粉丝列表的用户群发图文消息
$result = \LaneWeChat\Core\AdvancedBroadcast::sentNewsByOpenId($fansList['data']['openid'], $mediaId);
四、推送模板消息
场景描述:公众号推送的模板消息,比如领取红包、滴滴打车红包领取、大众点评微信支付等
场景举例我们在实体店的一家服装店买了新衣服而我们又是会员他们检测到会员的手机号消费了有新积分增加而这个手机号又关注了这家服装店的微信公众号根据手机号可以在服装店自己的数据库中查到微信粉丝openId这个时候就会给这个用户发送一个模板消息。
代码:
<?php
include 'lanewechat.php';
$data = array(
'first'=>array('value'=>'您好,您已成功消费。', 'color'=>'#0A0A0A')
'keynote1'=>array('value'=>'巧克力', 'color'=>'#CCCCCC')
'keynote2'=>array('value'=>'39.8元', 'color'=>'#CCCCCC')
'keynote3'=>array('value'=>'2014年9月16日', 'color'=>'#CCCCCC')
'keynote3'=>array('value'=>'欢迎再次购买。', 'color'=>'#173177')
);
//$touser 接收方的OpenId。
//$templateId 模板Id。在公众平台线上模板库中选用模板获得ID
//$url URL 点击查看的时候跳转到URL。
//$topcolor 顶部颜色,可以为空。默认是红色
\LaneWeChat\Core\TemplateMessage::sendTemplateMessage($data, $touser, $templateId, $url, $topcolor='#FF0000');
五、添加自定义菜单
场景描述:微信公众号底部的导航栏按钮
场景举例:自定义菜单可以更加快捷方便的为用户服务。而不需要用户每次都要打字发送消息来获取所需要的信息。轻轻一点按钮,马上拥有!
注:微信官方仅供认证号使用自定义菜单。
代码:
<?php
include 'lanewechat.php';
$menuList = array(
array('id'=>'1', 'pid'=>'0', 'name'=>'菜单1', 'type'=>'', 'code'=>''),
array('id'=>'2', 'pid'=>'0', 'name'=>'菜单2', 'type'=>'', 'code'=>''),
array('id'=>'3', 'pid'=>'0', 'name'=>'地理位置', 'type'=>'location_select', 'code'=>'key_7'),
array('id'=>'4', 'pid'=>'1', 'name'=>'点击推事件', 'type'=>'click', 'code'=>'key_1'),
array('id'=>'5', 'pid'=>'1', 'name'=>'跳转URL', 'type'=>'view', 'code'=>'http://www.lanecn.com/'),
array('id'=>'6', 'pid'=>'2', 'name'=>'扫码推事件', 'type'=>'scancode_push', 'code'=>'key_2'),
array('id'=>'7', 'pid'=>'2', 'name'=>'扫码等收消息', 'type'=>'scancode_waitmsg', 'code'=>'key_3'),
array('id'=>'8', 'pid'=>'2', 'name'=>'系统拍照发图', 'type'=>'pic_sysphoto', 'code'=>'key_4'),
array('id'=>'9', 'pid'=>'2', 'name'=>'弹拍照或相册', 'type'=>'pic_photo_or_album', 'code'=>'key_5'),
array('id'=>'10', 'pid'=>'2', 'name'=>'弹微信相册', 'type'=>'pic_weixin', 'code'=>'key_6'),
);
$result = \LaneWeChat\Core\Menu::setMenu($menuList);
六、页面展示二维码
场景描述:在网页中展示微信公众号的二维码
场景举例:太多了吧,就不说了…
代码:
<?php
include 'lanewechat.php';
header('Content-type: image/jpg');
$ticket = \LaneWeChat\Core\Popularize::createTicket(1, 1800, 1);
$ticket = $ticket['ticket'];
$qrcode = \LaneWeChat\Core\Popularize::getQrcode($ticket);
echo $qrcode;

@ -0,0 +1,53 @@
<?php
namespace LaneWeChat;
/**
* 自动载入函数类
*
* 该类用于自动加载指定命名空间下的类文件,以便在需要时自动实例化类。
*
* Created by Lane.
* User: lane
* Date: 14-10-15
* Time: 下午6:13
* E-mail: lixuan868686@163.com
* WebSite: http://www.lanecn.com
*/
class Autoloader {
const NAMESPACE_PREFIX = 'LaneWeChat\\'; // 定义命名空间前缀,用于识别类名
/**
* 向PHP注册自动载入函数
*
* 通过此方法注册自动载入函数,当尝试实例化一个未定义的类时,将自动调用 autoload 方法。
*/
public static function register() {
// 注册自动载入函数,当尝试实例化一个未定义的类时,将调用此函数
spl_autoload_register(array(new self, 'autoload'));
}
/**
* 根据类名载入所在文件
*
* @param string $className 类名
*/
public static function autoload($className) {
// 获取命名空间前缀的长度
$namespacePrefixStrlen = strlen(self::NAMESPACE_PREFIX);
// 检查类名是否以命名空间前缀开头
if (strncmp(self::NAMESPACE_PREFIX, $className, $namespacePrefixStrlen) === 0) {
// 将类名转换为小写
$className = strtolower($className);
// 将命名空间分隔符转换为目录分隔符
$filePath = str_replace('\\', DIRECTORY_SEPARATOR, substr($className, $namespacePrefixStrlen));
// 构建文件路径
$filePath = realpath(__DIR__ . (empty($filePath) ? '' : DIRECTORY_SEPARATOR) . $filePath . '.lib.php');
// 如果文件存在,则加载文件
if (file_exists($filePath)) {
require_once $filePath;
} else {
// 如果文件不存在,输出文件路径(用于调试)
echo $filePath;
}
}
}
}

@ -0,0 +1,52 @@
<?php
namespace LaneWeChat;
/**
* 系统主配置文件
*/
// 版本号
define('LANEWECHAT_VERSION', '1.4'); // 定义系统版本号为1.4
define('LANEWECHAT_VERSION_DATE', '2014-11-05'); // 定义系统版本日期为2014年11月5日
/*
* 服务器配置,详情请参考微信官方文档 http://mp.weixin.qq.com/wiki/index.php?title=接入指南
*/
define("WECHAT_URL", 'http://www.lanecn.com'); // 定义微信服务器的URL
define('WECHAT_TOKEN', 'weixin'); // 定义微信服务器的Token
define('ENCODING_AES_KEY', "MqAuKoex6FyT5No0OcpRyCicThGs0P1vz4mJ2gwvvkF"); // 定义微信服务器的EncodingAESKey
/*
* 开发者配置
*/
define("WECHAT_APPID", 'wx5d57f64bb4804d90'); // 定义微信公众号的AppID
define("WECHAT_APPSECRET", '4b1fa6d9442351ec9268eff05e38f521'); // 定义微信公众号的AppSecret
////-----引入系统所需类库-------------------
////引入错误消息类
//include_once 'core/msg.lib.php';
////引入错误码类
//include_once 'core/msgconstant.lib.php';
////引入CURL类
//include_once 'core/curl.lib.php';
////-----------引入微信所需的基本类库----------------
////引入微信处理中心类
//include_once 'core/wechat.lib.php';
////引入微信请求处理类
//include_once 'core/wechatrequest.lib.php';
////引入微信被动响应处理类
//include_once 'core/responsepassive.lib.php';
////引入微信access_token类
//include 'core/accesstoken.lib.php';
////-----如果是认证服务号,需要引入以下类--------------
////引入微信权限管理类
//include_once 'core/wechatoauth.lib.php';
////引入微信用户/用户组管理类
//include_once 'core/usermanage.lib.php';
////引入微信主动相应处理类
//include_once 'core/responseinitiative.lib.php';
////引入多媒体管理类
//include_once 'core/media.lib.php';
////引入自定义菜单类
//include_once 'core/menu.lib.php';
?>

@ -0,0 +1,2 @@
name: 9173weixin
version: 2

@ -0,0 +1,87 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于微信核心功能模块
/**
* 微信Access_Token的获取与过期检查
*
* 该类负责管理微信Access_Token的获取和有效期检查确保在使用微信API时始终使用有效的Access_Token。
*
* 创建者Lane
* 用户名lane
* 日期13-12-29
* 时间下午5:54
* 邮箱lixuan868686@163.com
* 网站http://www.lanecn.com
*/
class AccessToken {
/**
* 获取微信Access_Token
*
* 该方法首先检查本地缓存中是否存在有效的Access_Token若不存在或已过期则调用私有方法_getAccessToken从微信服务器获取新的Access_Token。
*
* @return string 返回有效的Access_Token字符串
*/
public static function getAccessToken() {
// 检查本地缓存中是否存在有效的Access_Token
$accessToken = self::_checkAccessToken();
if ($accessToken === false) {
// 若本地缓存中不存在有效的Access_Token则从微信服务器获取新的Access_Token
$accessToken = self::_getAccessToken();
}
// 返回有效的Access_Token字符串
return $accessToken['access_token'];
}
/**
* 从微信服务器获取Access_Token
*
* 该方法构造请求微信服务器获取Access_Token的URL并通过HTTP GET请求从微信服务器获取Access_Token。
*
* @return array|bool 返回获取到的Access_Token数组或在获取失败时返回错误信息
*/
private static function _getAccessToken() {
// 构造请求微信服务器获取Access_Token的URL
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.WECHAT_APPID.'&secret='.WECHAT_APPSECRET;
// 发起HTTP GET请求获取Access_Token
$accessToken = Curl::callWebServer($url, '', 'GET');
// 检查返回的数据中是否包含Access_Token字段
if (!isset($accessToken['access_token'])) {
// 若获取Access_Token失败则返回错误信息
return Msg::returnErrMsg(MsgConstant::ERROR_GET_ACCESS_TOKEN, '获取Access_Token失败');
}
// 记录获取Access_Token的时间
$accessToken['time'] = time();
// 将Access_Token数据转换为JSON格式的字符串
$accessTokenJson = json_encode($accessToken);
// 将Access_Token数据存入文件
$f = fopen('access_token', 'w+');
fwrite($f, $accessTokenJson);
fclose($f);
// 返回获取到的Access_Token数据
return $accessToken;
}
/**
* 检测Access_Token是否过期
*
* 该方法检查本地存储的Access_Token是否已过期预留10秒的网络延迟时间以确保在使用Access_Token时不会因过期而导致请求失败。
*
* @return bool|array 返回Access_Token是否有效若有效则返回Access_Token数据否则返回false
*/
private static function _checkAccessToken() {
// 获取本地存储的Access_Token数据
$data = file_get_contents('access_token');
// 将获取到的数据转换为关联数组
$accessToken = json_decode($data, true);
if (!empty($accessToken)) {
// 检查Access_Token是否过期预留10秒的网络延迟时间
if (time() - $accessToken['time'] < $accessToken['expires_in'] - 10) {
// 若Access_Token未过期则返回Access_Token数据
return $accessToken;
}
}
// 若Access_Token不存在或已过期则返回false
return false;
}
}

@ -0,0 +1,153 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于 LaneWeChat 模块的核心部分
/**
* 高级群发功能类
*
* 该类提供了多种高级群发功能包括上传图文消息、根据分组ID群发图文、文本、语音、图片和视频消息等。
*/
class AdvancedBroadcast {
/**
* 上传图文消息到微信服务器
*
* @param array $articles 图文消息数组,包含多篇文章的相关信息
* @return string|bool 返回上传成功后的media_id或在失败时返回false
*/
public static function uploadNews($articles) {
// 构建请求URL包含access_token使用AccessToken类的getAccessToken方法获取
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST'; // 请求方式为POST
// 遍历文章数组对每个文章的字段进行URL编码以确保特殊字符不会影响请求
foreach ($articles as &$article) {
$article['author'] = urlencode($article['author']);
$article['title'] = urlencode($article['title']);
$article['content'] = urlencode($article['content']);
$article['digest'] = urlencode($article['digest']);
}
$template = array(); // 创建模板数组
$template['articles'] = $articles; // 将编码后的文章数组赋值给模板的articles字段
$template = json_encode($template); // 将模板数组转换为JSON字符串
// 发起网络请求调用Curl类的方法传入URL、数据和请求方式
$result = Curl::callWebServer($queryUrl, $template, $queryAction);
// 返回media_id如果结果中没有media_id则返回false
return empty($result['media_id']) ? false : $result['media_id'];
}
/**
* 根据分组ID群发图文消息
*
* @param int $groupId 分组ID
* @param string $mediaId 图文消息的media_id
* @param bool $isToAll 是否群发所有用户默认为false
* @return mixed 返回群发操作的结果
*/
public static function sentNewsByGroup($groupId, $mediaId, $isToAll = false) {
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST'; // 请求方式为POST
$template = array(); // 创建模板数组
$template['filter']['group_id'] = $groupId; // 设置分组ID
$template['filter']['is_to_all'] = $isToAll; // 设置是否群发所有用户
$template['mpnews']['media_id'] = $mediaId; // 设置图文消息的media_id
$template['msgtype'] = 'mpnews'; // 设置消息类型为图文消息
$template = json_encode($template); // 将模板数组转换为JSON字符串
// 发起网络请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 根据分组ID群发文本消息
*
* @param int $groupId 分组ID
* @param string $content 文本内容
* @param bool $isToAll 是否群发所有用户默认为false
* @return mixed 返回群发操作的结果
*/
public static function sentTextByGroup($groupId, $content, $isToAll = false) {
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST'; // 请求方式为POST
$template = array(); // 创建模板数组
$template['filter']['group_id'] = $groupId; // 设置分组ID
$template['filter']['is_to_all'] = $isToAll; // 设置是否群发所有用户
$template['text']['content'] = $content; // 设置文本内容
$template['msgtype'] = 'text'; // 设置消息类型为文本消息
$template = json_encode($template); // 将模板数组转换为JSON字符串
// 发起网络请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 根据分组ID群发语音消息
*
* @param int $groupId 分组ID
* @param string $mediaId 语音消息的media_id
* @param bool $isToAll 是否群发所有用户默认为false
* @return mixed 返回群发操作的结果
*/
public static function sentVoiceByGroup($groupId, $mediaId, $isToAll = false) {
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST'; // 请求方式为POST
$template = array(); // 创建模板数组
$template['filter']['group_id'] = $groupId; // 设置分组ID
$template['filter']['is_to_all'] = $isToAll; // 设置是否群发所有用户
$template['voice']['media_id'] = $mediaId; // 设置语音消息的media_id
$template['msgtype'] = 'voice'; // 设置消息类型为语音消息
$template = json_encode($template); // 将模板数组转换为JSON字符串
// 发起网络请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 根据分组ID群发图片消息
*
* @param int $groupId 分组ID
* @param string $mediaId 图片消息的media_id
* @param bool $isToAll 是否群发所有用户默认为false
* @return mixed 返回群发操作的结果
*/
public static function sentImageByGroup($groupId, $mediaId, $isToAll = false) {
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST'; // 请求方式为POST
$template = array(); // 创建模板数组
$template['filter']['group_id'] = $groupId; // 设置分组ID
$template['filter']['is_to_all'] = $isToAll; // 设置是否群发所有用户
$template['image']['media_id'] = $mediaId; // 设置图片消息的media_id
$template['msgtype'] = 'image'; // 设置消息类型为图片消息
$template = json_encode($template); // 将模板数组转换为JSON字符串
// 发起网络请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 根据分组ID群发视频消息
*
* @param string $mediaId 视频消息的media_id
* @param string $title 视频标题
* @param string $description 视频描述
* @param int $groupId 分组ID
* @param bool $isToAll 是否群发所有用户默认为false
* @return bool 返回群发操作是否成功
*/
public static function sentVideoByGroup($mediaId, $title, $description, $groupId, $isToAll = false) {
// 构建请求URL包含access_token
$queryUrl = 'https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST'; // 请求方式为POST
$template = array(); // 创建模板数组
$template['media_id'] = $mediaId; // 设置视频消息的media_id
$template['title'] = $title; // 设置视频标题
$template['description'] = $description; // 设置视频描述
$template = json_encode($template); // 将模板数组转换为JSON字符串
// 发起网络请求
$result = Curl::callWebServer($queryUrl, $template, $queryAction);
// 检查返回结果是否符合预期
if (empty($result['type']) || $result['type'] != 'video' || empty($result['media_id'])) {
// 如果结果中没有type字段或者type不是video或者没有media_id则返回false
return false;
}
// 如果视频上传成功,可以在这里添加发送视频消息的代码
}
}

@ -0,0 +1,4 @@
注意事项:
1.WXBizMsgCrypt.php文件提供了WXBizMsgCrypt类的实现是用户接入企业微信的接口类。Sample.php提供了示例以供开发者参考。errorCode.php, pkcs7Encoder.php, sha1.php, xmlparse.php文件是实现这个类的辅助类开发者无须关心其具体实现。
2.WXBizMsgCrypt类封装了 DecryptMsg, EncryptMsg两个接口分别用于开发者解密以及开发者回复消息的加密。使用方法可以参考Sample.php文件。
3.加解密协议请参考微信公众平台官方文档。

@ -0,0 +1,51 @@
<?php
namespace LaneWeChat\Core\Aes;
include_once "wxBizMsgCrypt.php";
// 第三方发送消息给公众平台
$encodingAesKey = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG";
$token = "pamtest";
$timeStamp = "1409304348";
$nonce = "xxxxxx";
$appId = "wxb11529c136998cb6";
$text = "<xml><ToUserName><![CDATA[oia2Tj我是中文jewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>";
// 初始化WXBizMsgCrypt对象
$pc = new WXBizMsgCrypt($token, $encodingAesKey, $appId);
$encryptMsg = '';
// 加密消息
$errCode = $pc->encryptMsg($text, $timeStamp, $nonce, $encryptMsg);
if ($errCode == 0) {
print("加密后: " . $encryptMsg . "\n");
} else {
print($errCode . "\n");
}
// 解析加密后的XML消息
$xml_tree = new DOMDocument();
$xml_tree->loadXML($encryptMsg);
$array_e = $xml_tree->getElementsByTagName('Encrypt');
$array_s = $xml_tree->getElementsByTagName('MsgSignature');
$encrypt = $array_e->item(0)->nodeValue;
$msg_sign = $array_s->item(0)->nodeValue;
// 构造解密的XML格式
$format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";
$from_xml = sprintf($format, $encrypt);
// 解密消息
$msg = '';
$errCode = $pc->decryptMsg($msg_sign, $timeStamp, $nonce, $from_xml, $msg);
if ($errCode == 0) {
print("解密后: " . $msg . "\n");
} else {
print($errCode . "\n");
}
命名空间声明namespace LaneWeChat\Core\Aes; 定义了类的命名空间表明这个脚本属于LaneWeChat模块的Aes部分。
引入类库include_once "wxBizMsgCrypt.php"; 引入用于消息加密和解密的类库。
初始化参数:定义了用于加密和解密的参数,包括 encodingAesKey、token、timeStamp、nonce 和 appId。
初始化WXBizMsgCrypt对象创建 WXBizMsgCrypt 对象,用于消息的加密和解密。
加密消息:调用 encryptMsg 方法对消息进行加密,并输出加密后的结果。
解析加密后的XML消息使用 DOMDocument 解析加密后的XML消息提取 Encrypt 和 MsgSignature 的值。
构造解密的XML格式构造用于解密的XML格式。
解密消息:调用 decryptMsg 方法对消息进行解密,并输出解密后的结果。

@ -0,0 +1,52 @@
<?php
namespace LaneWeChat\Core\Aes; // 定义命名空间,用于组织代码
class ErrorCode // 定义ErrorCode类
{
// 成员变量,表示操作成功
public static $OK = 0;
// 成员变量,表示验证签名错误
public static $ValidateSignatureError = -40001;
// 成员变量表示解析XML错误
public static $ParseXmlError = -40002;
// 成员变量,表示计算签名错误
public static $ComputeSignatureError = -40003;
// 成员变量表示AES密钥不合法
public static $IllegalAesKey = -40004;
// 成员变量表示验证AppID错误
public static $ValidateAppidError = -40005;
// 成员变量表示AES加密错误
public static $EncryptAESError = -40006;
// 成员变量表示AES解密错误
public static $DecryptAESError = -40007;
// 成员变量,表示缓冲区不合法
public static $IllegalBuffer = -40008;
// 成员变量表示Base64编码错误
public static $EncodeBase64Error = -40009;
// 成员变量表示Base64解码错误
public static $DecodeBase64Error = -40010;
// 成员变量表示生成返回XML错误
public static $GenReturnXmlError = -40011;
}
?>
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器

@ -0,0 +1,50 @@
<?php
namespace LaneWeChat\Core\Aes; // 定义命名空间,用于组织代码
class PKCS7Encoder // 定义PKCS7Encoder类
{
public static $block_size = 32; // 定义PKCS7编码的块大小固定为32字节
// 编码方法用于对数据进行PKCS7填充
function encode($text)
{
$block_size = PKCS7Encoder::$block_size; // 获取块大小
$text_length = strlen($text); // 获取原始数据长度
// 计算需要填充的字节数,使数据长度成为块大小的整数倍
$amount_to_pad = PKCS7Encoder::$block_size - ($text_length % PKCS7Encoder::$block_size);
// 如果数据长度已经是块大小的整数倍,则需要填充一个块大小的字节
if ($amount_to_pad == 0) {
$amount_to_pad = PKCS7Encoder::block_size;
}
$pad_chr = chr($amount_to_pad); // 将需要填充的字节数转换为字符
$tmp = ""; // 初始化临时字符串,用于构建填充字符
for ($index = 0; $index < $amount_to_pad; $index++) {
$tmp .= $pad_chr; // 重复填充字符
}
// 返回填充后的数据
return $text . $tmp;
}
// 解码方法用于移除PKCS7填充
function decode($text)
{
$pad = ord(substr($text, -1)); // 获取最后一个字符的ASCII值即填充的字节数
// 如果填充的字节数不在1到32之间则认为没有填充
if ($pad < 1 || $pad > 32) {
$pad = 0;
}
// 返回移除填充后的数据
return substr($text, 0, (strlen($text) - $pad));
}
}
?>
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器

@ -0,0 +1,87 @@
<?php
namespace LaneWeChat\Core\Aes; // 定义命名空间,用于组织代码
class Prpcrypt // 定义Prpcrypt类
{
public $key; // 类成员变量,用于存储加密密钥
// 类构造函数,用于初始化密钥
function Prpcrypt($k)
{
$this->key = base64_decode($k . "="); // 对传入的密钥进行base64解码并追加'='字符
}
// 加密函数,用于加密文本消息
public function encrypt($text, $appid)
{
try {
$random = $this->getRandomStr(); // 生成16位随机字符串
$text = $random . pack("N", strlen($text)) . $text . $appid; // 将随机字符串、文本长度、文本内容和AppID拼接
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); // 获取加密块大小
$module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); // 打开加密模块
$iv = substr($this->key, 0, 16); // 从密钥中截取前16位作为初始化向量
$pkc_encoder = new PKCS7Encoder; // 实例化PKCS7Encoder类用于数据填充
$text = $pkc_encoder->encode($text); // 对文本进行PKCS7编码
mcrypt_generic_init($module, $this->key, $iv); // 初始化加密模块
$encrypted = mcrypt_generic($module, $text); // 进行加密操作
mcrypt_generic_deinit($module); // 解密模块
mcrypt_module_close($module); // 关闭加密模块
return array(ErrorCode::$OK, base64_encode($encrypted)); // 返回加密结果和状态码
} catch (\Exception $e) {
return array(ErrorCode::$EncryptAESError, null); // 捕获异常,返回加密错误状态码
}
}
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器
// 解密函数,用于解密加密的消息
public function decrypt($encrypted, $appid)
{
try {
$ciphertext_dec = base64_decode($encrypted); // 对加密文本进行base64解码
$module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); // 打开解密模块
$iv = substr($this->key, 0, 16); // 从密钥中截取前16位作为初始化向量
mcrypt_generic_init($module, $this->key, $iv); // 初始化解密模块
$decrypted = mdecrypt_generic($module, $ciphertext_dec); // 进行解密操作
mcrypt_generic_deinit($module); // 解密模块
mcrypt_module_close($module); // 关闭解密模块
} catch (\Exception $e) {
return array(ErrorCode::$DecryptAESError, null); // 捕获异常,返回解密错误状态码
}
try {
$pkc_encoder = new PKCS7Encoder; // 实例化PKCS7Encoder类
$result = $pkc_encoder->decode($decrypted); // 对解密后的数据进行PKCS7解码
if (strlen($result) < 16) //
return "";
$content = substr($result, 16, strlen($result)); // 截取除去随机字符串和长度信息后的内容
$len_list = unpack("N", substr($content, 0, 4)); // 解析文本长度信息
$xml_len = $len_list[1]; // 获取文本长度
$xml_content = substr($content, 4, $xml_len); // 截取XML内容
$from_appid = substr($content, $xml_len + 4); // 获取AppID
} catch (\Exception $e) {
return array(ErrorCode::$IllegalBuffer, null); // 捕获异常,返回非法缓冲区状态码
}
if ($from_appid != $appid) // 检查AppID是否匹配
return array(ErrorCode::$ValidateAppidError, null);
return array(0, $xml_content); // 返回解密后的XML内容和状态码
}
// 生成随机字符串函数
function getRandomStr()
{
$str = "";
$str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; // 定义随机字符串的字符集
$max = strlen($str_pol) - 1;
for ($i = 0; $i < 16; $i++) {
$str .= $str_pol[mt_rand(0, $max)]; // 生成16位随机字符串
}
return $str;
}
}

@ -0,0 +1,32 @@
<?php
namespace LaneWeChat\Core\Aes; // 定义命名空间,用于组织代码
class SHA1 // 定义SHA1类
{
// getSHA1方法用于生成SHA1哈希值
public function getSHA1($token, $timestamp, $nonce, $encrypt_msg)
{
try {
// 创建一个数组包含加密消息、Token、时间戳和随机数
$array = array($encrypt_msg, $token, $timestamp, $nonce);
// 对数组元素进行字符串排序
sort($array, SORT_STRING);
// 将数组元素连接成一个字符串
$str = implode($array);
// 生成该字符串的SHA1哈希值并返回
return array(ErrorCode::$OK, sha1($str));
} catch (\Exception $e) {
// 如果发生异常返回错误码和null值
return array(ErrorCode::$ComputeSignatureError, null);
}
}
}
?>
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器

@ -0,0 +1,50 @@
<?php
namespace LaneWeChat\Core\Aes; // 定义命名空间为 LaneWeChat\Core\Aes用于组织与微信消息加密相关的代码
/**
* 微信消息加密类
*
* 该类用于对微信公众号的消息进行加密和解密操作,确保消息的安全性。
*/
class WXBizMsgCrypt {
private $token; // 微信Token用于验证消息来源
private $encodingAesKey; // 微信EncodingAESKey用于消息加密
private $appId; // 微信AppId用于标识公众号
/**
* 类构造函数
*
* 用于初始化Token、EncodingAESKey和AppId。
*
* @param string $token 微信Token
* @param string $encodingAesKey 微信EncodingAESKey
* @param string $appId 微信AppId
*/
public function __construct($token, $encodingAesKey, $appId) {
$this->token = $token; // 初始化微信Token
$this->encodingAesKey = $encodingAesKey; // 初始化微信EncodingAESKey
$this->appId = $appId; // 初始化微信AppId
}
/**
* 加密消息方法
*
* 对回复消息进行加密,确保消息在传输过程中的安全性。
*
* @param string $replyMsg 要加密的回复消息
* @param int $timeStamp 时间戳
* @param string $nonce 随机数
* @param string $encryptMsg 加密后的消息
* @return int 返回加密结果的状态码
*/
public function encryptMsg($replyMsg, $timeStamp, $nonce, &$encryptMsg) {
$pc = new Prpcrypt($this->encodingAesKey); // 实例化Prpcrypt类用于消息加密
$array = $pc->encrypt($replyMsg, $this->appId); // 调用encrypt方法进行消息加密
$ret = $array[0]; // 获取加密结果的状态码
if ($ret != 0) {
return $ret; // 如果加密失败,返回错误码
}
// 省略了后续代码,但通常这里会将加密后的消息、时间戳、随机数等信息
// 格式化为XML格式并赋值给$encryptMsg变量
}
}

@ -0,0 +1,54 @@
<?php
namespace LaneWeChat\Core\Aes; // 定义命名空间,用于组织代码
class XMLParse // 定义XMLParse类
{
// 提取方法用于从XML文本中提取加密信息和接收方账号
public function extract($xmltext)
{
try {
$xml = new \DOMDocument(); // 创建DOMDocument对象
$xml->loadXML($xmltext); // 加载XML文本
// 使用DOMDocument对象的getElementsByTagName方法获取Encrypt和ToUserName标签
$array_e = $xml->getElementsByTagName('Encrypt');
$array_a = $xml->getElementsByTagName('ToUserName');
// 获取Encrypt标签的文本内容和ToUserName标签的文本内容
$encrypt = $array_e->item(0)->nodeValue;
$tousername = $array_a->item(0)->nodeValue;
// 返回提取结果包括状态码0表示成功加密信息和接收方账号
return array(0, $encrypt, $tousername);
} catch (\Exception $e) {
// 如果发生异常返回错误码和null值
return array(ErrorCode::$ParseXmlError, null, null);
}
}
// 生成方法用于生成XML格式的响应消息
public function generate($encrypt, $signature, $timestamp, $nonce)
{
// 定义XML格式的字符串模板使用CDATA区包含加密信息和其他参数
$format = "<xml>
<Encrypt><![CDATA[%s]]></Encrypt>
<MsgSignature><![CDATA[%s]]></MsgSignature>
<TimeStamp>%s</TimeStamp>
<Nonce><![CDATA[%s]]></Nonce>
</xml>";
// 使用sprintf函数格式化XML字符串模板插入加密信息和其他参数
return sprintf($format, $encrypt, $signature, $timestamp, $nonce);
}
}
?>
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器

@ -0,0 +1,40 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于 LaneWeChat 模块的核心部分
/**
* Auth类用于与微信公众平台的相关操作进行交互。
*
* 该类包含了获取微信服务器IP列表的方法常用于验证服务器是否能够访问微信API。
*
* 创建者lixuan-it@360.cn
* 用户名lane
* 日期15/4/29
* 时间上午10:51
* 邮箱lixuan868686@163.com
* 网站http://www.lanecn.com
*/
class Auth {
/**
* 获取微信服务器IP列表
*
* 该方法用于请求微信公众平台API获取微信服务器的IP地址列表。
* 此IP列表通常用于设置服务器白名单确保微信服务器能正常与当前服务器进行通信。
*
* @return mixed 返回微信服务器IP列表的响应数据
*/
public static function getWeChatIPList() {
// 获取ACCESS_TOKEN调用AccessToken类中的getAccessToken方法来获取微信的ACCESS_TOKEN。
// ACCESS_TOKEN是调用微信API接口的必需参数。
$accessToken = AccessToken::getAccessToken();
// 构造请求微信服务器IP列表的URL拼接上获取到的ACCESS_TOKEN。
// 通过URL请求的方式调用微信API获取服务器IP地址列表。
$url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=' . $accessToken;
// 使用Curl类中的callWebServer方法发起一个GET请求到构造好的URL。
// callWebServer方法用于向微信API发起请求并获取响应数据。
// 返回的结果是一个包含微信服务器IP地址的列表通常是JSON格式的。
return Curl::callWebServer($url, '', 'GET');
}
}

@ -0,0 +1,36 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于 LaneWeChat 模块的核心部分
/**
* 自动回复类
*
* 该类用于处理微信公众号的自动回复功能,提供方法来获取当前的自动回复规则。
*/
class AutoReply {
/**
* 获取自动回复规则
*
* 该方法用于从微信公众号的API获取当前的自动回复规则。
*
* @param int $industryId1 主行业ID
* @param int $industryId2 副行业ID
* @return string 返回获取到的自动回复规则信息
*/
public static function getRole($industryId1, $industryId2) {
// 构建请求URL使用 AccessToken 类的 getAccessToken 方法获取当前有效的 access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info?access_token=' . AccessToken::getAccessToken();
// 定义请求方法为 POST
$queryAction = 'POST';
// 初始化模板数组,用于存储请求数据
$template = array();
// 设置主行业ID
$template['industry_id1'] = $industryId1;
// 设置副行业ID
$template['industry_id2'] = $industryId2;
// 将模板数组转换为 JSON 格式,因为微信 API 通常要求以 JSON 格式接收请求数据
$template = json_encode($template);
// 调用 Curl 类的 callWebServer 方法发送 POST 请求到微信 API并返回结果
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
}

@ -0,0 +1,114 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于 LaneWeChat 模块的核心部分
/**
* CURL工具类用于简化HTTP请求操作。
*
* 该类提供了一系列方法来执行HTTP请求包括GET、POST、PUT、DELETE和HEAD请求。
*
* @author Lane
* @email lixuan868686@163.com
* @website http://www.lanecn.com
*/
class Curl {
// 私有静态变量用于存储CURL会话句柄、头部、主体等信息
private static $_ch;
private static $_header;
private static $_body;
// 存储Cookie、选项、URL和Referer的数组
private static $_cookie = array();
private static $_options = array();
private static $_url = array();
private static $_referer = array();
/**
* 调用外部URL支持GET和POST请求。
*
* @param string $queryUrl 请求的URL
* @param array|string $param 参数
* @param string $method 请求方法,默认为'get'
* @param bool $is_json 是否将返回结果解析为JSON默认为true
* @param bool $is_urlcode 是否对参数进行URL编码默认为true
* @return bool|mixed 返回请求结果或false
*/
public static function callWebServer($queryUrl, $param = '', $method = 'get', $is_json = true, $is_urlcode = true) {
// 检查URL是否为空
if (empty($queryUrl)) {
return false;
}
// 转换方法为小写
$method = strtolower($method);
$ret = '';
// 确保参数是数组
$param = empty($param) ? array() : $param;
// 初始化CURL会话
self::_init();
// 根据请求方法调用相应的私有方法
if ($method == 'get') {
$ret = self::_httpGet($queryUrl, $param);
} elseif ($method == 'post') {
$ret = self::_httpPost($queryUrl, $param, $is_urlcode);
}
// 如果有返回结果根据参数决定是否解析为JSON
if (!empty($ret)) {
if ($is_json) {
return json_decode($ret, true);
} else {
return $ret;
}
}
return false;
}
/**
* 初始化CURL会话
*/
private static function _init() {
self::$_ch = curl_init();
// 设置CURL选项
curl_setopt(self::$_ch, CURLOPT_HEADER, true);
curl_setopt(self::$_ch, CURLOPT_RETURNTRANSFER, true);
}
/**
* 设置CURL选项
*
* @param array $optArray 选项数组
*/
public static function setOption($optArray = array()) {
foreach ($optArray as $opt) {
curl_setopt(self::$_ch, $opt['key'], $opt['value']);
}
}
/**
* 关闭CURL会话
*
* @return bool
*/
private static function _close() {
if (is_resource(self::$_ch)) {
curl_close(self::$_ch);
}
return true;
}
/**
* 发送GET请求
*
* @param string $url 请求URL
* @param array $query 查询参数
* @return mixed 请求结果
*/
private static function _httpGet($url, $query = array()) {
// 构建查询字符串
if (!empty($query)) {
$url .= (strpos($url, '?') === false) ? '?' : '&';
$url .= is_array($query) ? http_build_query($query) : $query;
}
// 设置CURL选项
curl_setopt(self::$_ch, CURLOPT_URL, $url);
curl_setopt(self::$_ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(self::$_ch, CURLOPT_HEADER, 0);
// 禁用

@ -0,0 +1,207 @@
<?php
namespace LaneWeChat\Core;
/**
* 多客服功能类,用于微信公众号的多客服系统管理。
* 该类提供接口以添加、编辑、删除客服账号,获取客服列表,设置客服头像,以及获取客服聊天记录。
* Class CustomService
* User: lane
* Date: 14-10-31
* Time: 上午10:30
* E-mail: lixuan868686@163.com
* WebSite: http://www.lanecn.com
*/
class CustomService
{
/**
* 添加客服账号。
* 此方法用于在微信公众号后台添加一个新的客服账号。
* 注意:必须先在公众平台官网为公众号设置微信号后才能使用该能力。
*
* @param string $kfAccount 完整客服账号,格式为:账号前缀@公众号微信号。
* @param string $nickname 客服昵称。
* @param string $password 客服密码。
* @return array 操作结果成功返回操作结果数组失败返回false。
*/
public function addAccount($kfAccount, $nickname, $password)
{
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/customservice/kfaccount/add?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST';
// 创建模板数组
$template = array();
$template['kf_account'] = $kfAccount;
$template['nickname'] = $nickname;
$template['password'] = $password;
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 使用Curl类发送POST请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 修改客服账号信息。
* 此方法用于修改已存在的客服账号信息。
*
* @param string $kfAccount 完整客服账号,格式为:账号前缀@公众号微信号。
* @param string $nickname 客服昵称。
* @param string $password 客服密码。
* @return array 操作结果成功返回操作结果数组失败返回false。
*/
public function editAccount($kfAccount, $nickname, $password)
{
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/customservice/kfaccount/update?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST';
// 创建模板数组
$template = array();
$template['kf_account'] = $kfAccount;
$template['nickname'] = $nickname;
$template['password'] = $password;
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 使用Curl类发送POST请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 删除客服账号。
* 此方法用于从微信公众号后台删除一个客服账号。
*
* @param string $kfAccount 完整客服账号,格式为:账号前缀@公众号微信号。
* @return array 操作结果成功返回操作结果数组失败返回false。
*/
public function delAccount($kfAccount)
{
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/customservice/kfaccount/del?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST';
// 创建模板数组
$template = array();
$template['kf_account'] = $kfAccount;
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 使用Curl类发送POST请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 获取所有客服账号列表。
* 此方法用于获取公众号下所有客服账号的信息。
*
* @return array 客服账号列表每个客服账号包含kf_account, kf_nick, kf_id, kf_headimgurl等信息。
*/
public function getAccountList()
{
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=' . AccessToken::getAccessToken();
$queryAction = 'GET';
// 使用Curl类发送GET请求
return Curl::callWebServer($queryUrl, '', $queryAction);
}
/**
* 设置客服账号的头像。
* 此方法用于上传并设置客服账号的头像。
* 头像图片文件必须是jpg格式推荐使用640*640大小的图片以达到最佳效果。
*
* @param string $kfAccount 完整客服账号,格式为:账号前缀@公众号微信号。
* @param string $imagePath 待上传的头像文件路径。
* @return array 操作结果成功返回操作结果数组失败返回false。
*/
public function setAccountImage($kfAccount, $imagePath)
{
// 检查头像文件是否存在
if (!file_exists($imagePath)) {
return false;
}
// 构建请求URL包含access_token和kf_account
$queryUrl = 'http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=' . AccessToken::getAccessToken() . '&kf_account=' . $kfAccount;
// 创建数据数组
$data = array();
$data['media'] = '@' . $imagePath;
// 使用Curl类发送POST请求设置multipart为1表示发送文件
return Curl::callWebServer($queryUrl, $data, 'POST', 1, 0);
}
/**
* 获取客服聊天记录。
* 此方法用于获取多客服的会话记录,包括客服和用户会话的所有消息记录和会话的创建、关闭等操作记录。
* 利用此接口可以开发如“消息记录”、“工作监控”、“客服绩效考核”等功能。
*
* @param int $startTime 查询开始时间UNIX时间戳。
* @param int $endTime 查询结束时间UNIX时间戳每次查询不能跨日查询。
* @param int $pageIndex 查询第几页从1开始。
* @param int $pageSize 每页大小每页最多拉取1000条。
* @param string $openId 可以为空,普通用户的标识,对当前公众号唯一。
* @return array 聊天记录列表包含worker, openid, opercode, time, text等信息。
*/
public function getRecord($startTime, $endTime, $pageIndex = 1, $pageSize = 1000, $openId = '')
{
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/customservice/getrecord?access_token=' . AccessToken::getAccessToken();
$queryAction = 'POST';
// 创建模板数组
$template = array();
$template['starttime'] = $startTime;
$template['endtime'] = $endTime;
$template['openid'] = $openId;
$template['pagesize'] = $pageSize;
$template['pageindex'] = $pageIndex;
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 使用Curl类发送POST请求
$result = Curl::callWebServer($queryUrl, $template, $queryAction);
// 返回聊天记录列表
return isset($result['recordlist']) ? $result['recordlist'] : array();
}
}
/**
* AccessToken类用于管理微信公众号的access_token
*/
class AccessToken
{
/**
* 获取access_token
*
* @return string access_token值
*/
public static function getAccessToken()
{
// 这里应该是获取access_token的逻辑为了演示我们假设已经获取到了access_token
return 'ACCESS_TOKEN';
}
}
/**
* Curl类用于发送HTTP请求
*/
class Curl
{
/**
* 发送HTTP请求
*
* @param string $url 请求的URL
* @param string $data 请求的数据
* @param string $method 请求方法如GET、POST
* @param int $multipart 是否为multipart/form-data
* @param int $timeout 超时时间
* @return mixed 请求结果
*/
public static function callWebServer($url, $data, $method, $multipart = 0, $timeout = 0)
{
// 这里应该是发送HTTP请求的逻辑为了演示我们假设请求成功了
// 并返回了一个示例响应
return array(
'errcode' => 0,
'errmsg' => 'ok',
// 其他可能的响应数据...
);
}
}
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器

@ -0,0 +1,127 @@
<?php
namespace LaneWeChat\Core;
/**
* 智能接口类,提供与微信智能接口相关的服务。
*
* 该类主要包含语义理解功能,可以将用户的自然语言转换为机器可理解的意图。
*
* Class IntelligentInterface
* User: lane
* Date: 14-10-31
* Time: 下午3:00
* E-mail: lixuan868686@163.com
* WebSite: http://www.lanecn.com
*
*/
class IntelligentInterface
{
/**
* 微信公众号的AppID
*/
private static $appId = 'YOUR_APP_ID';
/**
* 微信公众号的AppSecret
*/
private static $appSecret = 'YOUR_APP_SECRET';
/**
* 语义理解接口,用于将用户的自然语言查询转换为结构化的语义表示。
* 该接口可以识别用户的意图,并返回相应的语义结果。
*
* @param string $query 输入文本串,用户的自然语言查询。
* @param string $category 需要使用的服务类型如“flight,hotel”多个类别用逗号分隔。
* @param string $openId 用户的OpenID用于标识用户。
* @param float $latitude 纬度坐标,与经度同时传入;与城市二选一传入。
* @param float $longitude 经度坐标,与纬度同时传入;与城市二选一传入。
* @param string $region 区域名称,在城市存在的情况下可省;与经纬度二选一传入。
* @param string $city 城市名称,如“北京”,与经纬度二选一传入。
* @return bool|mixed 语义理解结果失败返回false。
* 《接口协议文档》http://mp.weixin.qq.com/wiki/images/1/1f/微信语义理解协议文档.zip
*/
public static function semanticSemproxy($query, $category, $openId, $latitude='', $longitude='', $region='', $city='')
{
// 获取access_token
$accessToken = AccessToken::getAccessToken();
if (!$accessToken) {
// 如果获取access_token失败返回false
return false;
}
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/semantic/semproxy/search?access_token=' . $accessToken;
// 设置请求方法为POST
$queryAction = 'POST';
// 构建请求模板
$template = array();
$template['query'] = $query;
$template['category'] = $category;
$template['appid'] = self::$appId; // 微信公众号的AppID
$template['uid'] = $openId; // 用户的OpenID
// 如果提供了经纬度信息,则添加到请求模板中
if (!empty($latitude)) $template['latitude'] = $latitude;
if (!empty($longitude)) $template['longitude'] = $longitude;
// 如果提供了区域或城市信息,则添加到请求模板中
if (!empty($region)) $template['region'] = $region;
if (!empty($city)) $template['city'] = $city;
// 将请求模板转换为JSON格式
$template = json_encode($template);
// 调用Curl类的方法发送请求并获取结果
return Curl::callWebServer($queryUrl, $template, $queryAction, 0, 0);
}
/**
* 获取微信公众号的access_token
*/
private static function getAccessToken()
{
// 这里应该是获取access_token的逻辑为了演示我们假设已经获取到了access_token
return 'ACCESS_TOKEN';
}
}
/**
* AccessToken类用于管理微信公众号的access_token
*/
class AccessToken
{
/**
* 获取access_token
*
* @return string access_token值
*/
public static function getAccessToken()
{
// 这里应该是获取access_token的逻辑为了演示我们假设已经获取到了access_token
return 'ACCESS_TOKEN';
}
}
/**
* Curl类用于发送HTTP请求
*/
class Curl
{
/**
* 发送HTTP请求
*
* @param string $url 请求的URL
* @param string $data 请求的数据
* @param string $method 请求方法如GET、POST
* @param int $timeout 超时时间
* @param int $connectTimeout 连接超时时间
* @return mixed 请求结果
*/
public static function callWebServer($url, $data, $method, $timeout, $connectTimeout)
{
// 这里应该是发送HTTP请求的逻辑为了演示我们假设请求成功了
return '请求成功';
}
}
类声明class IntelligentInterface 定义了一个名为 IntelligentInterface 的类,用于提供微信智能接口相关的服务,主要包含语义理解功能。
属性声明private static $appId 和 private static $appSecret 分别用于存储微信公众号的AppID和AppSecret。
semanticSemproxy方法用于调用微信的语义理解接口将用户的自然语言查询转换为结构化的语义表示。该方法接受多个参数包括查询文本、服务类型、用户OpenID、经纬度、区域和城市等信息。
getAccessToken方法用于获取微信公众号的access_token这里假设已经获取到了access_token。
AccessToken类用于管理微信公众号的access_token提供 getAccessToken 方法来获取access_token。
Curl类用于发送HTTP请求提供 callWebServer 方法来发送请求并获取结果。

@ -0,0 +1,45 @@
namespace LaneWeChat\Core;
/**
* Auth类用于与微信公众平台进行交互。
* 该类提供了一个方法来获取微信服务器的IP列表通常用于服务器白名单的配置。
* 白名单配置可以帮助确保微信服务器能够正常与当前服务器进行通信。
*
* 创建者lixuan-it@360.cn
* 用户名lane
* 日期15/4/29
* 时间上午10:51
* 邮箱lixuan868686@163.com
* 网站http://www.lanecn.com
*/
class Auth {
/**
* 获取微信服务器IP列表
*
* 该方法请求微信公众平台的API接口获取微信服务器的IP地址列表。
* 获取到的IP地址列表可以用于设置服务器的白名单以保证微信服务器能够正常访问当前服务器。
*
* @return mixed 返回微信服务器的IP列表通常为JSON格式的数据。
*/
public static function getWeChatIPList(){
// 获取ACCESS_TOKEN调用AccessToken类中的getAccessToken方法来获取有效的ACCESS_TOKEN。
// ACCESS_TOKEN是调用微信API时必需的授权令牌必须在每次请求时附带。
$accessToken = AccessToken::getAccessToken();
// 构造请求微信API的URL拼接获取到的ACCESS_TOKEN。
// API地址为 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token='
// 通过此URL可以获取到微信服务器的IP列表。
$url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=' . $accessToken;
// 使用Curl类的callWebServer方法发起GET请求向微信API请求IP地址列表。
// 'callWebServer' 方法会通过cURL发起HTTP请求返回微信API的响应数据。
// 返回的数据通常是一个包含微信服务器IP地址的JSON格式字符串。
return Curl::callWebServer($url, '', 'GET');
}
}
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。

@ -0,0 +1,140 @@
<?php
namespace LaneWeChat\Core;
class Menu {
/**
* 添加菜单一级菜单最多3个每个一级菜单最多可以有5个二级菜单
* @param $menuList 菜单列表数组
* array(
* array('id'=>'', 'pid'=>'', 'name'=>'', 'type'=>'', 'code'=>''),
* array('id'=>'', 'pid'=>'', 'name'=>'', 'type'=>'', 'code'=>''),
* array('id'=>'', 'pid'=>'', 'name'=>'', 'type'=>'', 'code'=>''),
* );
* 'code'是view类型的URL或者其他类型的key
* 'type'是菜单类型,如下:
* 1、click点击推事件用户点击click类型按钮后微信服务器会通过消息接口推送消息类型为event的结构给开发者参考消息接口指南并且带上按钮中开发者填写的key值开发者可以通过自定义的key值与用户进行交互
* 2、view跳转URL用户点击view类型按钮后微信客户端将会打开开发者在按钮中填写的网页URL可与网页授权获取用户基本信息接口结合获得用户基本信息。
* 3、scancode_push扫码推事件用户点击按钮后微信客户端将调起扫一扫工具完成扫码操作后显示扫描结果如果是URL将进入URL且会将扫码的结果传给开发者开发者可以下发消息。
* 4、scancode_waitmsg扫码推事件且弹出“消息接收中”提示框用户点击按钮后微信客户端将调起扫一扫工具完成扫码操作后将扫码的结果传给开发者同时收起扫一扫工具然后弹出“消息接收中”提示框随后可能会收到开发者下发的消息。
* 5、pic_sysphoto弹出系统拍照发图用户点击按钮后微信客户端将调起系统相机完成拍照操作后会将拍摄的相片发送给开发者并推送事件给开发者同时收起系统相机随后可能会收到开发者下发的消息。
* 6、pic_photo_or_album弹出拍照或者相册发图用户点击按钮后微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。
* 7、pic_weixin弹出微信相册发图器用户点击按钮后微信客户端将调起微信相册完成选择操作后将选择的相片发送给开发者的服务器并推送事件给开发者同时收起相册随后可能会收到开发者下发的消息。
* 8、location_select弹出地理位置选择器用户点击按钮后微信客户端将调起地理位置选择工具完成选择操作后将选择的地理位置发送给开发者的服务器同时收起位置选择工具随后可能会收到开发者下发的消息。
*
* @return bool 返回是否成功创建菜单
*/
public static function setMenu($menuList) {
// 树形排布,将一维数组转换为树形结构,以支持子菜单
$menuList2 = $menuList;
foreach ($menuList as $key => $menu) {
foreach ($menuList2 as $k => $menu2) {
// 如果当前菜单是另一个菜单的子菜单则添加到父菜单的sub_button中
if ($menu['id'] == $menu2['pid']) {
$menuList[$key]['sub_button'][] = $menu2;
// 从数组中移除已经添加为子菜单的项
unset($menuList[$k]);
}
}
}
// 处理数据,遍历菜单数组,处理每个菜单项的详细信息
foreach ($menuList as $key => $menu) {
// 根据菜单类型处理type和code
if ($menu['type'] == 'view') {
// 对于view类型的菜单将code值作为URL
$menuList[$key]['url'] = urlencode($menu['code']);
} else if ($menu['type'] == 'click') {
// 对于click类型的菜单将code值作为key
$menuList[$key]['key'] = $menu['code'];
} else if (!empty($menu['type'])) {
// 对于其他类型的菜单将code值作为key并初始化sub_button数组
$menuList[$key]['key'] = $menu['code'];
if (!isset($menu['sub_button'])) $menuList[$key]['sub_button'] = array();
}
// 移除不需要的code字段
unset($menuList[$key]['code'], $menuList[$key]['id'], $menuList[$key]['pid']);
// 处理名字,对菜单名称进行编码以确保在JSON序列化时不会转换成Unicode字符
$menuList[$key]['name'] = urlencode($menu['name']);
// 如果存在子菜单,则递归处理子菜单
if (isset($menu['sub_button'])) {
unset($menuList[$key]['type']);
foreach ($menu['sub_button'] as $k => $son) {
// 根据子菜单类型处理type和code
if ($son['type'] == 'view') {
$menuList[$key]['sub_button'][$k]['url'] = urlencode($son['code']);
} else if ($son['type'] == 'click') {
$menuList[$key]['sub_button'][$k]['key'] = $son['code'];
} else {
$menuList[$key]['sub_button'][$k]['key'] = $son['code'];
$menuList[$key]['sub_button'][$k]['sub_button'] = array();
}
// 移除不需要的code字段
unset($menuList[$key]['sub_button'][$k]['code'], $menuList[$key]['sub_button'][$k]['id'], $menuList[$key]['sub_button'][$k]['pid']);
// 处理名字。因为汉字不能在转换JSON时被转为UNICODE
$menuList[$key]['sub_button'][$k]['name'] = urlencode($son['name']);
}
}
}
// 整理数据格式,准备发送到微信服务器
$data = array('button' => array_values($menuList)); // 重置数组索引
$data = json_encode($data); // 将数组转换为JSON字符串
$data = urldecode($data); // 对JSON字符串进行解码以确保中文字符不会被转换成Unicode字符
// 获取微信ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
$url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $accessToken;
// 发起POST请求将菜单数据发送到微信服务器
$result = Curl::callWebServer($url, $data, 'POST');
return $result['errcode'] == 0 ? true : $result; // 如果微信服务器返回errcode为0表示菜单创建成功
}
/**
* 获取微信菜单
* 此方法用于从微信服务器获取当前公众号的自定义菜单
*
* @return bool|mixed 获取成功返回菜单信息,失败返回错误信息
*/
public static function getMenu() {
// 获取微信ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
$url = 'https://api.weixin.qq.com/cgi-bin/menu/get?access_token=' . $accessToken;
// 发起GET请求从微信服务器获取菜单信息
return Curl::callWebServer($url, '', 'GET');
}
/**
* 删除微信菜单
* 此方法用于删除当前公众号的自定义菜单
*
* @return bool|mixed 删除成功返回{"errcode":0,"errmsg":"ok"},失败返回错误信息
*/
public static function delMenu() {
// 获取微信ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
$url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=' . $accessToken;
// 发起GET请求删除微信服务器上的自定义菜单
return Curl::callWebServer($url, '', 'GET');
}
}
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器

@ -0,0 +1,35 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于 LaneWeChat 模块的核心部分
/**
* 错误提示类
*
* 该类用于处理和返回错误信息,方便在程序中统一管理和显示错误。
*/
class Msg {
/**
* 返回错误信息
*
* 根据提供的错误码和错误信息,构造一个错误消息数组,并退出程序。
*
* @param int $code 错误码,用于标识具体的错误类型。
* @param string $errorMsg 自定义错误信息,如果为空,则使用默认错误信息。
* @return Ambigous <multitype:unknown , multitype:, boolean> 返回类型可能不明确因为exit函数会导致脚本终止。
*/
public static function returnErrMsg($code, $errorMsg = null) {
// 初始化错误消息数组,包含错误码
$returnMsg = array('error_code' => $code);
// 如果提供了自定义错误信息,则添加到错误消息数组中
if (!empty($errorMsg)) {
$returnMsg['custom_msg'] = $errorMsg;
}
// 如果没有提供自定义错误信息,则使用默认错误信息
// 这里可以根据错误码从错误码常量类中获取对应的错误信息
// $returnMsg['custom_msg'] = MsgConstant::ERROR_NO_BINDING_TEXT;
// 添加默认错误前缀信息
$returnMsg['custom_msg'] = '出错啦!' . $returnMsg['custom_msg'];
// 退出程序并输出错误信息
exit($returnMsg['custom_msg']);
}
}

@ -0,0 +1,86 @@
<?php
namespace LaneWeChat\Core;
// 错误码常量类
// 该类定义了一系列的错误码常量,用于标识和处理微信开发过程中可能遇到的错误。
class MsgConstant {
//-------系统错误相关--101 到200 ------
/**
* 系统错误常量
* 当系统发生未知错误时使用此常量。
*/
const ERROR_SYSTEM = 101; // 系统错误
/**
* 图文消息项数超过限制错误常量
* 当尝试发送的图文消息项数超过10时使用此常量。
*/
const ERROR_NEWS_ITEM_COUNT_MORE_TEN = 102; // 图文消息项数超过10
/**
* 菜单点击错误常量
* 当微信菜单点击跳转失败时使用此常量。
*/
const ERROR_MENU_CLICK = 103; // 菜单跳转失败,请重试
//-------用户输入相关--1001到1100------
/**
* 输入错误常量
* 当用户输入的数据有误时使用此常量。
*/
const ERROR_INPUT_ERROR = 1001; // 输入有误,请重新输入
/**
* 未知类型消息错误常量
* 当接收到未知类型的消息时使用此常量。
*/
const ERROR_UNKNOW_TYPE = 1002; // 收到了未知类型的消息
/**
* 验证码错误常量
* 当用户输入的验证码不正确时使用此常量。
*/
const ERROR_CAPTCHA_ERROR = 1003; // 验证码错误
/**
* 必填项未填写全错误常量
* 当用户提交的数据缺少必填项时使用此常量。
*/
const ERROR_REQUIRED_FIELDS = 1004; // 必填项未填写全
//-------远程调用相关--1201到1300------
/**
* 远程服务器未响应错误常量
* 当远程服务器没有响应时使用此常量。
*/
const ERROR_REMOTE_SERVER_NOT_RESPOND = 1201; // 远程服务器未响应
/**
* 获取ACCESS_TOKEN失败错误常量
* 当尝试获取微信ACCESS_TOKEN失败时使用此常量。
*/
const ERROR_GET_ACCESS_TOKEN = 1202; // 获取ACCESS_TOKEN失败
//-------文章管理相关--1301到1400------
// 文章管理相关的错误码常量可以在这里定义
//-------分类管理相关--1401到1500------
/**
* 菜单不存在错误常量
* 当尝试访问的菜单不存在时使用此常量。
*/
const ERROR_MENU_NOT_EXISTS = 1401; // 菜单不存在
//-------文案类------------
/**
* 未绑定微信错误文案常量
* 当用户未绑定微信时显示的错误文案。
*/
const ERROR_NO_BINDING_TEXT = '对不起,您尚未绑定微信,轻松绑定微信,即可查询实时流量,享受便捷服务!';
}
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class MsgConstant 定义了一个用于定义错误码常量的类。
系统错误相关常量:定义了系统错误、图文消息项数超过限制、菜单点击错误等常量。
用户输入相关常量:定义了输入错误、未知类型消息、验证码错误、必填项未填写全等常量。
远程调用相关常量定义了远程服务器未响应、获取ACCESS_TOKEN失败等常量。
分类管理相关常量:定义了菜单不存在的常量。
文案类常量:定义了未绑定微信时的错误文案。

@ -0,0 +1,86 @@
<?php
namespace LaneWeChat\Core;
class Popularize {
/**
* 生成带参数的二维码 - 第一步 创建二维码ticket
*
* 获取带参数的二维码的过程包括两步首先创建二维码ticket然后凭借ticket到指定URL换取二维码。
*
* 目前有2种类型的二维码分别是临时二维码和永久二维码
* 前者有过期时间最大为1800秒但能够生成较多数量后者无过期时间数量较少目前参数只支持1--100000
* 两种二维码分别适用于帐号绑定、用户来源统计等场景。
*
* @param int $type 二维码类型临时二维码类型为1永久二维码类型为2
* @param int $expireSeconds 过期时间只在类型为临时二维码时有效。最大为1800单位秒
* @param int $sceneId 场景值ID临时二维码时为32位非0整型永久二维码时最大值为100000目前参数只支持1--100000
* @return array 返回创建二维码ticket的结果
*/
public static function createTicket($type, $expireSeconds, $sceneId) {
// 拼接请求URL使用AccessToken::getAccessToken()获取access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' . AccessToken::getAccessToken();
// 请求方法为POST
$queryAction = 'POST';
// 初始化模板数组
$template = array();
// 根据二维码类型设置模板参数
if ($type == 1) {
$template['expire_seconds'] = $expireSeconds; // 设置临时二维码的有效时间
$template['action_name'] = 'QR_SCENE'; // 设置动作名称为QR_SCENE
} else {
$template['action_name'] = 'QR_LIMIT_SCENE'; // 设置动作名称为QR_LIMIT_SCENE
}
// 设置场景ID
$template['action_info']['scene']['scene_id'] = $sceneId;
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 调用Curl::callWebServer()方法发送请求并返回结果
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 生成带参数的二维码 - 第二步 通过ticket换取二维码
* @param string $ticket Popularize::createTicket()获得的ticket
* @param string $filename 文件路径如果不为空则会创建一个图片文件二维码文件为jpg格式保存到指定的路径
* @return string 直接echo本函数的返回值并在调用页面添加header('Content-type: image/jpg');,将会展示出一个二维码的图片。
*/
public static function getQrcode($ticket, $filename='') {
// 拼接请求URL使用urlencode()对ticket进行URL编码
$queryUrl = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . urlencode($ticket);
// 请求方法为GET
$queryAction = 'GET';
// 调用Curl::callWebServer()方法发送请求并获取结果
$result = Curl::callWebServer($queryUrl, '', $queryAction, 0);
// 如果指定了保存文件名,则将结果保存到文件
if (!empty($filename)) {
file_put_contents($filename, $result);
}
// 返回二维码图片内容或保存结果
return $result;
}
/**
* 将一条长链接转成短链接。
* 主要使用场景:开发者用于生成二维码的原链接(商品、支付二维码等)太长导致扫码速度和成功率下降,
* 将原长链接通过此接口转成短链接再生成二维码将大大提升扫码速度和成功率。
* @param string $longUrl 需要转换的长链接支持http://、https://、weixin://wxpay 格式的url
* @return array 返回短链接结果
*/
public static function long2short($longUrl) {
// 拼接请求URL使用AccessToken::getAccessToken()获取access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/shorturl?access_token=' . AccessToken::getAccessToken();
// 请求方法为POST
$queryAction = 'POST';
// 初始化模板数组
$template = array();
// 设置长链接
$template['long_url'] = $longUrl;
// 调用Curl::callWebServer()方法发送请求并返回结果
return Curl::callWebServer($queryUrl, json_encode($template), $queryAction);
}
}
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Popularize 定义了一个用于生成带参数的二维码和长链接转换的类。
createTicket方法创建二维码ticket。根据二维码类型临时或永久设置参数并发送POST请求获取ticket。
getQrcode方法通过ticket换取二维码。发送GET请求获取二维码图片并可选择保存到文件。
long2short方法将长链接转换为短链接。发送POST请求将长链接转换为短链接以提高扫码速度和成功率。

@ -0,0 +1,215 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于 LaneWeChat 模块的核心部分
/**
* 主动发送消息类
*
* 该类用于主动发送各种类型的消息给微信用户,包括文本、图片、语音、视频、音乐和图文消息。
*/
class ResponseInitiative {
// 发送消息的URL基础部分
protected static $queryUrl = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=';
// HTTP请求方法主动发送消息使用POST方法
protected static $action = 'POST';
/**
* 发送文本消息
*
* @param string $tousername 接收者的OpenID
* @param string $content 回复的消息内容换行在content中能够换行微信客户端就支持换行显示
* @return string 发送结果
*/
public static function text($tousername, $content) {
// 获取ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
// 拼接完整的请求URL
self::$queryUrl .= $accessToken;
// 构造文本消息模板
$template = array(
'touser' => $tousername, // 接收者的OpenID
'msgtype' => 'text', // 消息类型为文本
'text' => array(
'content' => $content, // 文本消息内容
),
);
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 发送请求并返回结果
return Curl::callWebServer(self::$queryUrl, $template, self::$action);
}
/**
* 发送图片消息
*
* @param string $tousername 接收者的OpenID
* @param string $mediaId 通过上传多媒体文件得到的id
* @return string 发送结果
*/
public static function image($tousername, $mediaId) {
// 获取ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
// 拼接完整的请求URL
self::$queryUrl .= $accessToken;
// 构造图片消息模板
$template = array(
'touser' => $tousername, // 接收者的OpenID
'msgtype' => 'image', // 消息类型为图片
'image' => array(
'media_id' => $mediaId, // 图片的媒体ID
),
);
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 发送请求并返回结果
return Curl::callWebServer(self::$queryUrl, $template, self::$action);
}
/**
* 发送语音消息
*
* @param string $tousername 接收者的OpenID
* @param string $mediaId 通过上传多媒体文件得到的id
* @return string 发送结果
*/
public static function voice($tousername, $mediaId) {
// 获取ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
// 拼接完整的请求URL
self::$queryUrl .= $accessToken;
// 构造语音消息模板
$template = array(
'touser' => $tousername, // 接收者的OpenID
'msgtype' => 'voice', // 消息类型为语音
'voice' => array(
'media_id' => $mediaId, // 语音的媒体ID
),
);
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 发送请求并返回结果
return Curl::callWebServer(self::$queryUrl, $template, self::$action);
}
/**
* 发送视频消息
*
* @param string $tousername 接收者的OpenID
* @param string $mediaId 通过上传多媒体文件得到的id
* @param string $title 标题
* @param string $description 描述
* @return string 发送结果
*/
public static function video($tousername, $mediaId, $title, $description) {
// 获取ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
// 拼接完整的请求URL
self::$queryUrl .= $accessToken;
// 构造视频消息模板
$template = array(
'touser' => $tousername, // 接收者的OpenID
'msgtype' => 'video', // 消息类型为视频
'video' => array(
'media_id' => $mediaId, // 视频的媒体ID
'title' => $title, // 视频标题
'description' => $description, // 视频描述
),
);
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 发送请求并返回结果
return Curl::callWebServer(self::$queryUrl, $template, self::$action);
}
/**
* 发送音乐消息
*
* @param string $tousername 接收者的OpenID
* @param string $title 标题
* @param string $description 描述
* @param string $musicUrl 音乐链接
* @param string $hqMusicUrl 高质量音乐链接WIFI环境优先使用该链接播放音乐
* @param string $thumbMediaId 缩略图的媒体id通过上传多媒体文件得到的id
* @return string 发送结果
*/
public static function music($tousername, $title, $description, $musicUrl, $hqMusicUrl, $thumbMediaId) {
// 获取ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
// 拼接完整的请求URL
self::$queryUrl .= $accessToken;
// 构造音乐消息模板
$template = array(
'touser' => $tousername, // 接收者的OpenID
'msgtype' => 'music', // 消息类型为音乐
'music' => array(
'title' => $title, // 音乐标题
'description' => $description, // 音乐描述
'musicurl' => $musicUrl, // 音乐链接
'hqmusicurl' => $hqMusicUrl, // 高质量音乐链接
'thumb_media_id' => $thumbMediaId, // 缩略图的媒体ID
),
);
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 发送请求并返回结果
return Curl::callWebServer(self::$queryUrl, $template, self::$action);
}
/**
* 准备图文消息的单个项目
*
* @param string $title 标题
* @param string $description 描述
* @param string $picUrl 图片链接支持JPG、PNG格式较好的效果为大图360*200小图200*200
* @param string $url 点击图文消息跳转链接
* @return array 图文消息项目
*/
public static function newsItem($title, $description, $picUrl, $url) {
// 返回图文消息的单个项目数组
return array(
'title' => $title, // 标题
'description' => $description, // 描述
'url' => $url, // 点击图文消息跳转链接
'picurl' => $picUrl, // 图片链接
);
}
/**
* 发送图文消息
*
* @param string $tousername 接收者的OpenID
* @param array $item 图文消息项目数组每个项由self::newsItem()返回
* @return string 发送结果
*/
public static function news($tousername, $item) {
// 获取ACCESS_TOKEN
$accessToken = AccessToken::getAccessToken();
// 拼接完整的请求URL
self::$queryUrl .= $accessToken;
// 构造图文消息模板
$template = array(
'touser' => $tousername, // 接收者的OpenID
'msgtype' => 'news', // 消息类型为图文
'news' => array(
'articles' => $item // 图文消息项目数组
),
);
// 将模板数组转换为JSON格式
$template = json_encode($template);
// 发送请求并返回结果
return Curl::callWebServer(self::$queryUrl, $template, self::$action);
}
}

@ -0,0 +1,437 @@
<?php
namespace LaneWeChat\Core;
/**
* 发送被动响应
* Created by Lane.
* User: lane
* Date: 13-12-19
* Time: 下午3:01
* Mail: lixuan868686@163.com
* Website: http://www.lanecn.com
*/
class ResponsePassive {
/**
* @description 文本消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $content 回复的消息内容换行在content中能够换行微信客户端就支持换行显示
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的文本消息
*/
public static function text($fromusername, $tousername, $content, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $content, $funcFlag);
}
/**
* @description 图片消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $mediaId 通过上传多媒体文件得到的id
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的图片消息
*/
public static function image($fromusername, $tousername, $mediaId, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[%s]]></MediaId>
</Image>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $mediaId, $funcFlag);
}
/**
* @description 语音消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $mediaId 通过上传多媒体文件得到的id
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的语音消息
*/
public static function voice($fromusername, $tousername, $mediaId, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[%s]]></MediaId>
</Voice>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $mediaId, $funcFlag);
}
/**
* @description 视频消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $mediaId 通过上传多媒体文件得到的id
* @param $title 标题
* @param $description 描述
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的视频消息
*/
public static function video($fromusername, $tousername, $mediaId, $title, $description, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<Video>
<MediaId><![CDATA[%s]]></MediaId>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
</Video>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $mediaId, $title, $description, $funcFlag);
}
/**
* @description 音乐消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $title 标题
* @param $description 描述
* @param $musicUrl 音乐链接
* @param $hqMusicUrl 高质量音乐链接WIFI环境优先使用该链接播放音乐
* @param $thumbMediaId 缩略图的媒体id通过上传多媒体文件得到的id
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的音乐消息
*/
public static function music($fromusername, $tousername, $title, $description, $musicUrl, $hqMusicUrl, $thumbMediaId, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
<Music>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<MusicUrl><![CDATA[%s]]></MusicUrl>
<HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
<ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
</Music>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $title, $description, $musicUrl, $hqMusicUrl, $thumbMediaId, $funcFlag);
}
/**
* @description 图文消息 - 单个项目的准备工作用于内嵌到self::news()中。现调用本方法再调用self::news()
* 多条图文消息信息默认第一个item为大图,注意如果调用本方法得到的数组总项数超过10则将会无响应
* @param $title 标题
* @param $description 描述
* @param $picUrl 图片链接支持JPG、PNG格式较好的效果为大图360*200小图200*200
* @param $url 点击图文消息跳转链接
* @return string 返回XML格式的图文消息项
*/
public static function newsItem($title, $description, $picUrl, $url) {
$template = <<<XML
<item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
XML;
return sprintf($template, $title, $description, $picUrl, $url);
}
/**
* @description 图文消息 - 先调用self::newsItem()再调用本方法
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $item 数组每个项由self::newsItem()返回
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的图文消息
*/
public static function news($fromusername, $tousername, $item, $funcFlag=0) {
//多条图文消息信息默认第一个item为大图,注意如果图文数超过10则将会无响应
if(count($item) >= 10){
$request = array('fromusername'=>$fromusername, 'tousername'=>$tousername);
return Msg::returnErrMsg(MsgConstant::ERROR_NEWS_ITEM_COUNT_MORE_TEN, '图文消息的项数不能超过10条', $request);
}
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>%s</ArticleCount
<?php
namespace LaneWeChat\Core;
/**
* 发送被动响应
* Created by Lane.
* User: lane
* Date: 13-12-19
* Time: 下午3:01
* Mail: lixuan868686@163.com
* Website: http://www.lanecn.com
*/
class ResponsePassive {
/**
* @description 文本消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $content 回复的消息内容换行在content中能够换行微信客户端就支持换行显示
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的文本消息
*/
public static function text($fromusername, $tousername, $content, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $content, $funcFlag);
}
/**
* @description 图片消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $mediaId 通过上传多媒体文件得到的id
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的图片消息
*/
public static function image($fromusername, $tousername, $mediaId, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[%s]]></MediaId>
</Image>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $mediaId, $funcFlag);
}
/**
* @description 语音消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $mediaId 通过上传多媒体文件得到的id
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的语音消息
*/
public static function voice($fromusername, $tousername, $mediaId, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[%s]]></MediaId>
</Voice>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $mediaId, $funcFlag);
}
/**
* @description 视频消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $mediaId 通过上传多媒体文件得到的id
* @param $title 标题
* @param $description 描述
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的视频消息
*/
public static function video($fromusername, $tousername, $mediaId, $title, $description, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<Video>
<MediaId><![CDATA[%s]]></MediaId>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
</Video>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $mediaId, $title, $description, $funcFlag);
}
/**
* @description 音乐消息
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $title 标题
* @param $description 描述
* @param $musicUrl 音乐链接
* @param $hqMusicUrl 高质量音乐链接WIFI环境优先使用该链接播放音乐
* @param $thumbMediaId 缩略图的媒体id通过上传多媒体文件得到的id
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的音乐消息
*/
public static function music($fromusername, $tousername, $title, $description, $musicUrl, $hqMusicUrl, $thumbMediaId, $funcFlag=0) {
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
<Music>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<MusicUrl><![CDATA[%s]]></MusicUrl>
<HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
<ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
</Music>
<FuncFlag>%s</FuncFlag>
</xml>
XML;
return sprintf($template, $fromusername, $tousername, time(), $title, $description, $musicUrl, $hqMusicUrl, $thumbMediaId, $funcFlag);
}
/**
* @description 图文消息 - 单个项目的准备工作用于内嵌到self::news()中。现调用本方法再调用self::news()
* 多条图文消息信息默认第一个item为大图,注意如果调用本方法得到的数组总项数超过10则将会无响应
* @param $title 标题
* @param $description 描述
* @param $picUrl 图片链接支持JPG、PNG格式较好的效果为大图360*200小图200*200
* @param $url 点击图文消息跳转链接
* @return string 返回XML格式的图文消息项
*/
public static function newsItem($title, $description, $picUrl, $url) {
$template = <<<XML
<item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
XML;
return sprintf($template, $title, $description, $picUrl, $url);
}
/**
* @description 图文消息 - 先调用self::newsItem()再调用本方法
* @param $fromusername 发送方的OpenId
* @param $tousername 接收方的OpenId
* @param $item 数组每个项由self::newsItem()返回
* @param $funcFlag 默认为0设为1时星标刚才收到的消息
* @return string 返回XML格式的图文消息
*/
public static function news($fromusername, $tousername, $item, $funcFlag=0) {
//多条图文消息信息默认第一个item为大图,注意如果图文数超过10则将会无响应
if(count($item) >= 10){
$request = array('fromusername'=>$fromusername, 'tousername'=>$tousername);
return Msg::returnErrMsg(MsgConstant::ERROR_NEWS_ITEM_COUNT_MORE_TEN, '图文消息的项数不能超过10条', $request);
}
$template = <<<XML
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>%s</ArticleCount
ResponsePassive 类是一个用于微信公众号被动响应消息的工具类,它封装了各种消息类型的发送方法,使得开发者能够方便地根据用户请求回复不同形式的消息。以下是该类中各方法的详细讲解:
文本消息
功能:用于回复文本内容给用户。
参数:
$fromusername发送方的OpenId即公众号的OpenId。
$tousername接收方的OpenId即用户的OpenId。
$content要回复的文本内容支持换行微信客户端会按换行显示。
$funcFlag默认为0设为1时星标刚才收到的消息方便用户快速找到。
返回值返回一个XML格式的文本消息字符串包含消息的接收方、发送方、创建时间、消息类型以及文本内容等字段。
图片消息
功能:用于回复图片给用户。
参数:
$fromusername发送方的OpenId即公众号的OpenId。
$tousername接收方的OpenId即用户的OpenId。
$mediaId通过上传多媒体文件到微信服务器得到的图片媒体id。
$funcFlag默认为0设为1时星标刚才收到的消息。
返回值返回一个XML格式的图片消息字符串包含消息的接收方、发送方、创建时间、消息类型以及图片媒体id等字段。
语音消息
功能:用于回复语音给用户。
参数:
$fromusername发送方的OpenId即公众号的OpenId。
$tousername接收方的OpenId即用户的OpenId。
$mediaId通过上传多媒体文件到微信服务器得到的语音媒体id。
$funcFlag默认为0设为1时星标刚才收到的消息。
返回值返回一个XML格式的语音消息字符串包含消息的接收方、发送方、创建时间、消息类型以及语音媒体id等字段。
视频消息
功能:用于回复视频给用户。
参数:
$fromusername发送方的OpenId即公众号的OpenId。
$tousername接收方的OpenId即用户的OpenId。
$mediaId通过上传多媒体文件到微信服务器得到的视频媒体id。
$title视频消息的标题。
$description视频消息的描述。
$funcFlag默认为0设为1时星标刚才收到的消息。
返回值返回一个XML格式的视频消息字符串包含消息的接收方、发送方、创建时间、消息类型、视频媒体id、标题、描述等字段。
音乐消息
功能:用于回复音乐给用户。
参数:
$fromusername发送方的OpenId即公众号的OpenId。
$tousername接收方的OpenId即用户的OpenId。
$title音乐消息的标题。
$description音乐消息的描述。
$musicUrl音乐链接用户点击后会跳转到该链接播放音乐。
$hqMusicUrl高质量音乐链接WIFI环境下优先使用该链接播放音乐。
$thumbMediaId缩略图的媒体id通过上传多媒体文件到微信服务器得到。
$funcFlag默认为0设为1时星标刚才收到的消息。
返回值返回一个XML格式的音乐消息字符串包含消息的接收方、发送方、创建时间、消息类型、音乐链接、高质量音乐链接、缩略图媒体id等字段。
图文消息 - 单个项目的准备工作
功能准备图文消息的单个项目用于内嵌到news()方法中组装成完整的图文消息。
参数:
$title图文消息的标题。
$description图文消息的描述。
$picUrl图片链接支持JPG、PNG格式大图建议360200小图建议200200。
$url点击图文消息跳转的链接。
返回值返回一个XML格式的图文消息项字符串包含标题、描述、图片链接、跳转链接等字段。
图文消息
功能:用于回复图文消息给用户。
参数:
$fromusername发送方的OpenId即公众号的OpenId。
$tousername接收方的OpenId即用户的OpenId。
$item数组每个项由newsItem()方法返回的图文消息项。
$funcFlag默认为0设为1时星标刚才收到的消息。
返回值返回一个XML格式的图文消息字符串包含消息的接收方、发送方、创建时间、消息类型、图文消息项数量以及各个图文消息项的内容。需要注意的是图文消息的项数不能超过10条否则将会无响应

@ -0,0 +1,106 @@
<?php
namespace LaneWeChat\Core;
/**
* 模板消息接口
* 此类提供了微信公众号模板消息的相关操作包括设置行业、获取模板ID和发送模板消息。
* 模板消息用于公众号向用户发送重要的服务通知,如信用卡刷卡通知、商品购买成功通知等。
* 不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。
*/
class TemplateMessage {
/**
* 设置所属行业
* 公众号模板消息需要设置所属行业每月可更改1次所选行业。
* @param int $industryId1 公众号模板消息所属行业编号,第一个行业编号
* @param int $industryId2 公众号模板消息所属行业编号,第二个行业编号
* @return mixed 返回调用结果通常是一个数组或者JSON字符串
*/
public static function setIndustry($industryId1, $industryId2) {
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=' . AccessToken::getAccessToken();
// 设置请求方法为POST
$queryAction = 'POST';
// 构建请求数据数组
$template = array();
$template['industry_id1'] = "$industryId1";
$template['industry_id2'] = "$industryId2";
// 将数组转换为JSON格式
$template = json_encode($template);
// 调用Curl类发送请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 获得模板ID
* 从模板库中添加模板获取模板ID。
* @param string $templateIdShort 模板库中模板的编号有“TM**”和“OPENTMTM**”等形式
* @return mixed 返回调用结果通常是一个数组或者JSON字符串
*/
public static function getTemplateId($templateIdShort) {
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=' . AccessToken::getAccessToken();
// 设置请求方法为POST
$queryAction = 'POST';
// 构建请求数据数组
$template = array();
$template['template_id_short'] = "$templateIdShort";
// 将数组转换为JSON格式
$template = json_encode($template);
// 调用Curl类发送请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
/**
* 向用户推送模板消息
* 发送模板消息给指定的用户。
* @param array $data 模板数据,包含多个键值对,每个键对应模板中的一个参数
* @param string $touser 接收方的OpenId
* @param string $templateId 模板Id在公众平台线上模板库中选用模板获得ID
* @param string $url 点击模板消息会跳转到的链接
* @param string $topcolor 顶部颜色,可以为空,默认是红色
* @return mixed 返回调用结果通常是一个数组或者JSON字符串
*/
public static function sendTemplateMessage($data, $touser, $templateId, $url, $topcolor = '#FF0000') {
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . AccessToken::getAccessToken();
// 设置请求方法为POST
$queryAction = 'POST';
// 构建请求数据数组
$template = array();
$template['touser'] = $touser;
$template['template_id'] = $templateId;
$template['url'] = $url;
$template['topcolor'] = $topcolor;
$template['data'] = $data;
// 将数组转换为JSON格式
$template = json_encode($template);
// 调用Curl类发送请求
return Curl::callWebServer($queryUrl, $template, $queryAction);
}
}
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class TemplateMessage 定义了一个用于处理微信公众号模板消息的类。
setIndustry方法设置公众号模板消息所属的行业。需要提供两个行业编号每月可更改一次。
getTemplateId方法从模板库中添加模板获取模板ID。需要提供模板库中的模板编号。
sendTemplateMessage方法向指定用户发送模板消息。需要提供模板数据、接收方的OpenId、模板ID、跳转链接和顶部颜色。
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class TemplateMessage 定义了一个用于处理微信公众号模板消息的类。
setIndustry方法设置公众号模板消息所属的行业。需要提供两个行业编号每月可更改一次。
getTemplateId方法从模板库中添加模板获取模板ID。需要提供模板库中的模板编号。
sendTemplateMessage方法向指定用户发送模板消息。需要提供模板数据、接收方的OpenId、模板ID、跳转链接和顶部颜色。
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class TemplateMessage 定义了一个用于处理微信公众号模板消息的类。
setIndustry方法设置公众号模板消息所属的行业。需要提供两个行业编号每月可更改一次。
getTemplateId方法从模板库中添加模板获取模板ID。需要提供模板库中的模板编号。
sendTemplateMessage方法向指定用户发送模板消息。需要提供模板数据、接收方的OpenId、模板ID、跳转链接和顶部颜色。
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class TemplateMessage 定义了一个用于处理微信公众号模板消息的类。
setIndustry方法设置公众号模板消息所属的行业。需要提供两个行业编号每月可更改一次。
getTemplateId方法从模板库中添加模板获取模板ID。需要提供模板库中的模板编号。
sendTemplateMessage方法向指定用户发送模板消息。需要提供模板数据、接收方的OpenId、模板ID、跳转链接和顶部颜色。
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class TemplateMessage 定义了一个用于处理微信公众号模板消息的类。
setIndustry方法设置公众号模板消息所属的行业。需要提供两个行业编号每月可更改一次。
getTemplateId方法从模板库中添加模板获取模板ID。需要提供模板库中的模板编号。
sendTemplateMessage方法向指定用户发送模板消息。需要提供模板数据、接收方的OpenId、模板ID、跳转链接和顶部颜色。

@ -0,0 +1,161 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于 LaneWeChat 模块的核心部分
/**
* 用户管理类
*
* 该类用于管理微信公众号的用户信息,包括创建和管理用户分组、获取用户信息、设置用户备注等。
*/
class UserManage {
/**
* 创建一个新的用户分组
*
* @param string $groupName 分组名称
* @return mixed 返回创建分组的结果
*/
public static function createGroup($groupName) {
// 获取access_token用于验证API请求的合法性
$accessToken = AccessToken::getAccessToken();
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/groups/create?access_token=' . $accessToken;
// 准备发送的数据,包含分组名称
$data = '{"group":{"name":"' . $groupName . '"}}';
// 发起POST请求调用Curl类的方法
return Curl::callWebServer($queryUrl, $data, 'POST');
}
/**
* 获取所有用户分组列表
*
* @return mixed 返回分组列表
*/
public static function getGroupList() {
// 获取access_token
$accessToken = AccessToken::getAccessToken();
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/groups/get?access_token=' . $accessToken;
// 不需要发送数据
$data = '';
// 发起GET请求调用Curl类的方法
return Curl::callWebServer($queryUrl, $data, 'GET');
}
/**
* 根据OpenId获取用户所在的分组ID
*
* @param string $openId 用户的OpenId
* @return mixed 返回用户所在的分组ID
*/
public static function getGroupByOpenId($openId) {
// 获取access_token
$accessToken = AccessToken::getAccessToken();
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/groups/getid?access_token=' . $accessToken;
// 准备发送的数据包含OpenId
$data = '{"openid":"' . $openId . '"}';
// 发起POST请求调用Curl类的方法
return Curl::callWebServer($queryUrl, $data, 'POST');
}
/**
* 编辑用户分组的名称
*
* @param int $groupId 分组ID
* @param string $groupName 新的分组名称
* @return mixed 返回编辑分组名称的结果
*/
public static function editGroupName($groupId, $groupName) {
// 获取access_token
$accessToken = AccessToken::getAccessToken();
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/groups/update?access_token=' . $accessToken;
// 准备发送的数据包含分组ID和新名称
$data = '{"group":{"id":' . $groupId . ',"name":"' . $groupName . '"}}';
// 发起POST请求调用Curl类的方法
return Curl::callWebServer($queryUrl, $data, 'POST');
}
/**
* 将用户移动到另一个分组
*
* @param string $openid 用户的OpenId
* @param int $to_groupid 目标分组ID
* @return mixed 返回移动用户的结果
*/
public static function editUserGroup($openid, $to_groupid) {
// 获取access_token
$accessToken = AccessToken::getAccessToken();
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token=' . $accessToken;
// 准备发送的数据包含OpenId和目标分组ID
$data = '{"openid":"' . $openid . '","to_groupid":' . $to_groupid . '}';
// 发起POST请求调用Curl类的方法
return Curl::callWebServer($queryUrl, $data, 'POST');
}
/**
* 获取用户的详细信息
*
* @param string $openId 用户的OpenId
* @return mixed 返回用户的详细信息
*/
public static function getUserInfo($openId) {
// 获取access_token
$accessToken = AccessToken::getAccessToken();
// 构建请求URL包含access_token和OpenId
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token=' . $accessToken . '&openid=' . $openId;
// 发起GET请求调用Curl类的方法
return Curl::callWebServer($queryUrl, '', 'GET');
}
/**
* 获取公众号粉丝列表
*
* @param string $next_openid 下一个OpenId用于分页获取粉丝列表
* @return mixed 返回粉丝列表
*/
public static function getFansList($next_openid = '') {
// 获取access_token
$accessToken = AccessToken::getAccessToken();
// 如果没有提供next_openid
if (empty($next_openid)) {
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token=' . $accessToken;
} else {
// 如果提供了next_openid
// 构建请求URL包含access_token和next_openid
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token=' . $accessToken . '&next_openid=' . $next_openid;
}
// 发起GET请求调用Curl类的方法
return Curl::callWebServer($queryUrl, '', 'GET');
}
/**
* 设置用户的备注名
*
* @param string $openId 用户的OpenId
* @param string $remark 用户的备注名
* @return mixed 返回设置备注名的结果
*/
public static function setRemark($openId, $remark) {
// 获取access_token
$accessToken = AccessToken::getAccessToken();
// 构建请求URL包含access_token
$queryUrl = 'https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token=' . $accessToken;
// 准备发送的数据包含OpenId和备注名
$data = json_encode(array('openid' => $openId, 'remark' => $remark));
// 发起POST请求调用Curl类的方法
return Curl::callWebServer($queryUrl, $data, 'POST');
}
/**
* 获取网络状态
*
* 输出JavaScript代码用于在微信浏览器中调用微信JSSDK的getNetworkType方法
*/
public static function getNetworkState() {
// 输出JavaScript代码
echo "WeixinJSBridge.invoke('getNetworkType',{},function(e){WeixinJSBridge.log(e.err_msg);});";
}
}

@ -0,0 +1,102 @@
<?php
// 定义命名空间,用于组织代码
namespace LaneWeChat\Core;
// Wechat类定义用于处理微信相关功能
class Wechat {
// 私有属性,用于调试模式和请求数据
private $debug;
private $request;
// 构造函数用于初始化Wechat对象
public function __construct($token, $debug = FALSE) {
// 检查是否是微信服务器的验证请求,并验证签名
if ($this->isValid() && $this->validateSignature($token)) {
// 如果验证通过返回echostr给微信服务器
return $_GET['echostr'];
}
// 设置调试模式
$this->debug = $debug;
// 解析微信发送的XML数据
$xml = (array) simplexml_load_string($GLOBALS['HTTP_RAW_POST_DATA'], 'SimpleXMLElement', LIBXML_NOCDATA);
// 将XML数据转换为数组并转换所有键为小写
$this->request = array_change_key_case($xml, CASE_LOWER);
}
// 私有方法isValid用于检查是否是微信服务器的验证请求
private function isValid() {
// 检查是否存在echostr参数该参数在微信服务器验证时存在
return isset($_GET['echostr']);
}
// 私有方法validateSignature用于验证签名
private function validateSignature($token) {
// 获取微信服务器发送的signature、timestamp、nonce参数
$signature = $_GET['signature'];
$timestamp = $_GET['timestamp'];
$nonce = $_GET['nonce'];
// 将token、timestamp、nonce组合并排序
$signatureArray = array($token, $timestamp, $nonce);
sort($signatureArray, SORT_STRING);
// 计算签名并比较
return sha1(implode($signatureArray)) == $signature;
}
// 受保护的方法getRequest用于获取请求参数
protected function getRequest($param = FALSE) {
// 如果没有指定参数,则返回所有请求参数
if ($param === FALSE) {
return $this->request;
}
// 将参数名转为小写
$param = strtolower($param);
// 如果请求参数存在,则返回该参数的值
if (isset($this->request[$param])) {
return $this->request[$param];
}
// 如果请求参数不存在则返回NULL
return NULL;
}
// 公共方法run用于处理微信请求
public function run() {
// 根据请求类型分发处理
return WechatRequest::switchType($this->request);
}
// 公共方法checkSignature用于检查签名
public function checkSignature() {
// 获取微信服务器发送的signature、timestamp、nonce参数
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
// 获取配置中的token
$token = WECHAT_TOKEN;
// 将token、timestamp、nonce组合并排序
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
// 将组合后的字符串转为sha1签名
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
// 比较计算出的签名和微信服务器发送的签名
if ($tmpStr == $signature) {
// 如果签名匹配返回echostr给微信服务器
echo $_GET['echostr'];
return true;
} else {
// 如果签名不匹配返回false
return false;
}
}
}
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间,用于组织代码。
类定义class Wechat 定义了一个用于处理微信相关功能的类。
私有属性private $debug; 和 private $request; 分别用于存储调试模式和请求数据。
构造函数public function __construct($token, $debug = FALSE) 初始化Wechat对象验证微信服务器的请求并解析微信发送的XML数据。
isValid方法private function isValid() 检查是否是微信服务器的验证请求。
validateSignature方法private function validateSignature($token) 验证微信服务器发送的签名。
getRequest方法protected function getRequest($param = FALSE) 获取请求参数,如果没有指定参数,则返回所有请求参数。
run方法public function run() 处理微信请求,根据请求类型分发处理。
checkSignature方法public function checkSignature() 检查签名,验证微信服务器发送的签名是否匹配。

@ -0,0 +1,121 @@
<?php
/**
* 微信OAuth2类
*
* 该类用于处理微信OAuth2授权流程包括获取授权URL、获取access_token和openid、刷新access_token、获取用户信息和检查access_token有效性。
*/
class WeChatOAuth {
/**
* 获取微信授权的URL并跳转用户到微信授权页面
*
* @param string $redirect_uri 授权后重定向的回调链接地址,需 urlencode 编码
* @param int $state 重定向后会带上 state 参数,可标识用户的不同身份
* @param string $scope 应用授权作用域,此处默认为 snsapi_base
* @return void 直接进行页面跳转,无返回值
*/
public function getCode($redirect_uri, $state = 1, $scope = 'snsapi_base') {
// 确保 redirect_uri 符合微信要求,去除前导斜杠
$redirect_uri = ltrim($redirect_uri, '/');
// 构建微信授权URL拼接所有必要的参数
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?' .
'appid=' . WECHAT_APPID .
'&redirect_uri=' . urlencode("http://" . $_SERVER['HTTP_HOST'] . "/" . $redirect_uri) .
'&response_type=code' .
'&scope=' . $scope .
'&state=' . $state .
'#wechat_redirect';
// 使用 HTTP 头实现页面跳转跳至微信授权页面
header("Location: $url");
exit;
}
/**
* 通过授权码获取 access_token 和 openid
*
* @param string $code 授权回调时带来的授权码参数
* @return array|bool 返回包含 access_token 和 openid 的数组,或在失败时返回 false
*/
public function getAccessTokenAndOpenId($code) {
// 构建请求微信接口的URL用于获取 access_token 和 openid
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' .
'appid=' . WECHAT_APPID .
'&secret=' . WECHAT_APPSECRET .
'&code=' . $code .
'&grant_type=authorization_code';
// 发起请求,获取响应结果
$result = Curl::callWebServer($url, null);
// 解析响应结果,检查是否获取成功
$res = json_decode($result, true);
return isset($res['access_token'], $res['openid']) ? $res : false;
}
/**
* 使用 refresh_token 刷新 access_token
*
* @param string $refreshToken 用于刷新的旧 access_token
* @return array|bool 成功时返回新的 access_token 和 openid失败时返回 false
*/
public function refreshToken($refreshToken) {
// 构建请求微信接口的URL用于刷新 access_token
$url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?' .
'appid=' . WECHAT_APPID .
'&grant_type=refresh_token' .
'&refresh_token=' . $refreshToken;
// 发起请求,获取响应结果
$result = Curl::callWebServer($url, null);
// 解析响应结果,检查是否成功刷新
$res = json_decode($result, true);
return isset($res['access_token'], $res['openid']) ? $res : false;
}
/**
* 获取用户的基本信息
*
* @param string $accessToken 有效的 access_token
* @param string $openId 用户标识
* @param string $lang 返回国家语言,这里默认为简体中文 'zh_CN'
* @return array 返回包含用户信息的数组
*/
public function getUserInfo($accessToken, $openId, $lang = 'zh_CN') {
// 构建请求微信接口的URL用于获取用户信息
$url = 'https://api.weixin.qq.com/sns/userinfo?' .
'access_token=' . $accessToken .
'&openid=' . $openId .
'&lang=' . $lang;
// 发起请求,获取响应结果
$result = Curl::callWebServer($url, null);
// 解析响应结果,直接返回
return json_decode($result, true);
}
/**
* 检查 access_token 是否有效
*
* @param string $accessToken 需要检查的 access_token
* @param string $openId 用户标识
* @return bool 有效返回 true无效返回 false
*/
public function checkAccessToken($accessToken, $openId) {
// 构建请求微信接口的URL用于验证 access_token 有效性
$url = 'https://api.weixin.qq.com/sns/auth?' .
'access_token=' . $accessToken .
'&openid=' . $openId;
// 发起请求,获取响应结果
$result = Curl::callWebServer($url, null);
// 解析响应结果,检查 errcode 是否为 0表示 access_token 有效
$res = json_decode($result, true);
return $res['errcode'] == 0;
}
}

@ -0,0 +1,138 @@
<?php
namespace LaneWeChat\Core; // 定义命名空间为 LaneWeChat\Core表示该类属于 LaneWeChat 模块的核心部分
/**
* 微信请求处理类
*
* 该类用于处理微信公众号接收到的各种请求,包括消息和事件。
*
* Created by Lane.
* User: lane
* Date: 13-12-19
* Time: 下午11:04
* Mail: lixuan868686@163.com
* Website: http://www.lanecn.com
*/
class WechatRequest {
/**
* 分发请求
*
* 根据请求的类型msgtype和事件类型event调用相应的处理方法。
*
* @param array $request 请求数据
* @return array|string 返回处理结果
*/
public static function switchType(&$request) {
$data = array();
switch ($request['msgtype']) {
// 事件类型的消息
case 'event':
$request['event'] = strtolower($request['event']);
switch ($request['event']) {
// 用户关注事件
case 'subscribe':
// 二维码关注事件
if (isset($request['eventkey']) && isset($request['ticket'])) {
$data = self::eventQrsceneSubscribe($request);
// 普通关注事件
} else {
$data = self::eventSubscribe($request);
}
break;
// 扫描二维码事件
case 'scan':
$data = self::eventScan($request);
break;
// 地理位置事件
case 'location':
$data = self::eventLocation($request);
break;
// 自定义菜单点击事件
case 'click':
$data = self::eventClick($request);
break;
// 自定义菜单跳转链接事件
case 'view':
$data = self::eventView($request);
break;
// 扫码推事件
case 'scancode_push':
$data = self::eventScancodePush($request);
break;
// 扫码推事件且弹出“消息接收中”提示框
case 'scancode_waitmsg':
$data = self::eventScancodeWaitMsg($request);
break;
// 弹出系统拍照发图事件
case 'pic_sysphoto':
$data = self::eventPicSysPhoto($request);
break;
// 弹出拍照或者相册发图事件
case 'pic_photo_or_album':
$data = self::eventPicPhotoOrAlbum($request);
break;
// 弹出微信相册发图事件
case 'pic_weixin':
$data = self::eventPicWeixin($request);
break;
// 弹出地理位置选择器事件
case 'location_select':
$data = self::eventLocationSelect($request);
break;
// 用户取消关注事件
case 'unsubscribe':
$data = self::eventUnsubscribe($request);
break;
// 群发接口完成后推送的结果
case 'masssendjobfinish':
$data = self::eventMassSendJobFinish($request);
break;
// 模板消息完成后推送的结果
case 'templatesendjobfinish':
$data = self::eventTemplateSendJobFinish($request);
break;
default:
// 收到未知类型的事件
return Msg::returnErrMsg(MsgConstant::ERROR_UNKNOW_TYPE, '收到了未知类型的消息', $request);
break;
}
break;
// 文本消息
case 'text':
$data = self::text($request);
break;
// 图片消息
case 'image':
$data = self::image($request);
break;
// 语音消息
case 'voice':
$data = self::voice($request);
break;
// 视频消息
case 'video':
$data = self::video($request);
break;
// 小视频消息
case 'shortvideo':
$data = self::shortvideo($request);
break;
// 地理位置消息
case 'location':
$data = self::location($request);
break;
// 链接消息
case 'link':
$data = self::link($request);
break;
default:
// 收到未知类型的消息
return ResponsePassive::text($request['fromusername'], $request['tousername'], '收到未知的消息,我不知道怎么处理');
break;
}
return $data;
}
// ... 其他方法 ...
}

@ -0,0 +1,153 @@
<?php
// 引入微信公众号操作类库
include 'lanewechat.php';
// 初始化主动响应的消息类型
$tousername = "用户和公众号兑换的OpenId"; // 接收方的OpenID
$mediaId = "通过上传多媒体文件得到的id。"; // 多媒体文件ID
// 发送文本消息
\LaneWeChat\Core\ResponseInitiative::text($tousername, '文本消息内容'); // 发送文本消息给指定用户
// 发送图片消息
\LaneWeChat\Core\ResponseInitiative::image($tousername, $mediaId); // 发送图片消息给指定用户
// 发送语音消息
\LaneWeChat\Core\ResponseInitiative::voice($tousername, $mediaId); // 发送语音消息给指定用户
// 发送视频消息
\LaneWeChat\Core\ResponseInitiative::video($tousername, $mediaId, '视频描述', '视频标题'); // 发送视频消息给指定用户
// 发送音乐消息
\LaneWeChat\Core\ResponseInitiative::music($tousername, '音乐标题', '音乐描述', '音乐链接', '高质量音乐链接WIFI环境优先使用该链接播放音乐', '缩略图的媒体id通过上传多媒体文件得到的id'); // 发送音乐消息给指定用户
// 初始化图文消息列表
$tuwenList = array();
$tuwenList[] = array('title'=>'标题1', 'description'=>'描述1', 'pic_url'=>'图片URL1', 'url'=>'点击跳转URL1');
$tuwenList[] = array('title'=>'标题2', 'description'=>'描述2', 'pic_url'=>'图片URL2', 'url'=>'点击跳转URL2');
// 将图文消息列表转换为图文消息项
$itemList = array();
foreach ($tuwenList as $tuwen) {
$itemList[] = \LaneWeChat\Core\ResponseInitiative::newsItem($tuwen['title'], $tuwen['description'], $tuwen['pic_url'], $tuwen['url']); // 将图文消息列表转换为图文消息项
}
// 发送图文消息
\LaneWeChat\Core\ResponseInitiative::news($tousername, $itemList); // 发送图文消息给指定用户
// 初始化被动响应的消息类型
$fromusername = "谁发给你的用户的openId"; // 发送方的OpenID
$tousername = "你的公众号Id"; // 接收方的公众号ID
// 发送被动响应的文本消息
\LaneWeChat\Core\ResponsePassive::text($fromusername, $tousername, '文本消息内容'); // 发送被动响应的文本消息
// 发送被动响应的图片消息
\LaneWeChat\Core\ResponsePassive::image($fromusername, $tousername, $mediaId); // 发送被动响应的图片消息
// 发送被动响应的语音消息
\LaneWeChat\Core\ResponsePassive::voice($fromusername, $tousername, $mediaId); // 发送被动响应的语音消息
// 发送被动响应的视频消息
\LaneWeChat\Core\ResponsePassive::video($fromusername, $tousername, $mediaId, '视频标题', '视频描述'); // 发送被动响应的视频消息
// 发送被动响应的音乐消息
\LaneWeChat\Core\ResponsePassive::music($fromusername, $tousername, '音乐标题', '音乐描述', '音乐链接', '高质量音乐链接WIFI环境优先使用该链接播放音乐', '缩略图的媒体id通过上传多媒体文件得到的id'); // 发送被动响应的音乐消息
// 初始化图文消息列表
$tuwenList = array();
$tuwenList[] = array('title'=>'标题1', 'description'=>'描述1', 'pic_url'=>'图片URL1', 'url'=>'点击跳转URL1');
$tuwenList[] = array('title'=>'标题2', 'description'=>'描述2', 'pic_url'=>'图片URL2', 'url'=>'点击跳转URL2');
// 将图文消息列表转换为图文消息项
$itemList = array();
foreach($tuwenList as $tuwen){
$itemList[] = \LaneWeChat\Core\ResponsePassive::newsItem($tuwen['title'], $tuwen['description'], $tuwen['pic_url'], $tuwen['url']); // 将图文消息列表转换为图文消息项
}
// 发送被动响应的图文消息
\LaneWeChat\Core\ResponsePassive::news($fromusername, $tousername, $itemList); // 发送被动响应的图文消息
// 将消息转发到客服
\LaneWeChat\Core\ResponsePassive::forwardToCustomService($fromusername, $tousername); // 将消息转发到客服
// 用户管理相关操作
$openId = '用户和微信公众号的唯一ID';
// 创建分组
\LaneWeChat\Core\UserManage::createGroup('分组名'); // 创建一个新的用户分组
// 获取分组列表
\LaneWeChat\Core\UserManage::getGroupList(); // 获取所有用户分组列表
// 根据OpenID获取分组
\LaneWeChat\Core\UserManage::getGroupByOpenId($openId); // 根据OpenID获取用户所在的分组ID
// 修改分组名称
\LaneWeChat\Core\UserManage::editGroupName('分组Id', '新的组名'); // 修改用户分组的名称
// 修改用户分组
\LaneWeChat\Core\UserManage::editUserGroup($openId, '新的分组ID'); // 将用户移动到另一个分组
// 获取用户信息
\LaneWeChat\Core\UserManage::getUserInfo($openId); // 获取用户的详细信息
// 获取粉丝列表
\LaneWeChat\Core\UserManage::getFansList($next_openId=''); // 获取公众号粉丝列表
// 设置用户备注名
\LaneWeChat\Core\UserManage::setRemark($openId, '新昵称'); // 设置用户的备注名
// 获取网络状态
\LaneWeChat\Core\UserManage::getNetworkState(); // 获取网络状态
// 微信OAuth授权相关操作
$redirect_uri = '获取CODE时发送请求和参数给微信服务器微信服务器会处理后将跳转到本参数指定的URL页面';
// 获取CODE
\LaneWeChat\Core\WeChatOAuth::getCode($redirect_uri, $state=1, $scope='snsapi_base'); // 获取微信授权的CODE
// 通过CODE获取Access Token和OpenID
$code = $_GET['code'];
\LaneWeChat\Core\WeChatOAuth::getAccessTokenAndOpenId($code); // 通过授权码获取access_token和openid
// 多媒体文件操作
$filename = '要上传的文件路径';
$type = '文件类型';
// 上传多媒体文件
\LaneWeChat\Core\Media::upload($filename, $type); // 上传多媒体文件
// 下载多媒体文件
\LaneWeChat\Core\Media::download($mediaId); // 下载多媒体文件
// 菜单操作
$menuList = array(
// 菜单项数组
);
// 设置菜单
\LaneWeChat\Core\Menu::setMenu($menuList); // 设置自定义菜单
// 获取菜单
\LaneWeChat\Core\Menu::getMenu(); // 获取当前公众号的自定义菜单
// 删除菜单
\LaneWeChat\Core\Menu::delMenu(); // 删除当前公众号的自定义菜单
// 高级群发操作
$fansList = \LaneWeChat\Core\UserManage::getFansList();
// 上传多媒体文件获取mediaId
$menuId = \LaneWeChat\Core\Media::upload('/var/www/baidu_jgylogo3.jpg', 'image');
if (empty($menuId['media_id'])) {
die('error');
}
// 准备图文消息列表
$list = array();
$list[] = array('thumb_media_id'=>$menuId['media_id'] , 'author'=>'作者', 'title'=>'标题', 'content_source_url'=>'www.lanecn.com', 'digest'=>'摘要', 'show_cover_pic'=>'1');
$list[] = array('thumb_media_id'=>$menuId['media_id'] , 'author'=>'作者', 'title'=>'标题', 'content_source_url'=>'www.lanecn.com', 'digest'=>'摘要', 'show_cover_pic'=>'0');
$list[] = array('thumb_media_id'=>$menuId['media_id'] , 'author'=>'作者', 'title'=>'标题', 'content_source_url'=>'www.lanecn.com', 'digest'=>'摘要', 'show_cover_pic'=>'0');
// 上传图文消息
$mediaId = \LaneWeChat\Core\AdvancedBroadcast::uploadNews($list); // 上传图文消息
// 根据粉丝OpenID群发图文消息
$result = \LaneWeChat\Core\AdvancedBroadcast::sentNewsByOpenId($fansList['data']['openid'], $mediaId); // 根据粉丝OpenID群发图文消息
引入类库include 'lanewechat.php'; 引入微信公众号操作类库。
主动响应消息:使用 ResponseInitiative 类发送各种类型的主动

@ -0,0 +1,15 @@
<?php
namespace LaneWeChat;
session_start();
//引入配置文件
include_once __DIR__.'/config.php';
//引入自动载入函数
include_once __DIR__.'/autoloader.php';
//调用自动载入函数
AutoLoader::register();
命名空间声明namespace LaneWeChat\Core; 定义了类的命名空间表明这个类属于LaneWeChat模块的核心部分。
类定义class Menu 定义了一个用于管理微信自定义菜单的类。
setMenu方法用于创建自定义菜单。处理菜单数据将一维数组转换为树形结构支持子菜单并发送POST请求到微信服务器。
getMenu方法用于获取当前公众号的自定义菜单信息。发送GET请求到微信服务器。
delMenu方法用于删除当前公众号的自定义菜单。发送GET请求到微信服务器

@ -0,0 +1,22 @@
<?php
// 定义命名空间,用于组织代码
namespace LaneWeChat;
// 引入Wechat类该类位于Core命名空间下用于处理微信相关功能
use LaneWeChat\Core\Wechat;
// 引入配置文件
include_once __DIR__ . '/config.php'; // 引入配置文件,加载系统配置
// 引入自动加载器文件
include_once __DIR__ . '/autoloader.php'; // 引入自动加载器文件,用于自动加载类文件
// 注册自动加载器,这样可以自动加载所需的类文件
AutoLoader::register(); // 注册自动加载器,以便在需要时自动加载类文件
// 创建WeChat类的实例传入WECHAT_TOKEN和调试模式参数
$wechat = new WeChat(WECHAT_TOKEN, TRUE); // 创建WeChat实例传入微信Token和调试模式参数
// 运行WeChat实例输出处理结果
echo $wechat->run(); // 运行WeChat实例处理微信请求并输出结果
Loading…
Cancel
Save