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))
總結:
第一、以上代碼親測可用
第二、細看文檔
第三、相信微信,出問題了絕對是自己的鍋
第四、相信微信,出問題了絕對是自己的鍋
第五、相信微信,出問題了絕對是自己的鍋
重要的事情說三遍。
出現報錯的時候不要慌,報錯複製出來百度,或者去微信官方文檔查看錯誤代碼,我在調試過程中調用以上代碼時也是報錯無數,但每次都是我背鍋,不是微信小程序或者公衆號配置有問題,就是簽名或者其他奇葩的地方有問題
最後,微信真坑。
發佈了11 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章