微信公众平台开发[2] —— 微信端分享功能

背景

    初次尝试微信公众号的开发,对于学习方法的探索都是来源于网上的博客、问答,对于参差不齐的信息,自己也是有苦说不出,抽出一点时间写点文章,既是对自己的学习总结,也希望给予同是菜鸟的小白一点帮助。

    今天想添加微信分享的功能,如果不进行自定义设计,那么当我们点击分享朋友圈、好友或者QQ好友、空间时,默认的标题就是标签中的信息,而显示的描述信息就是链接,图片多是默认为页面中显示的第一张图片,显然这样的处理是不合理的,所以需要查询开发文档进行编码设计。</span></p> <p style="font-size:14px;line-height:26px;"> <span style="font-family:'KaiTi_GB2312';font-size:18px;"><br></span></p> <h3 style="font-size:14px;line-height:26px;"> <span style="font-size:18px;font-family:'KaiTi_GB2312';">操作步骤:</span></h3> <h4><span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';">一.参考微信公众号开发文档</span></span></h4> <h5><span style="font-size:18px;">【1】.登录微信公众号</span></h5> <div> <span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span></span><span></span>      打开 “开发者工具-><span style="font-size:18px;">开发者文档->微信网页开发->微信JS-SDK说明文档”,找到对应的位置,首先要了解官方的需求说明才能进行下一步的开发。</span></span></span> </div> <div> <span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-size:18px;"><br></span></span></span> </div> <div>          <a href="http://img.e-com-net.com/image/info8/c1c1dae0b3d14c3c8d62406252d9664e.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c1c1dae0b3d14c3c8d62406252d9664e.jpg" width="650" height="462" alt="微信公众平台开发[2] —— 微信端分享功能_第1张图片" style="font-family:'KaiTi_GB2312';font-size:18px;;border:1px solid black;"></a> </div> <h5><span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-family:'KaiTi_GB2312';font-size:18px;">【2】.建议详细参考文档后再考虑代码的编写</span></span></span></h5> <div> <span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-family:'KaiTi_GB2312';font-size:18px;"><span></span><span></span>      提示:下拉上图中的网页最下端,下载官方提供的参考demo。本文的最后我会提供一份稍作修改的仅针对于php的实现代码,可作参考。</span></span></span> </div> <div> <span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-family:'KaiTi_GB2312';font-size:18px;"><br></span></span></span> </div> <div>          <a href="http://img.e-com-net.com/image/info8/f4e64d34352047b786b088c6646c5b27.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/f4e64d34352047b786b088c6646c5b27.jpg" width="650" height="121" alt="微信公众平台开发[2] —— 微信端分享功能_第2张图片" style="font-family:'KaiTi_GB2312';font-size:18px;;border:1px solid black;"></a> </div> <h4><span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-family:'KaiTi_GB2312';font-size:18px;">二.代码实现(PHP)及部分问题引导</span></span></span></h4> <h5><span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-family:'KaiTi_GB2312';font-size:18px;">【1】.我提供的代码就是下图中的几个简单文件</span></span></span></h5> <div> <span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-family:'KaiTi_GB2312';font-size:18px;"><span></span><span></span>      主要来源于微信公众号的开发文档,上面提到过一次。其中,我们操作的分享页面代码只需参考 sharePage.php就好,对于官方的实现可以去阅读其他文件,毕竟我们实现功能只需导入文件,调用所提供类及方法就好。</span></span></span> </div> <div> <span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-family:'KaiTi_GB2312';font-size:18px;"><br></span></span></span> </div> <div>          <a href="http://img.e-com-net.com/image/info8/6df775b038504b0ab3e65ffda75e440a.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/6df775b038504b0ab3e65ffda75e440a.jpg" width="646" height="145" alt="微信公众平台开发[2] —— 微信端分享功能_第3张图片" style="font-family:'KaiTi_GB2312';font-size:18px;;border:1px solid black;"></a> </div> <h5><span style="font-size:18px;"><span style="font-family:'KaiTi_GB2312';"><span style="font-family:'KaiTi_GB2312';font-size:18px;">【2】</span><span style="font-family:'KaiTi_GB2312';">.在此提供 sharePage.php 简单代码,以便参考讲解。</span></span></span></h5> <div> <span style="font-size:18px;font-family:'KaiTi_GB2312';"><span></span><span></span>      其中提出几点需要注意的是:</span> </div> <div> <span style="font-size:18px;font-family:'KaiTi_GB2312';">     (1).需要提供 $appid, $secret</span> </div> <div> <span style="font-size:18px;font-family:'KaiTi_GB2312';">     (2).代码中需要引用微信端提供的js文件</span> <span style="font-size:18px;font-family:'KaiTi_GB2312';"><script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> ,当然也可以下载其源代码,放于本地链接获取就可以。</span> </div> <div> <span style="font-size:18px;font-family:'KaiTi_GB2312';">     (3).保证 wx.config 的信息配置的正确,debug如果为true可以提示操作的过程,测试没有问题后可以改为false,这样才是合理的操作,另外jsApiList中要补全自己需要的功能</span> </div> <div> <span style="font-size:18px;font-family:'KaiTi_GB2312';">     (4).之前我把分享功能的代码写在 wx.config 平级中无法实现,之后测试发现应该写在wx.reday(function())中,具体的代码模式都应该参考开发文档。</span> </div> <div> <span style="font-size:18px;font-family:'KaiTi_GB2312';"><br></span> </div> <div> <span style="font-size:18px;font-family:'KaiTi_GB2312';"></span> <pre><code class="language-php"><?php require_once "jssdk.php"; //获取到网页授权的access_token $appid = "wx36xxxxxxxxxx199";// 输入公众号、服务号、或者测试号的appid $secret = "9caxxxxxxxxxxxxxxxxxx8a2";// 输入公众号、服务号、或者测试号的 secret $jssdk = new JSSDK($appid, $secret); $signPackage = $jssdk->GetSignPackage(); //此处用于输出得到的数据 用来测试签名证书是否正确 /* echo ' appId:'. $signPackage["appId"].'<br/>'; echo ' jsapi_ticket:'. $signPackage["jsapiTicket"].'<br/>'; echo ' url:'. $signPackage["url"].'<br/>'; echo ' timestamp:'. $signPackage["timestamp"].'<br/>'; echo ' nonceStr:'. $signPackage["nonceStr"].'<br/>'; echo ' signature:'. $signPackage["signature"]; echo '<br/>'; echo '<br/>'; echo '<br/>'; exit; */ ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title> Hello Hello Hello

