微信模板消息源码案例

112 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

微信模板消息源码案例

<?php

class sendMsg{
    private $appid = "你的appid";
    private $secret = "你的secret";

    public $template='';

    public function getAccessToken(){
        // 缓存文件名
        $file_path = "/access_token.txt";
        $str = '';
        if(is_file($file_path)) {
            $str = file_get_contents($file_path);//将整个文件内容读入到一个字符串中
            $str = str_replace("\r\n", "<br />", $str);
        }
        $data = json_decode($str); //转换为json格式

        if ($data->expire_time < time() or ! $data->expire_time) {

            //token过期的情况
            $temp_url = 'https://api.weixin.qq.com/cgi-bin/token?';
            $temp_url .= 'grant_type=client_credential';
            $temp_url .= '&appid='.$this->appid;
            $temp_url .= '&secret='.$this->secret;
            $res = $this->https_request($temp_url);
            $res = json_decode($res, true); // 对 JSON 格式的字符串进行编码
            $access_token = $res['access_token'];
            if ($access_token) {
                $data['expire_time'] = time() + 3600; //保存1小时
                $data['access_token'] = $access_token;
                $fp = fopen($file_path, "w"); //只写文件
                fwrite($fp, json_encode($data)); //写入json格式文件
                fclose($fp); //关闭连接
            }
        } else {
            $access_token = $data->access_token;
        }
        return $access_token;
    }


    /**
     * sendMsg constructor.
     * @param $touser   openid数组
     * @param $url      点击模板信息跳转地址
     * @param $template_id  模板id
     */
    public function sendMessage($touser,$url,$template_id){
        $access_token = $this->getAccessToken();
           //模板消息请求URL
        $wxurl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $access_token;
        //遍历发送微信消息
        foreach ($touser as $value) {
            $data = $this->getDataArray($value,$template_id,$url);
            $json_data = json_encode($data);//转化成json数组让微信可以接收
            $res_json = $this->https_request($wxurl, urldecode($json_data));//请求开始
            $res = json_decode($res_json, true);
            if ($res['errcode'] == 0 && $res['errcode'] == "ok") {
                //成功
                echo $res_json;
            }else{
                //失败
                echo $res_json;
            }
        }
    }

    /**
     * 获取发送数据数组
     * @param $value 用户openid
     * @param $template_id 模板id
     * @param $url  点击模板跳转地址
     * @return array  返回 支持微信接口的模板数据
     */
    function getDataArray($value,$template_id,$url)
    {

        $template =$this->template;
        $data = array(
            'touser' => $value, //要发送给用户的openid
            'template_id' => $template_id,//改成自己的模板id,在微信后台模板消息里查看
            'url' => $url, //自己网站链接url
            'data' =>$template
        );
        return $data;
    }

    public function updateTemplate($id){
        $this->template = $this->baseTemplate($id);
    }
    /**
     * 模板库
     * @param $id
     * @return mixed
     */
    public function baseTemplate($id){
        $data = array(
            //一个模板
            'tjJ4m-gtcTaMOh3GQuVKEj-OZcUBtEDmpaty4leJH9I'=> array(
                'first' => array(
                    'value' => "first value",
                    'color' => "#FFFFFF"//白色
                ),
                'keyword1' => array(
                    'value' => "keyword1 value",
                    'color' => "#FF0000"//红色
                ),
                'keyword2' => array(
                    'value' => "keyword2 value",
                    'color' => "#00FF00"//绿色
                ),
                'keyword3' => array(
                    'value' => "keyword3 value",
                    'color' => "#0000FF"//蓝色
                ),
                'remark' => array(
                    'value' => "\n remark value >>>",
                    'color' => "#FFFF00"//黄色
                ),
            ),
            //第二个模板
            'id'=> array(
                'first' => array(
                    'value' => "first value",
                    'color' => "#000"
                ),
                'keyword1' => array(
                    'value' => "keyword1 value",
                    'color' => "#f00"
                ),
                'keyword2' => array(
                    'value' => "keyword2 value",
                    'color' => "#173177"
                ),
                'keyword3' => array(
                    'value' => "keyword3 value",
                    'color' => "#3d3d3d"
                ),
                'remark' => array(
                    'value' => "\n remark value >>>",
                    'color' => "#3d3d3d"
                ),
            )
        );

        return $data[$id];
    }

    //curl请求函数,微信都是通过该函数请求
    function https_request($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

}



//这里是你要发送粉丝的openid
$touser = array('粉丝openid','粉丝openid');
//这个地址是点击消息跳转的页面
$url='';
$a = new sendMsg();
$template_id = '你的模板id';
//重构模板提示信息
$a->updateTemplate($template_id);
$a->template['first']['value'] = '恭喜您,您的预约审核通过!';
$a->template['keyword1']['value'] = '赵大夫';
$a->template['keyword2']['value'] = '2019年9月17日11:45';
$a->template['remark']['value'] = "\n 点击进入订单详细 >>>";
//发送
$a->sendMessage($touser,$url,$template_id);







?>

小程序统一下单

在这里插入图片描述

