当前位置:首页 > PHP教程 > php高级应用 > 列表

微信公众平台开发教程②微信端分享功能图文详解

发布:smiling 来源: PHP粉丝网  添加日期:2021-11-16 11:08:31 浏览: 评论:0 

本文实例讲述了微信公众平台微信端分享功能。分享给大家供大家参考,具体如下:

背景

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

今天想添加微信分享的功能,如果不进行自定义设计,那么当我们点击分享朋友圈、好友或者QQ好友、空间时,默认的标题就是<title>标签中的信息,而显示的描述信息就是链接,图片多是默认为页面中显示的第一张图片,显然这样的处理是不合理的,所以需要查询开发文档进行编码设计。

操作步骤:

一.参考微信公众号开发文档

【1】.登录微信公众号

打开 “开发者工具->开发者文档->微信网页开发->微信JS-SDK说明文档”,找到对应的位置,首先要了解官方的需求说明才能进行下一步的开发。

微信公众平台 微信端分享功能

【2】.建议详细参考文档后再考虑代码的编写

提示:下拉上图中的网页最下端,下载官方提供的参考demo。本文的最后我会提供一份稍作修改的仅针对于php的实现代码,可作参考。

微信公众平台 微信端分享功能

二.代码实现(PHP)及部分问题引导

【1】.我提供的代码就是下图中的几个简单文件

主要来源于微信公众号的开发文档,上面提到过一次。其中,我们操作的分享页面代码只需参考 sharePage.php就好,对于官方的实现可以去阅读其他文件,毕竟我们实现功能只需导入文件,调用所提供类及方法就好。

微信公众平台 微信端分享功能

【2】.在此提供 sharePage.php 简单代码,以便参考讲解。

其中提出几点需要注意的是:

(1).需要提供 $appid, $secret

(2).代码中需要引用微信端提供的js文件<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> ,当然也可以下载其源代码,放于本地链接获取就可以。

(3).保证 wx.config 的信息配置的正确,debug如果为true可以提示操作的过程,测试没有问题后可以改为false,这样才是合理的操作,另外jsApiList中要补全自己需要的功能

(4).之前我把分享功能的代码写在 wx.config 平级中无法实现,之后测试发现应该写在wx.reday(function())中,具体的代码模式都应该参考开发文档。

  1. <?php 
  2. require_once "jssdk.php"
  3.  
  4. //获取到网页授权的access_token 
  5. $appid = "wx36xxxxxxxxxx199";// 输入公众号、服务号、或者测试号的appid  
  6. $secret = "9caxxxxxxxxxxxxxxxxxx8a2";// 输入公众号、服务号、或者测试号的 secret 
  7.  
  8.  
  9. $jssdk = new JSSDK($appid$secret); 
  10. $signPackage = $jssdk->GetSignPackage(); 
  11.  
  12. //此处用于输出得到的数据 用来测试签名证书是否正确  
  13. /* 
  14. echo ' appId:'. $signPackage["appId"].'<br/>'; 
  15. echo ' jsapi_ticket:'. $signPackage["jsapiTicket"].'<br/>'; 
  16. echo ' url:'. $signPackage["url"].'<br/>'; 
  17. echo ' timestamp:'. $signPackage["timestamp"].'<br/>'; 
  18. echo ' nonceStr:'. $signPackage["nonceStr"].'<br/>'; 
  19. echo ' signature:'. $signPackage["signature"]; 
  20. echo '<br/>'; 
  21. echo '<br/>'; 
  22. echo '<br/>'; 
  23. exit; 
  24. */ 
  25.  
  26. ?> 
  27. <!DOCTYPE html> 
  28. <html lang="en"
  29. <head> 
  30.  <meta charset="UTF-8"
  31.  <title></title> 
  32. </head> 
  33. <body> 
  34.  Hello Hello Hello 
  35. </body> 
  36. <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> 
  37. <script> 

注意:

1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。

3. 常见问题及完整 JS-SDK 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可通过以下渠道反馈:

邮箱地址:weixin-open@qq.com

邮件主题:【微信JS-SDK反馈】具体问题

邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。

  1.  wx.config({ 
  2.  debug: true, 
  3.  appId: '<?php echo $signPackage["appId"];?>'
  4.  timestamp: <?php echo $signPackage["timestamp"];?>, 
  5.  nonceStr: '<?php echo $signPackage["nonceStr"];?>'
  6.  signature: '<?php echo $signPackage["signature"];?>'
  7.  jsApiList: [ 
  8.   // 所有要调用的 API 都要加到这个列表中 
  9.   'checkJsApi'
  10.   'onMenuShareTimeline'
  11.   'onMenuShareAppMessage'
  12.   'onMenuShareQQ'
  13.   'onMenuShareWeibo'
  14.   'onMenuShareQZone'
  15.  ] 
  16.  }); 
  17.  
  18.  wx.ready(function () { 
  19.  // 在这里调用 API 
  20.  //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 
  21.  wx.onMenuShareTimeline({ 
  22.   title: '快来!分享朋友圈'// 分享标题 
  23.   link: 'http://www.baidu.com', // 分享链接 
  24.   imgUrl: 'http://img1.3lian.com/img013/v2/4/d/101.jpg', // 分享图标 
  25.   success: function () { 
  26.   // 用户确认分享后执行的回调函数 
  27.   }, 
  28.   cancel: function () { 
  29.   // 用户取消分享后执行的回调函数 
  30.   } 
  31.  }); 
  32.  //获取“分享给朋友”按钮点击状态及自定义分享内容接口 
  33.  wx.onMenuShareAppMessage({ 
  34.   title: ' 微信分享给朋友'// 分享标题 
  35.   desc: '描述一下,可是知道该咋描述你呢?'// 分享描述 
  36.   link: 'http://www.baidu.com', // 分享链接 
  37.   imgUrl: 'http://img1.3lian.com/img013/v2/4/d/101.jpg', // 分享图标 
  38.   type: 'link'// 分享类型,music、video或link,不填默认为link 
  39.   dataUrl: ''// 如果type是music或video,则要提供数据链接,默认为空 
  40.  }); 
  41.  wx.onMenuShareQQ({ 
  42.   title: 'QQ我要跳转到百度页面了啊!'// 分享标题 
  43.   desc: '描述一下,可是知道该咋描述你呢?'// 分享描述 
  44.   link: 'http://www.baidu.com', // 分享链接 
  45.   imgUrl: 'http://img1.3lian.com/img013/v2/4/d/101.jpg', // 分享图标 
  46.  }); 
  47.  wx.onMenuShareQZone({ 
  48.   title: 'QZone我要跳转到百度页面了啊!'// 分享标题 
  49.   desc: '描述一下,可是知道该咋描述你呢?'// 分享描述 
  50.   link: 'http://www.baidu.com', // 分享链接 
  51.   imgUrl: 'http://img1.3lian.com/img013/v2/4/d/101.jpg', // 分享图标 
  52.  }); 
  53.  }); 
  54. </script> 
  55. </html> 

【3】.正常操作中,可能会有 “errMsg config:invalid signature" 签名错误

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

微信公众平台 微信端分享功能

对于需要填入的信息,可以从上文中打印出需要的信息,我做注释的那一部分信息,请参考。不过,普遍情况,这样的签名是没有问题的,可作为参考。

【4】.新发现一种情况

原先一切正常的分享功能,突然变得无法显示分享时的链接、图片等,我将 wx.config 中的debug 设定为true继续报错“errMsg config:invalid signature",并非签名证书的问题,我猜测应该是文档中一直提及的token或ticket缓存问题,个人打开之前导入的两个文件发现已经重新写入了值,但是我将其重新改为当初下载下来的文件放入服务器中覆盖,意外的发现可以重新获得正确的分享能力,不知哪一天又会出现问题,也希望好心的大牛告知一下。

【2016-7-14 补充】

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

微信公众平台 微信端分享功能

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

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

【5】.我遇到过提示此处代码报错的问题

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

微信公众平台 微信端分享功能

【6】.最后的报错信息显示该处对于文件操作的权限不足的问题

类似 “Warning: fopen(access_token.json) [function.fopen]: failed to open stream: Permission denied in jssdk.php "问题,可以参考此文的部分介绍。

微信公众平台 微信端分享功能

值得一提的是该问题大多牵扯操作系统的权限分配,之前我用的是新浪SAE进行测试,后面得知SAE是无法由我们用户进行权限设定的,最后我选择了公司服务器,使用类似 “chmod -R 777 /home/mypackage ” 的命令进行对应文件的操作权限分配。

三.补充

1.出现问题,多参考别人的解决方法,可见有一个可以带你的前辈是多么重要

2.自己探索问题的解决方法,然后做好笔记作为自己的经历回顾,虽然解决时间拉长,但成就感绝对比从别人口中听来分量重的多。

