ホームページ  >  記事  >  WeChat アプレット  >  PHP は WeChat SDK 共有インターフェイスを実装します

PHP は WeChat SDK 共有インターフェイスを実装します

小云云
小云云オリジナル
2018-03-16 14:10:395797ブラウズ

ソフトウェア開発キット (外国語の略語: SDK、外国語の正式名: Software Development Kit) は、一般に、一部のソフトウェア エンジニアが特定のソフトウェア パッケージ、ソフトウェア フレームワーク、ハードウェア プラットフォーム、オペレーティング システム、等。この記事では主に、PHP で WeChat SDK 共有インターフェイスを実装する方法について説明します。お役に立てれば幸いです。

<?php
class Wxsdk
{
    private $appId;
    private $appSecret;

    /*
     * 这里为威狮码的公众号的openid和appsecret,如果配置到其他的子商家会出现需要关注威狮码公众号,
     * 则需要获取数据库的vender表里面的openid和appsecret
     * */
    public function __construct($appId = &#39;自己的appid&#39;, $appSecret = &#39;自己的appSecret&#39;)
    {
        $this->appId = $appId;
        $this->appSecret = $appSecret;
    }


    public function getSignPackage(Request $request)
    {
//接收到前端的转义url转义回来
        $url = $_POST;
        $durl = $url[&#39;url&#39;];
        $durl = urldecode($durl);

        $jsapiTicket = $this->getJsApiTicket();
        $timestamp = time();
        $nonceStr = $this->createNonceStr();
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$durl";


        $signature = sha1($string);


        $signPackage = [
            "appId" => $this->appId,
            "nonceStr" => $nonceStr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $signature,
            "rawString" => $string
        ];
//        var_dump($signPackage);die;
        throw new SuccessMessage([&#39;msg&#39; => $signPackage]);
    }


    private 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;
    }


    private function getJsApiTicket()
    {
        // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents("jssdk/jsapi_ticket.json"));
        if ($data->expire_time < time()) {
            $accessToken = $this->getAccessToken();
            //定义传递的参数数组
            $params[&#39;type&#39;] = &#39;jsapi&#39;;
            $params[&#39;access_token&#39;] = $accessToken;
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $params[&#39;access_token&#39;] . "&type=" . $params[&#39;type&#39;] . "";
            $res = json_decode(curl_get($url, $params));
            $ticket = isset($res->ticket) ? $res->ticket : NULL;
            if ($ticket) {
                $res->expire_time = time() + 7000;
                $res->jsapi_ticket = $ticket;
                $fp = fopen("jssdk/jsapi_ticket.json", "w");
                fwrite($fp, json_encode($res));
                fclose($fp);
            }
        } else {
            $ticket = $data->jsapi_ticket;
        }
        return $ticket;
    }


    private function getAccessToken()
    {
        // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents("jssdk/access_token.json"));
        if ($data->expire_time < time()) {
            //定义传递的参数数组
            $params[&#39;grant_type&#39;] = &#39;client_credential&#39;;
            $params[&#39;appid&#39;] = $this->appId;
            $params[&#39;secret&#39;] = $this->appSecret;
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" . $params[&#39;grant_type&#39;] . "&appid=" . $params[&#39;appid&#39;] . "&secret=" . $params[&#39;secret&#39;] . "";
            $res = json_decode(curl_post($url, $params));
            $access_token = isset($res->access_token) ? $res->access_token : NULL;
            if ($access_token) {
                $res->expire_time = time() + 7000;
                $res->access_token = $access_token;
                $fp = fopen("jssdk/access_token.json", "w");
                fwrite($fp, json_encode($res));
                fclose($fp);
            }
        } else {
            $access_token = $data->access_token;
        }
        return $access_token;
    }
前端代码

公式の手順を確認し、署名アルゴリズムを確認してください。

  • 署名アルゴリズムが正しいことを確認します。検証には http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign ページ ツールを使用できます。

  • 設定内の nonceStr (js の標準的なキャメルケースの大文字 S) とタイムスタンプが、署名で使用されている対応する noncestr とタイムスタンプと一致していることを確認します。

  • URL が、「http(s)://」を含むページの完全な URL であることを確認します (現在のページのアラート(location.href.split('#')[0]) で確認してください) 「部分」と「?」 GETパラメータの'以降の部分ですが、'#'ハッシュ以降の部分は含みません。

  • config の appid が、jsapi_ticket の取得に使用された appid と一致していることを確認します。

  • access_tokenとjsapi_ticketを必ずキャッシュしてください。

  • 署名用に取得する URL が動的に取得されることを確認してください。動的ページについては、サンプル コードの PHP 実装を参照してください。 HTML の静的ページの場合、フロントエンドの ajax を介して署名のために URL がバックエンドに渡されます。フロントエンドは、「#」ハッシュ部分を除く現在のページのリンクを取得する必要があります。 location.href.split('#')[0] によって取得され、encodeURIComponent、バックグラウンドでの decodeURIComponent デコードが必要です)。これは、ページが共有されると、WeChat クライアントが現在のリンクの末尾に他のパラメーターを追加するためです。動的に取得されない場合、共有ページの署名は失敗します。

署名は正しいです。上記の手順で問題を解決できない場合 (無効な署名)、URL の問題を使用してください。 注: WeChat 公式アカウントは、デバッグした安全なドメイン名で構成する必要があります (2 番目のドメイン名を構成できます)。 -レベルのドメイン名: xxx.com を複数の a.xxx.com/b.xxx.com などで構成する代わりに。

理由: WeChat は、共有時に現在のページに複数のパラメーターを追加します。 sha1 を行うとき、URL アドレスが WeChat がパラメーターを追加した後のアドレスであることを確認する必要があります。そうすることで、config: 無効な署名が報告されません。

解決策: sha1 より前の URL は、デコード後に肉眼で直接認識できる通常の URL である必要があります。静的ページを使用している場合は、wx.config を構成する前に、最初に encodeURIComponent(location.href.split(') を渡します。 #')[0] ) 現在の URL エンコーディングをバックエンドに渡します。これは decodeURIComponent によってデコードされます。コア コードは次のとおりです:

フロントエンド HTML ページ、URL をエンコードします:

jQuery.post("/xxx", {"url": encodeURIComponent(window.location.href.split(&#39;#&#39;)[0]),"t": new Date().getTime()}, function (result) {
    if (result.errno != 0) {
        alert("您当前的网络不稳定请稍后再试!");
        return;
    }
    var shareUrl = result.data.url;
    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: &#39;xxx&#39;, // 必填,公众号的唯一标识
        timestamp: result.data.timestamp, // 必填,生成签名的时间戳
        nonceStr: result.data.nonceStr, // 必填,生成签名的随机串
        signature: result.data.signature,// 必填,签名,见附录1
        jsApiList: [&#39;onMenuShareAppMessage&#39;,&#39;onMenuShareTimeline&#39;,&#39;onMenuShareQQ&#39;,&#39;onMenuShareWeibo&#39;,&#39;onMenuShareQZone&#39;] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });


以上がPHP は WeChat SDK 共有インターフェイスを実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。