Tp5微信小程序模板消息,公众号模板消息,获取地理位置

 写了几个常用的微信接口,项目时间过于紧迫,未经整理,留待有空时再来整理或者扩展吧。

建议大家使用前,先去微信官方文档那边看一看,虽然微信的文档着实有点坑,但是总归还是能了解大概的业务逻辑以及找到一些排错手段来使用。

<?php
namespace think;
use think\Cache;
// 字符编码
header("Content-Type:text/html; charset=utf-8");

// 微信接口类
class Wechatmsg{
    private static $appid;//公众号appid
    private static $appsecret;//公众号secret
    private static $app_id;//小程序appid
    private static $app_secret;//小程序secret
    public function __construct()
    {

    }

    // 微信授权地址
    public static function getAuthorizeUrl($url){
        self::$appid = config('site.app_id')?config('site.app_id'):'';     // 开发者ID(AppID)
        self::$appsecret = config('site.app_secret')?config('site.app_secret'):'';  // 开发者密码(AppSecret)
        self::$app_id = config('site.miniapp_id')?config('site.miniapp_id'):'';     // 开发者ID(AppID)
        self::$app_secret = config('site.miniapp_secret')?config('site.miniapp_secret'):'';  // 开发者密码(AppSecret)
        $url_link = urlencode($url);
        return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . self::$appid . "&redirect_uri={$url_link}&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
    }

    // 获取TOKEN
    public static function getToken(){
        self::$appid = config('site.app_id')?config('site.app_id'):'';     // 开发者ID(AppID)
        self::$appsecret = config('site.app_secret')?config('site.app_secret'):'';  // 开发者密码(AppSecret)
        self::$app_id = config('site.miniapp_id')?config('site.miniapp_id'):'';     // 开发者ID(AppID)
        self::$app_secret = config('site.miniapp_secret')?config('site.miniapp_secret'):'';  // 开发者密码(AppSecret)
//        $urla = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . self::$appid . "&secret=" . self::$appsecret;
        $urla = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".config('site.app_id')."&secret=".config('site.app_secret');
        $outputa = self::curlGet($urla);
        $result = json_decode($outputa, true);
        return $result['access_token'];
    }
    // 获取TOKEN
    public static function get_Token(){
        self::$appid = config('site.app_id')?config('site.app_id'):'';     // 开发者ID(AppID)
        self::$appsecret = config('site.app_secret')?config('site.app_secret'):'';  // 开发者密码(AppSecret)
        self::$app_id = config('site.miniapp_id')?config('site.miniapp_id'):'';     // 开发者ID(AppID)
        self::$app_secret = config('site.miniapp_secret')?config('site.miniapp_secret'):'';  // 开发者密码(AppSecret)

        $urla = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . self::$app_id . "&secret=" . self::$app_secret;
        $outputa = self::curlGet($urla);
        $result = json_decode($outputa, true);
        return $result['access_token'];
    }
    /**
     * getUserInfo 获取用户信息
     * @param  string $code         微信授权code
     * @param  string $weiwei_token Token
     * @return array
     */
    public static function getUserInfo($code, $weiwei_token){
        self::$appid = config('site.app_id')?config('site.app_id'):'';     // 开发者ID(AppID)
        self::$appsecret = config('site.app_secret')?config('site.app_secret'):'';  // 开发者密码(AppSecret)
        self::$app_id = config('site.miniapp_id')?config('site.miniapp_id'):'';     // 开发者ID(AppID)
        self::$app_secret = config('site.miniapp_secret')?config('site.miniapp_secret'):'';  // 开发者密码(AppSecret)
        $access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . self::$appid . "&secret=" . self::$appsecret . "&code={$code}&grant_type=authorization_code";
        $access_token_json = self::curlGet($access_token_url);
        $access_token_array = json_decode($access_token_json, true);
        $openid = $access_token_array['openid'];
        $new_access_token = $weiwei_token;

        //全局access token获得用户基本信息
        $userinfo_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$new_access_token}&openid={$openid}";
        $userinfo_json = self::curlGet($userinfo_url);
        $userinfo_array = json_decode($userinfo_json, true);
        return $userinfo_array;
    }

    /**
     * pushMessage 发送自定义的模板消息
     * @param  array  $data          模板数据
    $data = [
    'openid' => '', 用户openid
    'url' => '', 跳转链接
    'template_id' => '', 模板id
    'data' => [ // 消息模板数据
    'first'    => ['value' => urlencode('黄旭辉'),'color' => "#743A3A"],
    'keyword1' => ['value' => urlencode('男'),'color'=>'blue'],
    'keyword2' => ['value' => urlencode('1993-10-23'),'color' => 'blue'],
    'remark'   => ['value' => urlencode('我的模板'),'color' => '#743A3A']
    ]
    ];
     * @param  string $topcolor 模板内容字体颜色,不填默认为黑色
     * @return array
     */
    public static function pushMessage($data = [],$topcolor = '#0000',$code=''){
        $weiwei_token = self::getToken(); // 获取微信token
//        $user_info = self::getUserInfo($code, $weiwei_token);
//        $openid = $user_info['openid'];
        $template = [
            'touser'      => $data['openid'],
            'template_id' => $data['template_id'],
            'pagepath'         => $data['url'],
            'topcolor'    => $topcolor,
            'data'        => $data['data']
        ];
        $json_template = json_encode($template);
        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $weiwei_token;
        $result = self::curlPost($url, urldecode($json_template));
        $resultData = json_decode($result, true);
        return $resultData;
    }
    /*
     * 小程序发送模板消息
     * */
    public static function send_msg($data = []){
        $weiwei_token = self::get_Token(); // 获取微信token
        $template = [
            'touser'      => $data['openid'],
            'template_id' => $data['template_id'],
            'page'         => $data['page'],
            'data'        => $data['data']
        ];
        $json_template = json_encode($template);
        $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" . $weiwei_token;
        $result = self::curlPost($url, urldecode($json_template));
        $resultData = json_decode($result, true);
        return $resultData;
    }
    /*
     * 发送站内信
     * */
    public static function send_message($id='',$touser='',$fromuser=1,$type=''){
        $msgtemplate = Db('msgtemplate')->where(array('id' => $id))->find();
        $data['createtime'] = $data['updatetime'] = time();
        $data['title'] = $msgtemplate['name'];
        $data['content'] = $msgtemplate['content'];
        $data['touser'] = $touser;
        $data['fromuser'] = $fromuser;
        $data['type'] = $type;
        $data['temid'] = $id;
        $data['image'] = $msgtemplate['image'];
        if(Db('message')->insert($data)){
            return true;
        }else{
            return false;
        }
    }
    /*
     * 是否关注
     * */
    public static function can_push(){
        $access_token = self::getToken(); // 获取微信token
        var_dump($access_token);
        $subscribe_msg = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$access_token.'&openid=oifrh1QtOleXgUwheISByEgaI_Fo';
        $subscribe = json_decode(self::curlGet($subscribe_msg));var_dump($subscribe);
    }
    /**
     * addLog 日志记录
     * @param string $log_content 日志内容
     */
    public static function addLog($log_content = ''){
        $data = "";
        $data .= "DATE: [ " . date('Y-m-d H:i:s') . " ]\r\n";
        $data .= "INFO: " . $log_content . "\r\n\r\n";
        file_put_contents('/wechat.log', $data, FILE_APPEND);
    }

    /**
     * 发送get请求
     * @param string $url 链接
     * @return bool|mixed
     */
    private static function curlGet($url){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        if(curl_errno($curl)){
            return 'ERROR ' . curl_error($curl);
        }
        curl_close($curl);
        return $output;
    }

    /**
     * 发送post请求
     * @param string $url 链接
     * @param string $data 数据
     * @return bool|mixed
     */
    private static function curlPost($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;
    }
    public static function getSignPackage($url='') {
        $appId = config('site.app_id')?config('site.app_id'):'';     // 开发者ID(AppID)
        $appSecret = config('site.app_secret')?config('site.app_secret'):'';  // 开发者密码(AppSecret)
        $jsapiTicket = self::getJsApiTicket($appId,$appSecret);
        // 注意 URL 一定要动态获取,不能 hardcode.
//        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
//        $url = "{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";

        $timestamp = time();
        $nonceStr = self::createNonceStr();
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket={$jsapiTicket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
//var_dump($url);
//        var_dump($string);
        $signature = sha1($string);
        // var_dump($signature);die;
        $signPackage = array(
            "nonceStr"  => $nonceStr,
            "timestamp" => $timestamp,
            "url"       => $url,
            "signature" => $signature,
            "rawString" => $string
        );
        return $signPackage;
    }

    public static function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    public static function getJsApiTicket($appId,$appSecret) {
        // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
        $jsapi_ticket = Cache::get('jsapi_ticket'.$appId);
        if(!$jsapi_ticket || empty($jsapi_ticket)){
            $accessToken = self::getAccessToken($appId,$appSecret);
            // 如果是企业号用以下 URL 获取 ticket
            // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$accessToken}";
            $res = json_decode(self::httpGet($url));
            $ticket = $res->ticket;
            $jsapi_tickets['expire_time'] = time() + 7000;
            $jsapi_tickets['jsapi_ticket'] = $ticket;
            Cache::set('jsapi_ticket'.$appId,$jsapi_tickets);
        }else{
            if($jsapi_ticket['expire_time'] <= time()){//缓存失效
                $accessToken = self::getAccessToken($appId,$appSecret);
                // 如果是企业号用以下 URL 获取 ticket
                // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
                $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$accessToken}";
                $res = json_decode(self::httpGet($url));
                $ticket = $res->ticket;
                $jsapi_tickets['expire_time'] = time() + 7000;
                $jsapi_tickets['jsapi_ticket'] = $ticket;
                Cache::set('jsapi_ticket'.$appId,$jsapi_tickets);
            }else{
                $jsapi_tickets = $jsapi_ticket;
            }
        }
//        $accessToken = self::getAccessToken($appId,$appSecret);
//        // 如果是企业号用以下 URL 获取 ticket
//        // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
//        $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$accessToken}";
//        $res = json_decode(self::httpGet($url));
//        $ticket = $res->ticket;
//        $jsapi_tickets['expire_time'] = time() + 7000;
//        $jsapi_tickets['jsapi_ticket'] = $ticket;
//        Cache::set('jsapi_ticket'.$appId,$jsapi_tickets);
        return $jsapi_tickets['jsapi_ticket'];
    }

    public static function getAccessToken($appId,$appSecret) {
        // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = Cache::get('access_token'.$appId);
        if(!$data || empty($data)){
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
            $res = json_decode(self::httpGet($url));
            $access_token = $res->access_token;
            $datas['expire_time'] = time() + 7000;
            $datas['access_token'] = $access_token;
            Cache::set('access_token'.$appId,$datas);
        }else{
            if($data['expire_time'] <= time()){//缓存失效
                $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
                $res = json_decode(self::httpGet($url));
                $access_token = $res->access_token;
                $datas['expire_time'] = time() + 7000;
                $datas['access_token'] = $access_token;
                Cache::set('access_token'.$appId,$datas);
            }else{
                $datas = $data;
            }
        }
//        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
//        $res = json_decode(self::httpGet($url));
//        $access_token = $res->access_token;
//        $datas['expire_time'] = time() + 7000;
//        $datas['access_token'] = $access_token;
//        Cache::set('access_token'.$appId,$datas);
        return $datas['access_token'];
    }

    public static function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }
}

 使用方式:

//引入微信操作类

use think\Wechatmsg;

//发送小程序模板消息

$data['openid'] = '你的微信小程序appid';
        $data['template_id'] = '小程序模板id';
        $data['page'] = '需要跳转的小程序页面路径';
        $data['data'] = array(
            'keyword1' => array("value" => '123', "color" => "#4a4a4a"),
            'phrase1' => array("value" => '审核'),
            'thing2' => array("value" => '审核结果'),
            'date3' => array("value" => date('Y-m-d', time())),
            'date4' => array("value" => date('Y-m-d', time())),
            'thing7' => array("value" => '审核结果'),
        );
        WeChatmsg::send_msg($data);

//发送公众号模板消息

$data['openid'] = '你的公众号appid';
        $data['template_id'] = '你的公众号模板id';
        $data['url'] = '需要跳转的路径';
        $data['data'] = array(
            'keyword1' => array("value" => date('Y-m-d', time()), "color" => "#4a4a4a"),//提现时间
            'keyword2' => array("value" => date('Y-m-d', time())),//到账时间
            'keyword3' => array("value" => 100),//到账金额
            'keyword4' => array("value" => 111),//账户余额
            'remark' => array('value' => '测试推送')
        );
        WeChatmsg::pushMessage($data);

//获取地理位置

//此处要说明一下,后端的微信地理位置的获取并不能直接获取到地址,只是获取到前端所需的jsapi_ticket和签名等信息,前端拿到后再请求微信接口即可拿到经纬度信息。注意:拿到jsapi_ticket和access_token的时候,一定要做缓存的操作,这两个东西微信都有调用次数限制,微信那边的有效时长为7200s,本地可根据此时间做一定的缓存操作。

//$url指的是当前页面所在地址,具体是使用后端动态获取还是由前端传入,要看具体项目情况,我使用的是前端传入的方式,之所以使用了urldecode是因为项目过程中发生了个奇怪现象,url在传输过程中出现了被转义的情况,使用时根据自己的情况选择一下就OK。


Wechatmsg::getSignPackage(urldecode($url))
总结:
第一、以上代码亲测可用
第二、细看文档
第三、相信微信,出问题了绝对是自己的锅
第四、相信微信,出问题了绝对是自己的锅
第五、相信微信,出问题了绝对是自己的锅
重要的事情说三遍。
出现报错的时候不要慌,报错复制出来百度,或者去微信官方文档查看错误代码,我在调试过程中调用以上代码时也是报错无数,但每次都是我背锅,不是微信小程序或者公众号配置有问题,就是签名或者其他奇葩的地方有问题
最后,微信真坑。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值