我们通过微信浏览器打开页面时,有时会提示要获取地理位置信息.点击同意后,自己的地理位置信息就会相应的显示在页面,同时通过数据库的查询,以实现以地理位置分类的逻辑业务.
本例通过thinkphp5来完成,下面介绍实现详细步骤!
首先我们引入一个类:
下载地址如下: https://pan.baidu.com/s/1mhLkHF6 密码: vgq5
需要注意的,类中获取的api_ticket和jsapi_ticket有效期是7200秒.通过access_token来获取。由于获取jsapi_ticket和api_ticket的api调用次数非常有限,频繁刷新他们会导致api调用受限,影响自身业务,必须在自己的服务全局缓存他们.
所以以下利用了tp5的cache缓存机制来存储他们.
我这里为了省事,直接将微信的appid和appsecret存在了配置文件中,并在类中直接常量定义
下载好类Wxjssdk.php,我把它放在了extends的wxweb目录下,并且命名空间为wxweb
appid = $appid;
$this->appsecret = $appsecret;
}
// $res = file_get_contents(EXTEND_PATH.'/wxweb/access_token.json');
// $result = json_decode($res, true);
// $this->expires_time = $result["expires_time"];
// $this->access_token = $result["access_token"];
$this->access_token = cache('access_token');
if(!cache('expires_time')){
$this->expires_time = 0;
}else{
$this->expires_time = cache('expires_time');
}
if (time() > ($this->expires_time + 3600)){
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$this->appid."&secret=".$this->appsecret;
$res = $this->http_request($url);
$result = json_decode($res, true);
$this->access_token = $result["access_token"];
$this->expires_time = time();
// file_put_contents(EXTEND_PATH.'/wxweb/access_token.json', '{"access_token": "'.$this->access_token.'", "expires_time": '.$this->expires_time.'}');
cache('access_token',$this->access_token);
cache('expires_time',$this->expires_time);
}
}
//生成长度16的随机字符串
public 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;
}
//获得微信卡券api_ticket
public function getCardApiTicket()
{
// $res = file_get_contents(EXTEND_PATH.'/wxweb/cardapi_ticket.json');
// $result = json_decode($res, true);
// $this->cardapi_ticket = $result["cardapi_ticket"];
// $this->cardapi_expire = $result["cardapi_expire"];
$this->cardapi_ticket = cache('cardapi_ticket');
if(!cache('cardapi_expire')){
$this->cardapi_expire = 0;
}else{
$this->cardapi_expire = cache('cardapi_expire');
}
if (time() > ($this->cardapi_expire + 3600)){
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card&access_token=".$this->access_token;
$res = $this->http_request($url);
$result = json_decode($res, true);
$this->cardapi_ticket = $result["ticket"];
$this->cardapi_expire = time();
// file_put_contents(EXTEND_PATH.'/wxweb/cardapi_ticket.json', '{"cardapi_ticket": "'.$this->cardapi_ticket.'", "cardapi_expire": '.$this->cardapi_expire.'}');
cache('cardapi_ticket',$this->cardapi_ticket);
cache('cardapi_expire',$this->cardapi_expire);
}
return $this->cardapi_ticket;
}
//cardSign卡券签名
public function get_cardsign($bizObj)
{
//字典序排序
asort($bizObj);
//URL键值对拼成字符串
$buff = "";
foreach ($bizObj as $k => $v){
$buff .= $v;
}
//sha1签名
return sha1($buff);
}
//获得JS API的ticket
private function getJsApiTicket()
{
// $res = file_get_contents(EXTEND_PATH.'/wxweb/jsapi_ticket.json');
// $result = json_decode($res, true);
// $this->jsapi_ticket = $result["jsapi_ticket"];
// $this->jsapi_expire = $result["jsapi_expire"];
$this->jsapi_ticket = cache('jsapi_ticket');
if(!cache('jsapi_expire')){
$this->jsapi_expire = 0;
}else{
$this->jsapi_expire = cache('jsapi_expire');
}
if (time() > ($this->jsapi_expire + 3600)){
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=".$this->access_token;
$res = $this->http_request($url);
$result = json_decode($res, true);
$this->jsapi_ticket = $result["ticket"];
$this->jsapi_expire = time();
// file_put_contents(EXTEND_PATH.'/wxweb/jsapi_ticket.json', '{"jsapi_ticket": "'.$this->jsapi_ticket.'", "jsapi_expire": '.$this->jsapi_expire.'}');
cache('jsapi_ticket',$this->jsapi_ticket);
cache('jsapi_expire',$this->jsapi_expire);
}
return $this->jsapi_ticket;
}
//获得签名包
public function getSignPackage() {
$jsapiTicket = $this->getJsApiTicket();
$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();
$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
$signature = sha1($string);
$signPackage = array(
"appId" => $this->appid,
"nonceStr" => $nonceStr,
"timestamp" => $timestamp,
"url" => $url,
"signature" => $signature,
"rawString" => $string
);
return $signPackage;
}
//HTTP请求(支持HTTP/HTTPS,支持GET/POST)
protected function http_request($url, $data = null)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
}
然后在控制器如下:
GetSignPackage();
return view('',['res'=>$signPackage]);
}
}
$signPackage就是微信js-sdk的config接口注入权限验证配信息
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见附录1
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
然后在视图页面,首先引入微信js,必须项
然后写js文件如下:
ajax请求的控制中如下:
//获取用户地理位置信息
public function map()
{
$ak = '8gcWsC7GGjpiGsAN7hfEyXNPHr7wDz27';
$data = input('get.res/a');
$lat = $data['latitude'];
$lng = $data['longitude'];
$url = "http://api.map.baidu.com/geocoder/v2/?ak={$ak}&location={$lat},{$lng}&output=json&coordtype=gcj02ll";
$res = file_get_contents($url);
//百度地图返回的并不是json,而是字符串,需要自己在做一个处理
$res = json_decode($res,true);
return json($res);
}