后端即时通讯【免费下载链接】easywechat 一个 PHP 微信 SDK项目地址https://gitcode.com/gh_mirrors/ea/easywechat点击查看免费下载本文基于 EasyWeChat 6.x 官方文档 公众号模块索引 编写。公众号Official Account模块是 EasyWeChat 中最常用的模块之一用于对接微信公众号的消息推送、服务端验证、网页授权、素材与客服消息等能力。读完本文你将掌握如何初始化Application工厂并配置核心参数、如何通过getServer()/getClient()/getAccessToken()等入口调用各子模块、如何理解服务端验证与消息加解密的签名校验逻辑以及如何结合仓库源码Application.php、AccessToken.php、Server.php排查配置问题。使用前建议先熟读微信官方《公众号》文档Overview 章节本文所有配置项与接口行为均以当前仓库 6.x 源码为准。一、最小可用的初始化配置公众号模块的常用配置参数其实很少——除非你有特别的定制需求例如自定义 OAuth 回调、自定义 HTTP 重试策略、使用 Stable Access Token否则大部分参数使用默认值即可。以下是最小可用配置use EasyWeChat\OfficialAccount\Application; $config [ app_id wx3cf0f39249eb0exx, secret f1c242f4f28f735d4687abb469072axx, token easywechat, aes_key , // 明文模式请勿填写 EncodingAESKey /** * OAuth 配置 * * scopes公众平台snsapi_userinfo / snsapi_base开放平台snsapi_login * redirect_urlOAuth授权完成后的回调页地址 */ oauth [ scopes [snsapi_userinfo], redirect_url /examples/oauth_callback.php, ], /** * 接口请求相关配置超时时间等 */ http [ timeout 5.0, // base_uri https://api.weixin.qq.com/, // 如果你在国外想要覆盖默认的 url 的时候才使用 retry true, // 使用默认重试配置 // retry [ // // 仅以下状态码重试 // status_codes [429, 500], // // 最大重试次数 // max_retries 3, // // 请求间隔 (毫秒) // delay 1000, // // 如果设置每次重试的等待时间都会增加这个系数 // // (例如. 首次:1000ms; 第二次: 3 * 1000ms; etc.) // multiplier 3 // ], ], ]; $app new Application($config);app_id公众号 AppID必填。Config类将app_id声明为唯一必填键见 src/OfficialAccount/Config.php 的requiredKeys缺失会直接报错。secretAppSecret用于换取access_token。token服务端消息推送的签名校验依赖它必须填写。aes_keyEncodingAESKey。明文模式请留空兼容模式与安全模式下一定要填写。oauth网页授权配置scopes可选snsapi_userinfo/snsapi_base公众平台或snsapi_login开放平台。httpHTTP 请求配置支持timeout、base_uri、retry等。完整配置样例含require_encryption、use_stable_access_token等进阶项见 配置文档。文档明确建议用到啥就配置啥大部分默认值即可。二、Application统一工厂与子模块入口Application是一个工厂类所有子模块都从$app访问并且几乎每个模块都提供了 getter 和 setter 可自定义替换。它的完整接口定义在 src/OfficialAccount/Contracts/Application.php实现位于 src/OfficialAccount/Application.php。1. 服务端$app-getServer()服务端模块封装了消息推送接收、服务端验证echostr校验与消息加解密基于中间件模式处理推送$server $app-getServer();从源码看Application.phpgetServer()会基于当前请求、Encryptor、token 与require_encryption配置惰性创建Server实例只有配置了aes_key时才会注入加密器。$response $server-serve();serve()内部依次处理echostr验证、请求签名校验、密文解密与中间件链最终返回一个Psr\Http\Message\ResponseInterface实例。关于中间件注册、消息监听与完整示例详见 服务端使用文档。2. API Client$app-getClient()封装了多种模式的 API 调用类默认自动处理access_token注入、过期自动刷新等逻辑$client $app-getClient();从源码看Application.phpcreateClient()会先基于http配置构建底层 HttpClient默认base_uri为https://api.weixin.qq.com/若http.retry为 true则包装为RetryableHttpClient并绑定AccessTokenExpiredRetryStrategy再包装为AccessTokenAwareClient并将errcode ! 0视为失败判定实现 access_token 过期错误码 42001时的自动刷新重试。更完整的用法GET/POST、上传、下载、异步请求等见 API 调用文档。3. 配置$app-getConfig()$config $app-getConfig();你可以用$config-get($key, $default)读取配置或在调用前用$config-set($key, $value)修改配置项。例如运行时临时改 OAuth 回调地址$app-getConfig()-set(oauth.redirect_url, /my-callback.php);4. AccessToken$app-getAccessToken()access_token是调用公众号 API 的必备凭证。手动获取$accessToken $app-getAccessToken(); $accessToken-getToken(); // string也可以注入自定义 AccessToken 类$accessToken new MyCustomAccessToken(); $app-setAccessToken($accessToken);5. 网页授权$app-getOAuth()$oauth $app-getOAuth();getOAuth()基于oauth.scopes与oauth.redirect_url配置创建 Overtrue Socialite 的 WeChat ProviderApplication.php。详情参考 网页授权文档。6. 公众号账户$app-getAccount()公众号账户类提供一系列 getter 获取基本信息$account $app-getAccount(); $account-getAppId(); $account-getSecret(); $account-getToken(); $account-getAesKey();对应实现见 src/OfficialAccount/Account.phpgetSecret()在未配置时会抛出RuntimeExceptiongetToken()/getAesKey()允许为 null明文模式。7. 其他内置模块$app-getEncryptor()消息加解密器基于tokenaes_key构建Application.php。$app-getTicket()JsApiTicket用于 JSSDK 签名。$app-getUtils()工具类例如buildJsSdkConfig()一键生成 JSSDK 配置Utils.php。$app-getCache()/$app-getHttpClient()缓存与底层 HTTP 客户端默认分别为 Symfony FilesystemAdapter 与 HttpClient::create。上述 getter/setter 的行为均有对应的单元测试验证见 tests/OfficialAccount/ApplicationTest.phptest_get_and_set_account、test_get_and_set_server、test_get_and_set_access_token、test_get_and_set_ticket等。三、进阶配置项深入解析以下配置项来自 配置文档默认值已标注。配置项默认值说明app_id无必填AppID缺失时 Config 直接抛错secret无AppSecrettoken无消息推送签名校验 Token必填aes_key空字符串EncodingAESKey兼容/安全模式必填require_encryptionfalse设为 true 时服务端拒绝一切明文推送use_stable_access_tokenfalse是否使用 Stable Access Token 接口oauth.scopes[snsapi_userinfo]授权范围oauth.redirect_url无OAuth 回调地址http.timeout5.0请求超时秒http.base_urihttps://api.weixin.qq.com/接口基地址海外部署时可覆盖http.retryfalse是否启用重试可为布尔值或数组http.max_retries2重试次数上限http.throwtrue请求失败是否抛异常1.require_encryption只接受加密推送公众号后台设为「安全模式」时建议将require_encryption设为true。开启后服务端将拒绝一切明文推送的消息即使其 signature 校验通过从而在 token 泄露时也能防止攻击者伪造明文消息。实现见 Server.php加密请求走decryptRequestMessage()解密非加密请求若requireEncryption为 true 则抛出BadRequestException。2.use_stable_access_token使用 Stable Access Token默认false。设为true后AccessToken::refresh()会调用getStableAccessToken()请求https://api.weixin.qq.com/cgi-bin/stable_token接口AccessToken.php否则走传统cgi-bin/token接口AccessToken.php。Stable Access Token 适用于需要更稳定凭证、希望减少主动刷新次数的场景。3.http.retry重试策略retry支持布尔值或数组两种形态true使用默认重试配置数组可精确控制status_codes仅对哪些状态码重试如[429, 500]、max_retries最大重试次数、delay请求间隔毫秒、multiplier指数退避系数每次重试等待时间乘以该系数。重试策略由getRetryStrategy()构建Application.php并额外判断响应内容中是否出现错误码42001access_token expired——即 access_token 过期时也会触发自动刷新并重试这是 SDK 处理 token 失效的底层机制。四、服务端验证、加解密与中间件核心实操服务端是公众号模块最核心的入口。完整参考 服务端使用文档以下提炼关键点。1. 服务端验证SDK 内置了echostr验证逻辑你不需要关心如何拼签名、返回echostr$server $app-getServer(); return $server-serve();serve()会校验请求的signaturetoken、timestamp、nonce三者排序后 sha1校验通过则原样返回echostr。$response是Psr\Http\Message\ResponseInterface实现请自行适配你的框架。若使用 ThinkPHP、Workerman 等框架需先把框架请求转换成 Symfony 请求再通过$app-setRequestFromSymfonyRequest($symfonyRequest)替换 request 对象然后再调用getServer()。2. 消息校验与加解密6.20.0serve()与getDecryptedMessage()会强制校验每一个请求的签名校验不通过时抛出EasyWeChat\Kernel\Exceptions\BadRequestException推送形态校验方式带密文encrypt_typeaes或消息体含Encrypt节点且配置了aes_key校验msg_signature并解密缺失或不匹配即拒绝纯明文校验signaturetoken、timestamp、nonce 三者排序后 sha1纯明文且配置了require_encryption true直接拒绝因此token必须正确配置否则抛出InvalidConfigException。手动实例化Server而非通过$app-getServer()时请记得显式传入 tokenuse EasyWeChat\OfficialAccount\Server; $server new Server( request: $request, encryptor: $encryptor, // 明文模式下可为 null token: your-token, requireEncryption: false, );如果公众号后台设置为「安全模式」强烈建议同时配置require_encryption true这样即使 token 泄露攻击者也无法通过明文推送伪造消息。加密请求的识别逻辑见 Server.php当 query 中encrypt_type aes或消息体含Encrypt/encrypt节点时判定为密文请求进而校验msg_signature并解密。3. 自助处理推送消息不要在返回$server-serve()前输出任何内容。获取原始推送消息$message $server-getRequestMessage(); // 原始消息获取解密后的消息6.5.0$message $server-getDecryptedMessage();$message为EasyWeChat\OfficialAccount\Message实例定义见 src/OfficialAccount/Message.php提供MsgType、Event等属性。4. 中间件模式服务端使用中间件链依次调用开发者注册的中间件处理完逻辑后可以回复消息或交给下一个中间件$server-with(function($message, \Closure $next) { // 你的自定义逻辑 return $next($message); }); $response $server-serve();可链式注册多个中间件$server -with(function($message, \Closure $next) { // 你的自定义逻辑1 return $next($message); }) -with(function($message, \Closure $next) { // 你的自定义逻辑2 return $next($message); }) -with(function($message, \Closure $next) { // 你的自定义逻辑3 return $next($message); }); $response $server-serve();回复消息当中间件不回复消息时调用$next($message)传递给下一个中间件若需返回消息给用户直接返回字符串或数组即可function($message, \Closure $next) { return 感谢你使用 EasyWeChat; }注意回复消息后后续未执行的中间件将不再执行所以请将全局都需要执行的中间件优先提前注册。回复图片等多媒体消息参考微信官方「被动回复消息」的 XML 结构以数组形式返回需省略ToUserName、FromUserName、CreateTimefunction($message, \Closure $next) { return [ MsgType image, Image [ MediaId media_id, ], ]; }多条消息服务端只能被动回复一条消息若需发送多条请调用微信客服消息接口对应 JSON 结构见下文消息结构一节。使用独立中间件类中间件支持可调用对象与类名class MyCustomHandler { public function __invoke($message, \Closure $next) { if ($message-MsgType text) { //... } return $next($message); } } $server-with(MyCustomHandler::class); // 或者 $server-with(new MyCustomHandler());使用 callable 类型中间件支持函数名、[$class, $method]、ClassName::method等 callable 形式$server-with([$object, method]); $server-with(ClassName::method);5. 便捷监听按消息类型 / 事件类型注册addMessageListener匹配MsgType字段例如文本消息$server-addMessageListener(text, function() { ... });addEventListener匹配Event字段例如关注事件$server-addEventListener(subscribe, function() { ... });对应实现见 Server.php它们本质上是帮你包了一层按字段匹配的中间件。6. 完整示例use EasyWeChat\OfficialAccount\Application; $config [...]; $app new Application($config); $server $app-getServer(); $server-addEventListener(subscribe, function($message, \Closure $next) { return 感谢您关注 EasyWeChat!; }); $response $server-serve(); return $response;五、消息结构速查服务端 XML vs 客服消息 JSON公众号消息分为服务端被动回复消息XML与客服消息JSON两个场景结构类似但命名有差异使用时请勿混淆详见 消息文档。1. 服务端请求消息XML基本属性所有消息均包含- ToUserName 接收方帐号该公众号 ID - FromUserName 发送方帐号OpenID代表用户的唯一标识 - CreateTime 消息创建时间时间戳 - MsgId 消息 ID64位整型按MsgType细分文本Content文本消息内容图片MediaId媒体id、PicUrl图片链接语音MediaId、Format如 amr、speex、Recognition开通语音识别后才有视频MediaId、ThumbMediaId缩略图媒体id小视频MsgType shortvideo、MediaId、ThumbMediaId事件MsgType event、Event如 subscribe、unsubscribe、CLICK 等扫描带参数二维码EventKey如qrscene_123123、Ticket上报地理位置Latitude、Longitude、Precision自定义菜单EventKey对应菜单 KEY 值或 URL地理位置Location_X、Location_Y、Scale、Label链接Title、Description、Url文件Title、Description、FileKey、FileMd5、FileTotalLen字节2. 客服消息JSON结构客服消息通过 API 主动发送给用户常用的几种// 文本 { touser: OPENID, msgtype: text, text: { content: Hello World } } // 图片 { touser: OPENID, msgtype: image, image: { media_id: MEDIA_ID } } // 语音 { touser: OPENID, msgtype: voice, voice: { media_id: MEDIA_ID } } // 视频 { touser: OPENID, msgtype: video, video: { media_id: MEDIA_ID, thumb_media_id: MEDIA_ID, title: TITLE, description: DESCRIPTION } } // 音乐 { touser: OPENID, msgtype: music, music: { title: MUSIC_TITLE, description: MUSIC_DESCRIPTION, musicurl: MUSIC_URL, hqmusicurl: HQ_MUSIC_URL, thumb_media_id: THUMB_MEDIA_ID } } // 图文跳转外链 { touser: OPENID, msgtype: news, news: { articles: [ { title: Happy Day, description: Is Really A Happy Day, url: URL, picurl: PIC_URL } ]} } // 图文跳转图文消息页面 { touser: OPENID, msgtype: mpnews, mpnews: { media_id: MEDIA_ID } } // 菜单消息 { touser: OPENID, msgtype: msgmenu, msgmenu: { head_content: 您对本次服务是否满意呢? , list: [ { id: 101, content: 满意 }, { id: 102, content: 不满意 } ], tail_content: 欢迎再次光临 } } // 卡券消息 { touser: OPENID, msgtype: wxcard, wxcard: { card_id: 123dsdajkasd231jhksad } }客服消息的具体发送方式通过getClient()调用message/custom/send接口请结合 API 调用文档 使用消息结构以微信官方文档为准。六、源码级验证这些行为如何被测试保障当前仓库对上述模块行为提供了完整的单元测试可作为配置与调用的活文档tests/OfficialAccount/ApplicationTest.php验证getAccount()/getServer()/getAccessToken()/getTicket()等 getter 的惰性创建与 setter 替换行为并验证无http配置时getClient()不会抛异常对应 issue #2743 回归测试。tests/OfficialAccount/ServerTest.php验证服务端验证、消息解密与中间件链路。tests/OfficialAccount/AccessTokenTest.php验证 access_token 的缓存读写与刷新逻辑。tests/OfficialAccount/ConfigTest.php验证app_id必填等配置约束。七、常见问题排查建议The token is required to validate the request signaturetoken未配置。确保config[token]已填写且与公众号后台「服务器配置」中的 Token 一致。服务端验证返回 401/校验失败检查签名校验所需的token、timestamp、nonce是否来自微信推送原样传递若框架改写了 query 参数请先通过setRequestFromSymfonyRequest()注入原始请求。安全模式下收到明文推送被拒这是require_encryption true的预期行为请确认公众号后台已切换为「安全模式」并正确配置aes_key。access_token 获取失败检查app_id/secret是否正确启用use_stable_access_token true时需确认接口权限。海外部署请求超时可通过http.base_uri覆盖默认的https://api.weixin.qq.com/并结合http.timeout、http.retry调整网络策略。更多框架集成Laravel、Symfony 等与缓存、自定义替换服务的说明请参考 安装文档、缓存配置 与 替换服务文档。赞分享后端即时通讯【免费下载链接】easywechat 一个 PHP 微信 SDK项目地址https://gitcode.com/gh_mirrors/ea/easywechat点击查看免费下载相关推荐KuboIPFS防火墙配置指南开放 Swarm 端口 4001 并验证节点可达性KuboIPFS防火墙配置指南开放 Swarm 端口 4001 并验证节点可达性 本篇指南以 KuboGo 语言实现的 IPFS 节点为对象系统讲解后端即时通讯EasyWeChat 4.x 公众号模块实战指南从初始化、配置到服务端与 OAuth 开发EasyWeChat 4.x 公众号模块实战指南从初始化、配置到服务端与 OAuth 开发 导读 本指南以 EasyWeChat 4.x 文档中「公众号」模块后端即时通讯如何快速检测微信单向好友3分钟找出谁删了你如何快速检测微信单向好友3分钟找出谁删了你 微信好友关系一键检测工具 WechatRealFriends 是一款基于微信iPad协议的开源解决方案专门帮助用后端即时通讯上一篇Renovate helm-requirements 管理器全指南自动更新 Helm v2 requirements.yaml 中的 Chart 依赖下一篇Megatron-LM 首次训练实战指南从最小分布式循环到 LLaMA-3 FP8 训练与数据预处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
