计算机网络/计算机科学与应用/系统/运维/开发

thinkphp5.1 服务号发送模版消息

<?php
namespace app\index\controller;
// 引入ThinkPHP的Session门面(根据你的TP版本调整,TP5/6通用)
use think\facade\Session;
// 引入配置类
use think\facade\Config;
// 引入日志类,方便调试
use think\facade\Log;
class Test
{
    /**
     * 发送微信模板消息
     * @param string $openid 接收消息用户的openid
     * @param array $data 模板消息所需数据(create_time/site/order_cate_id/remark等)
     * @return string 发送结果(成功/失败+原因)
     */
    public function test()
    {
// 这里是个人微信关注服务号之后产生的openid
$openid  = 'oQ3jZ0QZH62lk1zpYUax4u5EIDXg';
        // 1. 获取access_token
        $access_token2 = '';
        // 从Session获取缓存的token
        if (Session::has('access_token')) {
            $access_token2 = Session::get('access_token');
            Log::info('从Session获取缓存的access_token');
        } else {
            // 从配置获取appid和appsecret
            $appid = "wx002f60583b2b4ccc"; 
            $secret = "892f79805bed29b4ce2c9a67523b3ad1"; 
            
            if (empty($appid) || empty($secret)) {
                Log::error('模板消息发送失败:appid或appsecret未配置');
                return '发送失败:appid或appsecret未配置';
            }
            // 获取token的接口是GET请求
            $token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}";
            $json_token = $this->curl_request($token_url);
            
            if (empty($json_token)) {
                Log::error('模板消息发送失败:获取access_token接口返回为空');
                return '发送失败:获取access_token失败';
            }
            $access_token1 = json_decode($json_token, true);
            // 校验token返回结果
            if (json_last_error() !== JSON_ERROR_NONE) {
                Log::error('模板消息发送失败:access_token返回值解析失败,原始数据:'.$json_token);
                return '发送失败:access_token返回值解析失败';
            }
            if (isset($access_token1['errcode']) && $access_token1['errcode'] != 0) {
                Log::error('模板消息发送失败:获取access_token出错,错误码:'.$access_token1['errcode'].',错误信息:'.$access_token1['errmsg']);
                return '发送失败:'.$access_token1['errmsg'];
            }
            $access_token2 = $access_token1['access_token'] ?? '';
            if (empty($access_token2)) {
                Log::error('模板消息发送失败:access_token为空,原始返回:'.$json_token);
                return '发送失败:access_token获取为空';
            }
            // 缓存token到Session,有效期7200秒(2小时)
            Session::set('access_token', $access_token2, 7200);
            Log::info('成功获取新的access_token并缓存到Session');
        }
        // 2. 发送模板消息
        $json_template = $this->json_template($openid); 
        if (empty($json_template)) {
            return '发送失败:模板消息JSON构建失败';
        }
        $send_url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$access_token2}";
        // 模板消息发送是POST请求,传入JSON数据
        $res = $this->curl_request($send_url, $json_template, 'POST');
        
        if (empty($res)) {
            Log::error('模板消息发送失败:接口返回为空,access_token:'.$access_token2);
            return '发送失败:模板消息接口返回为空';
        }
        // 正确解析JSON返回结果
        $res_arr = json_decode($res, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            Log::error('模板消息发送失败:返回值解析失败,原始数据:'.$res);
            return '发送失败:返回值解析失败,原始数据:'.$res;
        }
        // 判断发送结果
        if (isset($res_arr['errcode']) && $res_arr['errcode'] == 0) {
            Log::info('模板消息发送成功,msgid:'.$res_arr['msgid']);
            return '发送成功';
        } else {
            $err_msg = $res_arr['errmsg'] ?? '未知错误';
            Log::error('模板消息发送失败:'.$err_msg.',错误码:'.$res_arr['errcode']);
            return '发送失败:'.$err_msg;
        }
    }
    /**
     * 构建模板消息的JSON数据
     * @param string $openid 用户openid
     * @param array $data 模板数据
     * @return string 格式化后的JSON字符串
     */
    public function json_template($openid)
    {
        $template_id = "PDO8VNR5oyJ5ocGhuenGNH3gngVXzb8AqmeTiHpGgC0"; 
        if (empty($template_id)) {
            Log::error('模板消息构建失败:template_id未配置');
            return '';
        }
        // 处理时间格式(确保create_time是时间戳)
        // $create_time = isset($data['create_time']) ? $data['create_time'] : time();
         $time = date("Y-m-d H:i:s"); 
        // 获取跳转链接
        $url = "pages/index/index";
        // 构建模板数据
        $template = [
            'touser' => "oQ3jZ0QZH62lk1zpYUax4u5EIDXg",
            'template_id' => $template_id,
            'url' => $url,
            'topcolor' => "#7B68EE",
            'data' => [
                'thing29' => ['value' => "用户名称", 'color' => "#FF0000"],
                'character_string2' => ['value' => '订单号', 'color' => '#FF0000'],
                'thing3' => ['value' =>$time, 'color' => '#FF0000'],
                'amount30' => ['value' => '订单金额', 'color' => '#FF0000'],
                'phone_number39' => ['value' =>'18328321035','color'=> '#FF0000'],
            ]
        ];
        // 生成JSON(确保中文不转义,JSON_UNESCAPED_UNICODE)
        $json_template = json_encode($template, JSON_UNESCAPED_UNICODE);
        if (json_last_error() !== JSON_ERROR_NONE) {
            Log::error('模板消息JSON构建失败:'.json_last_error_msg());
            return '';
        }
        return $json_template;
    }
    /**
     * 通用curl请求方法(支持GET/POST)
     * @param string $url 请求地址
     * @param string $post_data POST数据(JSON字符串)
     * @param string $method 请求方式(GET/POST)
     * @return string 接口返回数据
     */
    function curl_request($url, $post_data = '', $method = 'GET')
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 关闭SSL验证(生产环境建议开启,需配置CA证书)
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        // 设置超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        // POST请求处理
        if (strtoupper($method) == 'POST' && !empty($post_data)) {
            curl_setopt($ch, CURLOPT_POST, 1);
            // 设置POST数据格式为JSON
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($post_data)
            ]);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        }
        $output = curl_exec($ch);
        // 捕获curl错误
        if (curl_errno($ch)) {
            Log::error('CURL请求错误:'.curl_error($ch).',URL:'.$url);
            $output = '';
        }
        curl_close($ch);
        return $output;
    }
}


注意:小程序要关联服务号才行


// 商户的openid(接收通知的管理员微信openid)

'merchant_openid' => 'oQ3jZ0QZH62lk1zpYUax4u5EIDXg', // 我自己的

//'merchant_openid'=>'oQ3jZ0Q3b54aYVbLb-qf9wnDlVc0',  // 萌萌


所有的努力,不是为了让别人觉得你了不起,而是为了能让自己打心眼里看得起自己。

评论

^