    //微信小程序接口
    private function weixinapp() {
        //统一下单接口
        $unifiedorder = $this->unifiedorder();
		file_put_contents(__DIR__.'/../../../make_order.json', json_encode($unifiedorder).PHP_EOL,FILE_APPEND);
        $parameters = array(
            'appId' => $this->appid, //小程序ID
            'timeStamp' => '' . time() . '', //时间戳
            'nonceStr' => $this->createNoncestr(), //随机串
            'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //数据包
            'signType' => 'MD5'//签名方式
        );
        //签名
        $parameters['paySign'] = $this->getSign($parameters);
        return $parameters;
    }

微信接口的sign算法

在这里插入图片描述

    //作用:生成签名
//以交互数据为例
<?php
/**
 * Created by PhpStorm.
 * User: zhaoxinglu
 * Date: 2018/12/14
 * Time: 14:08
 */
namespace App\Http\Controllers;


class CxorderController extends Controller
{
    public $key  = '192006250b4c09247ec02edce69f6a2d';//注:key为商户平台设置的密钥key

    public function test(){
        /*
        : wxd930ea5d5a258f4f
        mch_id: 10000100
        device_info: 1000
        body: test
        nonce_str: ibuaiVcKdpRxkhJA
          */
        //以交互数据为例
        $data = [
            'appid'=>'wxd930ea5d5a258f4f',
            'mch_id'=>'10000100',
            'device_info'=>'1000',
            'body'=>'test',
            'nonce_str'=>'ibuaiVcKdpRxkhJA'
        ];
        $obj = $this->arrayTransitionObject($data);
        $res = $this->getSign($obj);
        echo $res;
        exit;


    }
    private function getSign($Obj) {
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        //签名步骤一:按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);

        //签名步骤二:在string后加入KEY
        $String = $String . "&key=" . $this->key;
        //签名步骤三:MD5加密
        $String = md5($String);
        //签名步骤四:所有字符转为大写
        $result_ = strtoupper($String);
        return $result_;
    }

    ///作用:格式化参数,签名过程需要使用
    private function formatBizQueryParaMap($paraMap, $urlencode) {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar='';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }
    protected function arrayTransitionObject(Array $array)
    {
        if (is_array($array)) {
            $obj = new class{};
            foreach ($array as $key => $val) {
                $obj->$key = $val;
            }
        } else {
            $obj = $array;
        }
        return $obj;
    }
    }

////////////////////////////////////////////////////////////// 微信xml与数组互转


    /**
     * XML编码
     * @param mixed $data 数据
     * @param string $root 根节点名
     * @param string $item 数字索引的子节点名
     * @param string $attr 根节点属性
     * @param string $id   数字索引子节点key转换的属性名
     * @param string $encoding 数据编码
     * @return string
     */
    public function xml_encode($data, $root='xml', $item='item', $attr='', $id='id', $encoding='utf-8') {
        if(is_array($attr)){
            $_attr = array();
            foreach ($attr as $key => $value) {
                $_attr[] = "{$key}=\"{$value}\"";
            }
            $attr = implode(' ', $_attr);
        }
        $attr   = trim($attr);
        $attr   = empty($attr) ? '' : " {$attr}";
        $xml   = "<{$root}{$attr}>";
        $xml   .= self::data_to_xml($data, $item, $id);
        $xml   .= "</{$root}>";
        return $xml;
    }
    /**
     * 数据XML编码
     * @param mixed $data 数据
     * @return string
     */
    public static function data_to_xml($data) {
        $xml = '';
        foreach ($data as $key => $val) {
            is_numeric($key) && $key = "item id=\"$key\"";
            $xml    .=  "<$key>";
            $xml    .=  ( is_array($val) || is_object($val)) ? self::data_to_xml($val)  : self::xmlSafeStr($val);
            list($key, ) = explode(' ', $key);
            $xml    .=  "</$key>";
        }
        return $xml;
    }


    public static function xmlSafeStr($str)
    {
        return '<![CDATA['.preg_replace("/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]/",'',$str).']]>';
    }
    
    function xmlToArray($xml) {
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $arr;
    }


    /**
     * POST 请求
     * @param string $url
     * @param array $param
     * @return string content
     */
    function http_post($url,$param){
        $oCurl = curl_init();
        if(stripos($url,"https://")!==FALSE){
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
        }
        if (is_string($param)) {
            $strPOST = $param;
        } else {
            $aPOST = array();
            foreach($param as $key=>$val){
                $aPOST[] = $key."=".urlencode($val);
            }
            $strPOST =  join("&", $aPOST);
        }
        curl_setopt($oCurl, CURLOPT_URL, $url);
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt($oCurl, CURLOPT_POST,true);
        curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
        $sContent = curl_exec($oCurl);
        $aStatus = curl_getinfo($oCurl);
        curl_close($oCurl);
        if(intval($aStatus["http_code"])==200){
            return $sContent;
        }else{
            return false;
        }
    }

}

    
	///////////////////////////////////////////////////
	    //数组转换成xml
    private function arrayToXml($arr) {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_array($val)) {
                $xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
        }
        $xml .= "</xml>";
        //echo $xml;exit;
        return $xml;
    }


    //xml转换成数组
    private function xmlToArray($xml) {

        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $val = json_decode(json_encode($xmlstring), true);
        return $val;
    }