【3】.正常操作中,可能会有 “errMsg config:invalid signature" 签名错误
      可以参考博文  《微信js sdk invalid signature签名错误》,网上多数的建议是检查签名证书是否正确,用作者的话就是“确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验”。

        微信公众平台开发[2] —— 微信端分享功能_第4张图片
      对于需要填入的信息,可以从上文中打印出需要的信息,我做注释的那一部分信息,请参考。不过,普遍情况,这样的签名是没有问题的,可作为参考。
【4】.新发现一种情况
     原先一切正常的分享功能,突然变得无法显示分享时的链接、图片等,我将 wx.config 中的debug 设定为true继续报错“errMsg config:invalid signature",并非签名证书的问题,我猜测应该是文档中一直提及的token或ticket缓存问题,个人打开之前导入的两个文件发现已经重新写入了值,但是我将其重新改为当初下载下来的文件放入服务器中覆盖,意外的发现可以重新获得正确的分享能力,不知哪一天又会出现问题,也希望好心的大牛告知一下。
2016-7-14 补充

      经测试发现,上文提及分享功能的失败,与token ,ticket 存储文件没有多大关系,因为如今无法重现 Bug,无语的是,发现当初开发者中心使用的测试号是被赋予了分享权限的,然而自己申请的订阅号,通过查看“接口权限”发现“未获得”分享权限。


        微信公众平台开发[2] —— 微信端分享功能_第5张图片


      一般的服务号都是拥有分享权限的,获取需要开通什么来着,具体的可百度,我的问题是没有进入“公众号平台->公众号设置->功能设置”中填写“JS接口安全域名”,其中要求是备案过的域名,个人实验证明填写去掉“http://www”后的形如“beidou.com”的域名即可,便于限制诱导关注的情况出现。

      设置完成后可以查看上图中的“分享接口”,保证里面显现的是获得权限,然后再进行菜单栏的分享测试即可发现,正常进行。