3.在此我粘贴稍作修改后的代码,其实就是其中的大概几行的改动,为了配合上面签名的测试,所以需要参考,其中另外的两个文件没做改动,无需上传,公众号开发文档的最后就有 demo 文件,具体的请参照开发文档。

  1. <?php 
  2. class JSSDK { 
  3.  private $appId
  4.  private $appSecret
  5.  
  6.  public function __construct($appId$appSecret) { 
  7.  $this->appId = $appId
  8.  $this->appSecret = $appSecret
  9.  } 
  10.  
  11.  public function getSignPackage() { 
  12.  $jsapiTicket = $this->getJsApiTicket(); 
  13.  
  14.  // 注意 URL 一定要动态获取,不能 hardcode. 
  15.  $protocol = (!emptyempty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"
  16.  $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"
  17.  
  18.  $timestamp = time(); 
  19.  $nonceStr = $this->createNonceStr(); 
  20.  
  21.  // 这里参数的顺序要按照 key 值 ASCII 码升序排序 
  22.  $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"
  23.  
  24.  $signature = sha1($string); 
  25.  
  26.  $signPackage = array
  27.  "appId" => $this->appId, 
  28.  "jsapiTicket" => $jsapiTicket
  29.  "nonceStr" => $nonceStr
  30.  "timestamp" => $timestamp
  31.  "url" => $url
  32.  "signature" => $signature
  33.  "rawString" => $string 
  34.  ); 
  35.  return $signPackage
  36.  } 
  37.  
  38.  private function createNonceStr($length = 16) { 
  39.  $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  40.  $str = ""
  41.  for ($i = 0; $i < $length$i++) { 
  42.  $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 
  43.  } 
  44.  return $str
  45.  } 
  46.  
  47.  private function getJsApiTicket() { 
  48.  // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例 
  49.  $data = json_decode($this->get_php_file("jsapi_ticket.php")); 
  50.  if ($data->expire_time < time()) { 
  51.  $accessToken = $this->getAccessToken(); 
  52.  // 如果是企业号用以下 URL 获取 ticket 
  53.  // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken"; 
  54.  $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken"
  55.  $res = json_decode($this->httpGet($url)); 
  56.  $ticket = $res->ticket; 
  57.  if ($ticket) { 
  58.  $data->expire_time = time() + 7000; 
  59.  $data->jsapi_ticket = $ticket
  60.  $this->set_php_file("jsapi_ticket.php", json_encode($data)); 
  61.  } 
  62.  } else { 
  63.  $ticket = $data->jsapi_ticket; 
  64.  } 
  65.  
  66.  return $ticket
  67.  } 
  68.  
  69.  private function getAccessToken() { 
  70.  // access_token 应该全局存储与更新,以下代码以写入到文件中做示例 
  71.  $data = json_decode($this->get_php_file("access_token.php")); 
  72.  if ($data->expire_time < time()) { 
  73.  // 如果是企业号用以下URL获取access_token 
  74.  // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret"; 
  75.  $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret"
  76.  $res = json_decode($this->httpGet($url)); 
  77.  $access_token = $res->access_token; 
  78.  if ($access_token) { 
  79.  $data->expire_time = time() + 7000; 
  80.  $data->access_token = $access_token
  81.  $this->set_php_file("access_token.php", json_encode($data)); 
  82.  } 
  83.  } else { 
  84.  $access_token = $data->access_token; 
  85.  } 
  86.  return $access_token
  87.  } 
  88.  
  89.  private function httpGet($url) { 
  90.  $curl = curl_init(); 
  91.  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
  92.  curl_setopt($curl, CURLOPT_TIMEOUT, 500); 
  93.  // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。 
  94.  // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。 
  95.  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); 
  96.  //curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true); 
  97.  curl_setopt($curl, CURLOPT_URL, $url); 
  98.  
  99.  $res = curl_exec($curl); 
  100.  curl_close($curl); 
  101.  
  102.  return $res
  103.  } 
  104.  
  105.  private function get_php_file($filename) { 
  106.  return trim(substr(file_get_contents($filename), 15)); 
  107.  } 
  108.  private function set_php_file($filename$content) { 
  109.  $fp = fopen($filename"w"); 
  110.  fwrite($fp"<?php exit();?>" . $content); 
  111.  fclose($fp); 
  112.  } 
  113. }

Tags: 微信公众平台 微信端分享功能

分享到: