PHP微信开发---根据用户回复的关键词和位置,返回附近的信息

用户关注了微信公众号之后,可以回复用户的地理位置(腾讯地图)给公众号,提取位置信息的纬度和经度,转化为百度的纬度和经度。


然后根据纬度和经度,调用百度地图的API,返回附近半径2KM以内的“饭店”“旅馆”(可以自定义)等信息。调用百度的API时,需要获取apiKEY,如果没有,请到百度开发者中心去注册和申请。


首先,用一组纬度和经度来测试接口返回的数据:


  1. <?php  
  2.   
  3. /**根据一组经纬度查找附近2公里以内的关键字**/  
  4.   
  5. header('Content-type:text/html;charset=utf-8');  
  6.   
  7. //--------第一步:转换经纬度----  
  8. //参考链接:http://developer.baidu.com/map/index.php?title=webapi/guide/changeposition  
  9.   
  10. $Location_X = 23.134521;  
  11. $Location_Y = 113.358803;  
  12.   
  13. $url = "http://api.map.baidu.com/geoconv/v1/?coords=$Location_X,$Location_Y&from=3&to=5&ak=这里填写你的apikey";  
  14.   
  15. $res = file_get_contents($url);  
  16. $res = json_decode($res, true);  
  17.   
  18. //用户发送腾讯的soso地图位置信息经过转换之后,得到百度地图的经纬度  
  19. $x = $res['result'][0]['x'];  
  20. $y = $res['result'][0]['y'];  
  21.   
  22. //---------第二步:根据经纬度和关键词获得附近的信息----------  
  23. //参考链接:http://developer.baidu.com/map/index.php?title=webapi/guide/webservice-placeapi  
  24. $url = "http://api.map.baidu.com/place/v2/search?ak=这里填写你的apikey&output=json&query=" . urlencode("饭店") . "&page_size=10&page_num=0&scope=2&location=$x,$y&radius=2000";  
  25. $res = file_get_contents($url);  
  26. $res = json_decode($res, true);  
  27.   
  28. // echo "<pre>";  
  29. // print_r($res);  
  30. // echo "</pre>";  
  1. //提取所需的信息  
  2. foreach($res['results'as $k=>$v){  
  3.     $arr[$k]['name'] = $v['name'];  
  4.     $arr[$k]['address'] = $v['address'];  
  5.     $arr[$k]['img_url'] = 'http://misakaqnxt-public.stor.sinaapp.com/click.png';  
  6.     $arr[$k]['detail_url'] = isset($v['detail_info']['detail_url'])?$v['detail_info']['detail_url']:'';  
  7. }  
  8.   
  9.  echo "<pre>";  
  10.  print_r($arr);  
  11.  echo "</pre>";  
返回的数据
PHP微信开发---根据用户回复的关键词和位置,返回附近的信息


如果你填写了正确的apikey,那么应该返回了上面的数据了。

下来:在微信的接口平台代码(放在你的公网域名空间里的PHP脚本)里,判断消息类型,并获取纬度和经度,调用百度地图API,拼接XML返回即可。由于百度API返回的数据里,没有“饭店”的缩略图,所以我就用了自己网站的一张图。


为了能够让用户自定义查找周围的“饭店”或“旅馆”等信息,可以先让用户回复“寻找XX”,然后提取出XX,放到session里,等用户再回复地理位置时取出session。但我设置了session之后,没能取出session。所以我这里用新浪云的KVDB服务,当然你也可以用memcache或者redis等缓存方式。

  1. $which = mb_substr($keyword, 0, 2, 'UTF-8');  
  1. elseif($which == "寻找"){  
  2.   
  3.                 $find = str_replace($which""$keyword);  
  4.   
  5.                 //调用新浪云的KVDB服务  
  6.                 $kv = new SaeKV();  
  7.                 $kv->init();  
  8.                 $kv->set('find'$find);  
  9.   
  10.                 $contentStr = "选择表情旁边的'+',发送位置,即可查找你要找的地方";  
  11.                 $resultStr = sprintf($textTpl$fromUsername$toUsername$time$msgtype$contentStr);  
  12.                 echo $resultStr;  
  13.                 exit();  
  14.   
  15.             }  

  1. elseif($postObj->MsgType == 'location'){  
  2.                     /** 
  3.                      * 如果是收到了地理位置消息,则返回附近的饭店 
  4.                      */  
  5.   
  6.                     //--------第一步:转换经纬度-------  
  7.                     //参考链接:http://developer.baidu.com/map/index.php?title=webapi/guide/changeposition  
  8.                     $Location_X = $postObj->Location_X;  
  9.                     $Location_Y = $postObj->Location_Y;  
  10.                       
  11.                     $url = "http://api.map.baidu.com/geoconv/v1/?coords=$Location_X,$Location_Y&from=3&to=5&ak=这里填写你的apikey";  
  12.                       
  13.                     $res = file_get_contents($url);  
  14.                     $res = json_decode($res, true);  
  15.   
  16.                     //用户发送腾讯的soso地图位置信息经过转换之后,得到百度地图的经纬度  
  17.                     $x = $res['result'][0]['x'];  
  18.                     $y = $res['result'][0]['y'];  
  19.   
  20.                     //---------第二步:根据经纬度和关键词获得附近的信息----------  
  21.                     $kv = new SaeKV();  
  22.                     // 初始化KVClient对象  
  23.                     $kv->init();  
  24.                       
  25.                     $url = "http://api.map.baidu.com/place/v2/search?ak=这里填写你的apikey&output=json&query=" . urlencode($kv->get('find')) . "&page_size=10&page_num=0&scope=2&location=$x,$y&radius=2000";  
  26.                     $res = file_get_contents($url);  
  27.                     $res = json_decode($res, true);  
  28.                       
  29.                     //提取信息  
  30.                     foreach($res['results'as $k=>$v){  
  31.                         $arr[$k]['name'] = $v['name'];  
  32.                         $arr[$k]['address'] = $v['address'];  
  33.                         $arr[$k]['img_url'] = 'http://misakaqnxt-public.stor.sinaapp.com/click.png';  
  34.                         $arr[$k]['detail_url'] = isset($v['detail_info']['detail_url'])?$v['detail_info']['detail_url']:'';  
  35.                     }  
  36.   
  37.                     //--------第三步:拼接XML字符串--------  
  38.                     $head = "<xml>  
  39.                     <ToUserName><![CDATA[%s]]></ToUserName>  
  40.                     <FromUserName><![CDATA[%s]]></FromUserName>  
  41.                     <CreateTime>%s</CreateTime>  
  42.                     <MsgType><![CDATA[news]]></MsgType>  
  43.                     <ArticleCount>10</ArticleCount>  
  44.                     <Articles>";  
  45.   
  46.                     $items = "";  
  47.                     foreach($arr as $v){  
  48.                         $items .= "<item>  
  49.                         <Title><![CDATA[" . $v['name'] ."". $v['address'] . "]]></Title>  
  50.                         <Description><![CDATA[" . $v['address'] . "]]></Description>  
  51.                         <PicUrl><![CDATA[" . $v['img_url'] . "]]></PicUrl>  
  52.                         <Url><![CDATA[" . $v['detail_url'] . "]]></Url>  
  53.                         </item>";  
  54.                     }  
  55.   
  56.                     $foot = "</Articles></xml>";  
  57.   
  58.                     $res = $head . $items . $foot;  
  59.                       
  60.                     $resultStr = sprintf($res$fromUsername$toUsername$time);  
  61.                     echo $resultStr;  
  62.                     exit();  
  63.   
  64.   
  65.                 }