PHP 实现微信 SDK 分享接口详细步骤教程解析

why 32 2024-09-30

软件开发工具包(外语首字母缩写:sdk、外语全称:software development kit)一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。本文主要和大家分享php实现微信sdk分享接口,希望能帮助到大家。

PHP 实现微信 SDK 分享接口详细步骤教程解析

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

<?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 页面工具进行校验。

  • 确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。

  • 确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。

  • 确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。

  • 确保一定缓存access_token和jsapi_ticket。

  • 确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent,后台decodeURIComponent解码),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。

签名是正确,上面的步骤还没能解决你的问题(invalid signature)那就用是url的问题,注意:微信公众号必须配置了你调试的安全域名(可以配置二级域名:xxx.com,而不用配置多个a.xxx.com/b.xxx.com等)。

原因:微信分享时候会给你当前页面添加多个参数,你sha1时候必须保证url地址是微信给你加了参数之后的地址,这样才不会报config:invalid signature.

解决方案:sha1之前url必须是解码之后的正常的肉眼直接能识别的url,如果你用的是静态页面,在你配置wx.config之前,先通过encodeURIComponent(location.href.split('#')[0])把当前url编码传递到后台,后台通过decodeURIComponent解码,核心代码如下:

前台html页面,编码传递url:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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

    });

  


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信硬件 H5 开发控制灯光步骤全面详细解析
下一篇:Asp.Net MVC 开发微信扫码支付详细步骤与教程
相关文章

 发表评论

暂时没有评论,来抢沙发吧~