【5】.我遇到过提示此处代码报错的问题
      参考网上资源介绍的多是与签名安全相关的信息,可自行百度,鉴于能力有限,暂时发现注释此处的代码可避免该问题的影响,等有时间再做深入解决。

     微信公众平台开发[2] —— 微信端分享功能_第6张图片

【6】.最后的报错信息显示该处对于文件操作的权限不足的问题
      类似 “Warning: fopen(access_token.json) [function.fopen]: failed to open stream: Permission denied in jssdk.php "问题,可以参考此文的部分介绍。

     微信公众平台开发[2] —— 微信端分享功能_第7张图片
      值得一提的是该问题大多牵扯操作系统的权限分配,之前我用的是新浪SAE进行测试,后面得知SAE是无法由我们用户进行权限设定的,最后我选择了公司服务器,使用类似 “ chmod -R 777 /home/mypackage ” 的命令进行对应文件的操作权限分配。

三.补充

     1.出现问题,多参考别人的解决方法,可见有一个可以带你的前辈是多么重要
     2.自己探索问题的解决方法,然后做好笔记作为自己的经历回顾,虽然解决时间拉长,但成就感绝对比从别人口中听来分量重的多。
    3.在此我粘贴稍作修改后的代码,其实就是其中的大概几行的改动,为了配合上面签名的测试,所以需要参考,其中另外的两个文件没做改动,无需上传,公众号开发文档的最后就有 demo 文件,具体的请参照开发文档。
     
appId = $appId;
    $this->appSecret = $appSecret;
  }

  public function getSignPackage() {
    $jsapiTicket = $this->getJsApiTicket();

    // 注意 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 = $this->createNonceStr();

    // 这里参数的顺序要按照 key 值 ASCII 码升序排序
    $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";

    $signature = sha1($string);

    $signPackage = array(
        "appId"     => $this->appId,
        "jsapiTicket" => $jsapiTicket,
        "nonceStr"  => $nonceStr,
        "timestamp" => $timestamp,
        "url"       => $url,
        "signature" => $signature,
        "rawString" => $string
    );
    return $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($this->get_php_file("jsapi_ticket.php"));
    if ($data->expire_time < time()) {
      $accessToken = $this->getAccessToken();
      // 如果是企业号用以下 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($this->httpGet($url));
      $ticket = $res->ticket;
      if ($ticket) {
        $data->expire_time = time() + 7000;
        $data->jsapi_ticket = $ticket;
        $this->set_php_file("jsapi_ticket.php", json_encode($data));
      }
    } else {
      $ticket = $data->jsapi_ticket;
    }

    return $ticket;
  }

  private function getAccessToken() {
    // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
    $data = json_decode($this->get_php_file("access_token.php"));
    if ($data->expire_time < time()) {
      // 如果是企业号用以下URL获取access_token
      // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
      $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
      $res = json_decode($this->httpGet($url));
      $access_token = $res->access_token;
      if ($access_token) {
        $data->expire_time = time() + 7000;
        $data->access_token = $access_token;
        $this->set_php_file("access_token.php", json_encode($data));
      }
    } else {
      $access_token = $data->access_token;
    }
    return $access_token;
  }

  private function httpGet($url) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_TIMEOUT, 500);
    // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。
    // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
    //curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
    curl_setopt($curl, CURLOPT_URL, $url);

    $res = curl_exec($curl);
    curl_close($curl);

    return $res;
  }

  private function get_php_file($filename) {
    return trim(substr(file_get_contents($filename), 15));
  }
  private function set_php_file($filename, $content) {
    $fp = fopen($filename, "w");
    fwrite($fp, "" . $content);
    fclose($fp);
  }
}

四、附录

    1.在此推荐参考一篇比较详细的 微信分享博文,向前辈致敬。   
    2.源代码之前存于360云盘共享
如今已经过期找不到了。其实参考文中的代码同时下载官方demo就能完全重现源代码。
    3.此处 推荐参考新篇: 微信公众平台开发[6]微信开发集成类的使用 (包含微信分享功能)





你可能感兴趣的:(PHP,微信)