微信公众号最佳实践 ( 7.8)附近搜索

标签: 附近搜索  微信公众号开发最佳实践

附近搜索

这里写图片描述

百度地图

这里写图片描述
http://lbsyun.baidu.com/

place区域检索POI服务接口如下:
http://api.map.baidu.com/place/v2/search

该接口的参数说明如下表:
这里写图片描述
这里写图片描述

示例如下:

<?php
define ("DEBUG_MODE", false);

var_dump(catchEntitiesFromLocation("银行", "22.123185", "113.23434", "5000"));

function catchEntitiesFromLocation($entity, $x, $y, $radius)
{
    $url = "http://api.map.baidu.com/place/v2/search?ak=MgBALVVeCd8THVBi6gPdvsvG&output=json&query=".$entity."&page_size=5&page_num=0&scope=2&location=".$x.",".$y."&radius=".$radius."&filter=sort_name:distance";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);

    $data = json_decode($output, true);

    if ($data['status'] != 0){
        return $data['message'];
    }

    $results = $data['results'];
    if (count($results) == 0){
        return "附近没有找到".$entity;
    }
    $shopArray = array();
    $shopArray[] = array("Title"=>"附近的".$entity, "Description"=>"", "PicUrl"=>"", "Url"=>"");
    for ($i = 0; $i < count($results); $i++) {
        $shopArray[] = array(
            "Title"=>"【".$results[$i]['name']."】<".$results[$i]['detail_info']['distance']."米>\n".$results[$i]['address'].
            (isset($results[$i]['telephone'])?"\n".$results[$i]['telephone']:""),
            "Description"=>"", 
            "PicUrl"=>"", 
            "Url"=>(isset($results[$i]['detail_info']['detail_url'])?($results[$i]['detail_info']['detail_url']):""));
    }
    return $shopArray;
}

?>

返回如下:

{
    "status":0,
    "message":"ok",
    "total":23,
    "results":[
        {
            "name":"珠海农商银行24小时自助银行服务",
            "location":{
                "lat":22.113364,
                "lng":113.201677
            },
            "address":"迎雁东路83号",
            "province":"广东省",
            "city":"珠海市",
            "area":"金湾区",
            "detail":1,
            "uid":"df6e3b1cebf10b05c5effbd0",
            "detail_info":{
                "distance":3537,
                "tag":"金融;atm",
                "type":"life",
                "detail_url":"http://api.map.baidu.com/place/detail?uid=df6e3b1cebf10b05c5effbd0&output=html&source=placeapi_v2",
                "overall_rating":"0.0",
                "image_num":"5",
                "comment_num":"2",
                "children":[

                ]
            }
        },
        {
            "name":"中国农业银行(乾务支行)",
            "location":{
                "lat":22.160167,
                "lng":113.235957
            },
            "address":"珠海市斗门区乾务镇乾南中路137号",
            "province":"广东省",
            "city":"珠海市",
            "area":"斗门区",
            "telephone":"(0756)5581277",
            "detail":1,
            "uid":"df0a9263497fc271e31103a9",
            "detail_info":{
                "distance":4115,
                "tag":"金融;银行",
                "navi_location":{
                    "lng":113.23575142485,
                    "lat":22.160135374353
                },
                "type":"life",
                "detail_url":"http://api.map.baidu.com/place/detail?uid=df0a9263497fc271e31103a9&output=html&source=placeapi_v2",
                "overall_rating":"0.0",
                "image_num":"10",
                "comment_num":"2",
                "children":[

                ]
            }
        },
        {
            "name":"中国农业银行24小时自助银行(珠海斗门乾务支行)",
            "location":{
                "lat":22.160218,
                "lng":113.235991
            },
            "address":"乾务镇乾南北路137号",
            "province":"广东省",
            "city":"珠海市",
            "area":"斗门区",
            "detail":1,
            "uid":"42e484d3e3ffc86b631c67d5",
            "detail_info":{
                "distance":4121,
                "tag":"金融;atm",
                "type":"life",
                "detail_url":"http://api.map.baidu.com/place/detail?uid=42e484d3e3ffc86b631c67d5&output=html&source=placeapi_v2",
                "overall_rating":"1.0",
                "image_num":"3",
                "comment_num":"1",
                "children":[

                ]
            }
        },
        {
            "name":"中国工商银行(珠海平沙支行)",
            "location":{
                "lat":22.110259,
                "lng":113.196565
            },
            "address":"珠海市金湾区平沙镇平沙一路145号",
            "province":"广东省",
            "city":"珠海市",
            "area":"金湾区",
            "telephone":"(0756)7751348,(0756)7753287",
            "detail":1,
            "uid":"610852118c426ea1c51b7545",
            "detail_info":{
                "distance":4148,
                "tag":"金融;银行",
                "navi_location":{
                    "lng":113.1965447138,
                    "lat":22.109864165734
                },
                "type":"life",
                "detail_url":"http://api.map.baidu.com/place/detail?uid=610852118c426ea1c51b7545&output=html&source=placeapi_v2",
                "overall_rating":"2.2",
                "image_num":"5",
                "comment_num":"4",
                "children":[

                ]
            }
        },
        {
            "name":"中国工商银行ATM(珠海平沙支行)",
            "location":{
                "lat":22.110046,
                "lng":113.196419
            },
            "address":"广东省珠海市金湾区平沙一路174",
            "province":"广东省",
            "city":"珠海市",
            "area":"金湾区",
            "detail":1,
            "uid":"cc788fde14973e8a88fc0645",
            "detail_info":{
                "distance":4170,
                "tag":"金融;atm",
                "navi_location":{
                    "lng":113.19644331577,
                    "lat":22.109846982092
                },
                "type":"life",
                "detail_url":"http://api.map.baidu.com/place/detail?uid=cc788fde14973e8a88fc0645&output=html&source=placeapi_v2",
                "overall_rating":"0.0",
                "image_num":"5",
                "comment_num":"2",
                "children":[

                ]
            }
        }
    ]
}

这里写图片描述

这里写图片描述

这里写图片描述
代码实现:

index.php

<?php
/*
    CopyRight 2018 All Rights Reserved
*/

define("TOKEN", "weixin");

$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
    $wechatObj->responseMsg();
}else{
    $wechatObj->valid();
}

class wechatCallbackapiTest
{
    public function valid()
    {
        $echoStr = $_GET["echostr"];
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }

    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];
        $token = TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if($tmpStr == $signature){
            return true;
        }else{
            return false;
        }
    }

    public function responseMsg()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        if (!empty($postStr)){
            $this->logger("R ".$postStr);
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $RX_TYPE = trim($postObj->MsgType);

            switch ($RX_TYPE)
            {
                case "event":
                    $result = $this->receiveEvent($postObj);
                    break;
                case "text":
                    $result = $this->receiveText($postObj);
                    break;
                case "location":
                    $result = $this->receiveLocation($postObj);
                    break;
            }
            $this->logger("T ".$result);
            echo $result;
        }else {
            echo "";
            exit;
        }
    }

    private function receiveEvent($object)
    {
        $content = "";
        switch ($object->Event)
        {
            case "subscribe":
                $content = "欢迎关注  德强1012 ";
                break;
            case "unsubscribe":
                $content = "取消关注";
                break;
        }
        $result = $this->transmitText($object, $content);
        return $result;
    }

    private function receiveText($object)
    {
        $keyword = trim($object->Content);
        $category = substr($keyword,0,6);
        $entity = trim(substr($keyword,6,strlen($keyword)));
        switch ($category)
        {
            case "附近":
                include("location.php");
                $location = getLocation($object->FromUserName);
                if (is_array($location)){
                    include("mapbaidu.php");
                    //$content = count($location);
                    $content = catchEntitiesFromLocation($entity, $location["locationX"], $location["locationY"], "5000");
                }else{
                    $content = $location;
                }
                break;
            default:
                $content = $object->FromUserName;
                break;
        }
        if(is_array($content)){
            $result = $this->transmitNews($object, $content);
        }else{
            $result = $this->transmitText($object, $content);
        }
        return $result;
    }

    /*
     * 接收位置消息
     */
    private function receiveLocation($object)
    {
        include("location.php");
        $content = setLocation($object->FromUserName,(string)$object->Location_X, (string)$object->Location_Y);
        $result = $this->transmitText($object, $content);
        return $result;
    }

    private function transmitText($object, $content)
    {
        $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[text]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                     </xml>";
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
        return $result;
    }

    private function transmitNews($object, $arr_item)
    {
        if(!is_array($arr_item))
            return;

        $itemTpl = "    <item>
                            <Title><![CDATA[%s]]></Title>
                            <Description><![CDATA[%s]]></Description>
                            <PicUrl><![CDATA[%s]]></PicUrl>
                            <Url><![CDATA[%s]]></Url>
                        </item>
                    ";
        $item_str = "";
        foreach ($arr_item as $item)
            $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);

        $newsTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[news]]></MsgType>
                        <Content><![CDATA[]]></Content>
                        <ArticleCount>%s</ArticleCount>
                        <Articles>
                        $item_str</Articles>
                     </xml>";

        $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));
        return $result;
    }

    private function logger($log_content)
    {
        if(isset($_SERVER['HTTP_BAE_ENV_APPID'])){   //BAE
            require_once "BaeLog.class.php";
            $logger = BaeLog::getInstance();
            $logger ->logDebug($log_content);
        }else if(isset($_SERVER['HTTP_APPNAME'])){   //SAE
            sae_set_display_errors(false);
            sae_debug($log_content);
            sae_set_display_errors(true);
        }else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL
            $max_size = 10000;
            $log_filename = "log.xml";
            if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}
            file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND);
        }
    }
}


