微信(WeChat)是腾讯公司于2011年1月21日推出的一个为智能终端提供即时通讯服务的免费应用程序,由张小龙所带领的腾讯广州研发中心产品团队打造 [2] 。微信支持跨通信运营商、跨操作系统平台通过网络快速发送免费(需消耗少量网络流量)语音短信、视频、图片和文字,同时,也可以使用通过共享流媒体内容的资料和基于位置的社交插件“摇一摇”、“漂流瓶”、“朋友圈”、”公众平台“、”语音记事本“等服务插件。
软件开发工具包(外语首字母缩写:SDK、外语全称:Software Development Kit)一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。本文主要和大家分享php实现微信sdk分享接口,希望能帮助到大家。
<?php
class Wxsdk
{
private $appId;
private $appSecret;
/*
* 这里为威狮码的公众号的openid和appsecret,如果配置到其他的子商家会出现需要关注威狮码公众号,
* 则需要获取数据库的vender表里面的openid和appsecret
* */
public function __construct($appId = '自己的appid', $appSecret = '自己的appSecret')
{
$this->appId = $appId;
$this->appSecret = $appSecret;
}
public function getSignPackage(Request $request)
{
//接收到前端的转义url转义回来
$url = $_POST;
$durl = $url['url'];
$durl = urldecode($durl);
$jsapiTicket = $this->getJsApiTicket();
$timestamp = time();
$nonceStr = $this->createNonceStr();
// 这里参数的顺序要按照 key 值 ASCII 码升序排序
$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$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(['msg' => $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['type'] = 'jsapi';
$params['access_token'] = $accessToken;
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $params['access_token'] . "&type=" . $params['type'] . "";
$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['grant_type'] = 'client_credential';
$params['appid'] = $this->appId;
$params['secret'] = $this->appSecret;
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" . $params['grant_type'] . "&appid=" . $params['appid'] . "&secret=" . $params['secret'] . "";
$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;
}
前端代码
签名是正确,上面的步骤还没能解决你的问题(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解码,核心代码如下: