微信JS-SDK——微信分享給朋友

    參考: 微信JS-SDK文檔 其中包含有分享朋友圈、發送給朋友的js接口方法。(彷佛不知道何時就會廢棄)
    文檔中有完整的步驟,麻煩的是第三步:經過config接口注入權限驗證配置。其中須要獲取 signature(簽名) ,必須經過服務器端才行。php

    本文主要是關於經過服務器獲取簽名的方法json

  受權須要獲取access_token,而後經過access_token取到jsapi_ticket再進行加密簽名。api

  微信公衆號獲取的access_token有兩種:網頁受權access_token、普通access_token,前者僅用於網頁端請求用戶受權,獲取用戶信息。後者則普遍用於微信各類接口。本文須要的就是後者:普通access_token。數組

  (另外備註一點:網頁受權獲取access_token是先獲取到(用戶贊成受權以後的)code,再根據code獲取access_token,而普通access_token直接經過appid、appsecret,請求一次就可得到)服務器

       主要是獲取access_token的,之後再用直接複製就行微信

<?php

class weixin{
    private $AppID = '';//自行填寫
    private $AppSecret = '';//自行填寫

    public $tokenFile = './wxtoken.txt';//保存token的文件,有效期2小時
    public $jsapiFile = './wxjsapi_ticket.txt';//保存 jsapi_ticket的文件,有限期2小時
    public $getTokenUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET';
    public $getjsapiUrl = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi';

    public function __construct(){
        $this->http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
    }

    public function index(){
      $action = isset($_GET['do']) ? $_GET['do'] : '';
      switch($action){
        case 'ApiJsSignature':
          $ret = $this->ApiJsSignature();//獲取分享須要的簽名等數據
          break;
        default:
          echo 'default';
          break;
      }
    }

    //用於微信分享到朋友圈或給朋友的參數
    public function ApiJsSignature(){
        $access_token = $this->get_access_token();
        $JsapiTicket = $this->get_jsapi_ticket($access_token);

        $signArr = array(
            'jsapi_ticket' => $JsapiTicket,
            'noncestr' => $this->str_rand(16),
            'timestamp' => time(),
            'url' => urldecode($_POST['jsapi_url'])
        );
        $signStr = 'jsapi_ticket='.$signArr['jsapi_ticket'].'&noncestr='.$signArr['noncestr'].'&timestamp='.$signArr['timestamp'].'&url='.$signArr['url'];
        //http_build_query()這個方法好像有問題,我使用以後返回的參數缺乏字符

        $signArr['signature'] = sha1($signStr);
        $signArr['appid'] = $this->AppID;
        echo json_encode($signArr);
    }


    //第二步獲取jsapi_ticket
    public function get_jsapi_ticket($access_token) {
        if(!file_exists($this->jsapiFile)) {
            $JsapiTicket = $this->resetJsapiTicket($access_token);
        }else{
            $fileContent=file_get_contents($this->jsapiFile);
            $ticketArr = json_decode($fileContent,true);
            if($ticketArr['expires_in'] < time()) {
                $JsapiTicket = $this->resetJsapiTicket($access_token);
            }else{
                $JsapiTicket = $ticketArr['ticket'];
            }
        }
        return $JsapiTicket;
    }
    public function resetJsapiTicket($access_token) {
        $url = str_replace('ACCESS_TOKEN', $access_token, $this->getjsapiUrl);

        $ticketJson = $this->curlPost($url);
        $ticketData = json_decode($ticketJson, true);

        $ticketData['expires_in'] = $ticketData['expires_in']+time();
        file_put_contents($this->jsapiFile, json_encode($ticketData));

        return $ticketData['ticket'];
    }

    //第一步獲取access_token
    public function get_access_token() {
        if(!file_exists($this->tokenFile)) {
            $access_token = $this->resetToken();//重置token並寫入文件 , 返回token值
        }else{
            $fileContent=file_get_contents($this->tokenFile);
            $tokenArr = json_decode($fileContent,true);
            if($tokenArr['expires_in'] < time()) {
                $access_token = $this->resetToken();
            }else{
                $access_token = $tokenArr['access_token'];
            }
        }
        return $access_token;
    }
    //刷新、重置token, 設置獲取token事件並將json數據寫入文件,最後返回token值,
    private function resetToken(){
        $url = str_replace('APPID', $this->AppID, $this->getTokenUrl);
        $url = str_replace('APPSECRET', $this->AppSecret, $url);

        $tokenJson = $this->curlPost($url);
        $tokenData = json_decode($tokenJson, true);

        $tokenData['expires_in'] = $tokenData['expires_in']+time();
        file_put_contents($this->tokenFile, json_encode($tokenData));

        return $tokenData['access_token'];
    }

    //生成隨機字符串
    public function str_rand($length = 32) {
        $char = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        if(!is_int($length) || $length < 0) {
            return false;
        }
        $string = '';
        for($i = $length; $i > 0; $i--) {
            $string .= $char[mt_rand(0, strlen($char) - 1)];
        }
        return $string;
    }

    //發送請求
    public function curlPost($url, $data = '') {
        if (! function_exists('curl_init')) {
            return '';
        }

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        // curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); // 可提交數組參數
        $data = curl_exec($ch);

        if (! $data) {
            error_log(curl_error($ch));
        }

        curl_close($ch);
        return $data;
    }
}

// 調用方式: index.php?do=ApiJsSignature
$weixin = new weixin();
$weixin->index();
相關文章
相關標籤/搜索