yunzer/app/index/controller/WechatController.php
2025-06-05 20:22:12 +08:00

165 lines
5.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\index\controller;
use think\facade\Request;
use think\facade\Log;
use think\facade\Cache;
class WechatController extends BaseController
{
public function index()
{
// 检查请求方法
if (Request::method() == 'GET') {
// 首次验证服务器地址的有效性
$this->checkSignature();
} elseif (Request::method() == 'POST') {
// 接收消息并回复
$response = $this->receiveMessage();
// 直接输出回复的XML字符串
echo $response;
exit;
}
}
// 验证签名
protected function checkSignature()
{
$signature = Request::get('signature');
$timestamp = Request::get('timestamp');
$nonce = Request::get('nonce');
$echostr = Request::get('echostr');
$token = "token2024";
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if ($tmpStr == $signature) {
echo $echostr;
exit;
}
}
// 接收消息
protected function receiveMessage()
{
$postStr = file_get_contents("php://input");
if (empty($postStr)) {
return '';
}
libxml_disable_entity_loader(true);
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
Log::write($postObj);
// 检查消息类型
$msgType = strtolower((string) $postObj->MsgType);
if ($msgType == 'text') {
// 提取消息内容
$fromUsername = (string) $postObj->FromUserName; // 微信用户openid
$toUsername = (string) $postObj->ToUserName; // 公众号id
$keyword = trim((string) $postObj->Content);
// 构造自动回复的文本消息
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
$responseContent = "消息标题";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $responseContent);
// 假设已经确定要发送小程序卡片消息
$this->sendMiniProgramCard((string) $postObj->FromUserName);
return $resultStr;
}
// 如果需要处理其他类型的消息,可以在这里添加相应的逻辑
// 如果不是文本消息,可以返回一个空字符串或错误消息
return '';
}
// 发送小程序卡片消息的方法
private function sendMiniProgramCard($openid)
{
$accessToken = $this->getGZHAccessToken();
if (!$accessToken) {
// 处理获取access_token失败的情况
return;
}
$postData = json_encode([
'touser' => $openid, // 接收者用户的openid
'msgtype' => 'miniprogrampage',
'miniprogrampage' => [
'title' => '小程序标题',
'appid' => '小程序appid',
'pagepath' => '小程序路径',
'thumb_media_id' => '你的thumb_media_id'
]
], JSON_UNESCAPED_UNICODE);
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$accessToken}";
$result = json_decode(file_get_contents($url, false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-type: application/json\r\n",
'content' => $postData,
'timeout' => 60 // 超时时间(单位:s
]
])), true);
// 处理返回结果
if ($result['errcode'] == 0) {
// 发送成功
} else {
// 发送失败
}
}
// 获取公众号Access token
public function getGZHAccessToken()
{
$access_token = Cache::get('gzh_access_token');
if (!$access_token) {
$config = [
'appid' => 'appid',
'secret' => 'secret',
'grant_type' => 'client_credential'
];
$response = $this->curlPost('https://api.weixin.qq.com/cgi-bin/token', $config);
$data = json_decode($response, true);
$access_token = $data["access_token"];
Cache::set('gzh_access_token', $access_token, $data["expires_in"] - 200);
}
return $access_token;
}
// 发送请求
public function curlPost($url = '', $postData = '', $options = array())
{
if (is_array($postData)) {
$postData = http_build_query($postData);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
if (!empty($options)) {
curl_setopt_array($ch, $options);
}
//https请求 不验证证书和host
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
}