?>

mapbaidu.php

<?php

define ("DEBUG_MODE", false);
 var_dump(catchEntitiesFromLocation("银行", "22.123185", "113.23434", "5000"));
function catchEntitiesFromLocation($entity, $x, $y, $radius)
{
    $url = "http://api.map.baidu.com/place/v2/search?ak=MgBALVVeCd8THVBi6gPdvsvG&output=json&query=".$entity."&page_size=5&page_num=0&scope=2&location=".$x.",".$y."&radius=".$radius."&filter=sort_name:distance";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);

    $data = json_decode($output, true);

    if ($data['status'] != 0){
        return $data['message'];
    }

    $results = $data['results'];
    if (count($results) == 0){
        return "附近没有找到".$entity;
    }
    $shopArray = array();
    $shopArray[] = array("Title"=>"附近的".$entity, "Description"=>"", "PicUrl"=>"", "Url"=>"");
    for ($i = 0; $i < count($results); $i++) {
        $shopArray[] = array(
            "Title"=>"【".$results[$i]['name']."】<".$results[$i]['detail_info']['distance']."米>\n".$results[$i]['address'].
            (isset($results[$i]['telephone'])?"\n".$results[$i]['telephone']:""),
            "Description"=>"", 
            "PicUrl"=>"", 
            "Url"=>(isset($results[$i]['detail_info']['detail_url'])?($results[$i]['detail_info']['detail_url']):""));
    }
    return $shopArray;
}

?>

location.php

<?php

/*
DROP TABLE IF EXISTS `user`;
CREATE TABLE IF NOT EXISTS `user` (
  `openid` varchar(28) NOT NULL COMMENT '微信ID',
  `locationX` float default '0' COMMENT '纬度',
  `locationY` float default '0' COMMENT '经度',
  PRIMARY KEY (`openid`)
) ENGINE=MyISAM DEFAULT CHARSET=gbk;
*/


/*
{"ollB4jtmI_i8CqYlj-QMiuxx": {"locationX": "22.123","locationY": "113.23434"}}


var_dump($l);
var_dump($l["locationX"]);

setLocation("ollB4jtmI_i8CqYlj-QMiuxx", "22.123", "113.23434");
$l = getLocation("ollB4jtmI_i8CqYlj-QMiuxx");
var_dump($l);

setLocation("oDeOAjgSJUX10wvImSRMSwmyQAyA", "22.123", "113.23434");
$location = getLocation("oDeOAjgSJUX10wvImSRMSwmyQAyA");
var_dump($location);
*/
function setLocation($openid, $locationX, $locationY)
{
    $mmc = memcache_init();
    if($mmc == true){
        $location = array("locationX"=>$locationX, "locationY"=>$locationY);
        memcache_set($mmc, $openid, json_encode($location), 60);
        return "您的位置已缓存。\n现在可发送“附近”加目标的命令,如“附近酒店”,“附近加油站”。";
    }
    else{
        return "未启用缓存,请先开启服务器的缓存功能。";
    }
}

function getLocation($openid)
{
    $mmc = memcache_init();
    if($mmc == true){
        $location = memcache_get($mmc, $openid);
        if (!empty($location)){
            return json_decode($location,true);
        }else{
            return "请先发送位置给我!\n点击底部的'+'号,再选择'位置',等地图显示出来以后,点击'发送'";
        }
    }
    else{
        return "未启用缓存,请先开启服务器的缓存功能。";
    }
}

?>