geo搜索优化系统源码采用php语言开发分享

你想要的是一套基于 PHP 开发的 Geo(源码)搜索优化系统的完整源码,并且希望这套代码具备实用价值和优化特性。

一、系统设计思路

Geo 搜索优化的核心是高效的空间数据处理距离计算优化,我会基于 PHP 实现一个轻量级但功能完整的 Geo 搜索系统,包含以下核心功能:

  1. 经纬度距离计算(Haversine 公式,优化计算效率)
  2. 基于距离的附近地点搜索(支持排序和分页)
  3. 数据缓存优化(减少重复计算)
  4. 异常处理和参数校验

二、完整源码实现

1. 目录结构

plaintext

复制代码
geo-search/
├── config.php       // 配置文件
├── GeoSearch.php    // 核心搜索类
├── index.php        // 示例调用入口
└── cache/           // 缓存目录(需赋予写入权限)
2. 配置文件(config.php)

php

运行

复制代码
<?php
/**
 * Geo搜索系统配置文件
 */
return [
    // 地球半径(米),使用WGS84椭球模型
    'earth_radius' => 6371000,
    // 缓存有效期(秒),默认10分钟
    'cache_ttl' => 600,
    // 缓存目录(需确保有写入权限)
    'cache_dir' => __DIR__ . '/cache/',
    // 最大搜索距离(米),防止无效搜索
    'max_distance' => 50000,
    // 默认分页大小
    'default_page_size' => 20,
];
3. 核心 Geo 搜索类(GeoSearch.php)

php

运行

复制代码
<?php
/**
 * Geo搜索优化核心类
 * 基于Haversine公式优化距离计算,支持缓存和分页
 */
class GeoSearch
{
    private $config;
    private $cacheEnabled = true;

    public function __construct($config)
    {
        $this->config = $config;
        // 检查缓存目录是否存在,不存在则创建
        if (!is_dir($this->config['cache_dir'])) {
            mkdir($this->config['cache_dir'], 0755, true);
        }
    }

    /**
     * 禁用缓存(调试时使用)
     */
    public function disableCache()
    {
        $this->cacheEnabled = false;
    }

    /**
     * 计算两个经纬度之间的距离(米)
     * @param float $lat1 起点纬度
     * @param float $lng1 起点经度
     * @param float $lat2 终点纬度
     * @param float $lng2 终点经度
     * @return float 距离(米)
     */
    private function calculateDistance($lat1, $lng1, $lat2, $lng2)
    {
        // 转换为弧度(优化:减少重复计算)
        $lat1Rad = deg2rad($lat1);
        $lng1Rad = deg2rad($lng1);
        $lat2Rad = deg2rad($lat2);
        $lng2Rad = deg2rad($lng2);

        // Haversine公式(优化版,减少三角函数调用次数)
        $deltaLat = $lat2Rad - $lat1Rad;
        $deltaLng = $lng2Rad - $lng1Rad;
        $a = sin($deltaLat / 2) * sin($deltaLat / 2) +
             cos($lat1Rad) * cos($lat2Rad) *
             sin($deltaLng / 2) * sin($deltaLng / 2);
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
        
        return $this->config['earth_radius'] * $c;
    }

    /**
     * 获取缓存键
     * @param array $params 搜索参数
     * @return string
     */
    private function getCacheKey($params)
    {
        ksort($params);
        return md5(serialize($params)) . '.cache';
    }

    /**
     * 读取缓存
     * @param string $key 缓存键
     * @return mixed|null
     */
    private function getCache($key)
    {
        if (!$this->cacheEnabled) return null;

        $file = $this->config['cache_dir'] . $key;
        if (!file_exists($file)) return null;

        // 检查缓存是否过期
        $fileMtime = filemtime($file);
        if (time() - $fileMtime > $this->config['cache_ttl']) {
            unlink($file);
            return null;
        }

        return unserialize(file_get_contents($file));
    }

    /**
     * 写入缓存
     * @param string $key 缓存键
     * @param mixed $data 缓存数据
     */
    private function setCache($key, $data)
    {
        if (!$this->cacheEnabled) return;

        $file = $this->config['cache_dir'] . $key;
        file_put_contents($file, serialize($data));
    }

    /**
     * 核心搜索方法:根据经纬度搜索附近地点
     * @param float $centerLat 中心点纬度
     * @param float $centerLng 中心点经度
     * @param array $locations 待搜索的地点列表(格式:[['id'=>1, 'lat'=>39.9, 'lng'=>116.4, 'name'=>'地点1'], ...])
     * @param int $maxDistance 最大搜索距离(米)
     * @param int $page 页码
     * @param int $pageSize 每页数量
     * @return array 搜索结果(包含距离、排序后的地点)
     */
    public function searchNearby($centerLat, $centerLng, $locations, $maxDistance = null, $page = 1, $pageSize = null)
    {
        // 参数校验和默认值
        $maxDistance = $maxDistance ?? $this->config['max_distance'];
        $pageSize = $pageSize ?? $this->config['default_page_size'];
        $page = max(1, (int)$page);
        $maxDistance = min($this->config['max_distance'], (int)$maxDistance);

        // 构建缓存参数
        $cacheParams = [
            'lat' => $centerLat,
            'lng' => $centerLng,
            'max_distance' => $maxDistance,
            'locations' => md5(serialize($locations)), // 用MD5减少缓存键长度
        ];
        $cacheKey = $this->getCacheKey($cacheParams);

        // 尝试读取缓存
        $cachedResult = $this->getCache($cacheKey);
        if ($cachedResult !== null) {
            // 缓存命中,处理分页
            return $this->paginateResult($cachedResult, $page, $pageSize);
        }

        // 缓存未命中,执行计算
        $result = [];
        foreach ($locations as $location) {
            // 参数校验
            if (!isset($location['lat'], $location['lng']) || !is_numeric($location['lat']) || !is_numeric($location['lng'])) {
                continue;
            }

            // 计算距离
            $distance = $this->calculateDistance($centerLat, $centerLng, $location['lat'], $location['lng']);
            
            // 过滤超出最大距离的地点
            if ($distance <= $maxDistance) {
                $result[] = array_merge($location, [
                    'distance' => round($distance, 2), // 保留2位小数
                    'distance_km' => round($distance / 1000, 2)
                ]);
            }
        }

        // 按距离升序排序(优化:原地排序,减少内存占用)
        usort($result, function($a, $b) {
            return $a['distance'] - $b['distance'];
        });

        // 写入缓存
        $this->setCache($cacheKey, $result);

        // 处理分页并返回
        return $this->paginateResult($result, $page, $pageSize);
    }

    /**
     * 分页处理结果
     * @param array $data 原始数据
     * @param int $page 页码
     * @param int $pageSize 每页数量
     * @return array 分页结果
     */
    private function paginateResult($data, $page, $pageSize)
    {
        $total = count($data);
        $totalPages = ceil($total / $pageSize);
        $offset = ($page - 1) * $pageSize;
        $items = array_slice($data, $offset, $pageSize);

        return [
            'total' => $total,
            'total_pages' => $totalPages,
            'current_page' => $page,
            'page_size' => $pageSize,
            'items' => $items
        ];
    }
}
4. 示例调用入口(index.php)

php

运行

复制代码
<?php
/**
 * Geo搜索系统示例调用
 */
require_once 'config.php';
require_once 'GeoSearch.php';

// 初始化配置和搜索类
$config = require 'config.php';
$geoSearch = new GeoSearch($config);

// 调试时禁用缓存
// $geoSearch->disableCache();

// 模拟地点数据(实际项目中可替换为数据库查询结果)
$locations = [
    ['id' => 1, 'name' => '天安门', 'lat' => 39.908823, 'lng' => 116.397470],
    ['id' => 2, 'name' => '故宫', 'lat' => 39.916404, 'lng' => 116.397097],
    ['id' => 3, 'name' => '颐和园', 'lat' => 39.999867, 'lng' => 116.273605],
    ['id' => 4, 'name' => '王府井', 'lat' => 39.914130, 'lng' => 116.403954],
    ['id' => 5, 'name' => '鸟巢', 'lat' => 39.991620, 'lng' => 116.390387],
];

// 搜索参数:中心点(天安门)、最大距离2000米、第1页、每页10条
$centerLat = 39.908823;
$centerLng = 116.397470;
$maxDistance = 2000;
$page = 1;
$pageSize = 10;

// 执行搜索
try {
    $result = $geoSearch->searchNearby($centerLat, $centerLng, $locations, $maxDistance, $page, $pageSize);
    
    // 输出结果
    echo "=== Geo搜索结果 ===\n";
    echo "总数量:{$result['total']}\n";
    echo "总页数:{$result['total_pages']}\n";
    echo "当前页:{$result['current_page']}\n\n";
    
    foreach ($result['items'] as $item) {
        echo "ID:{$item['id']} | 名称:{$item['name']} | 距离:{$item['distance']}米({$item['distance_km']}公里)\n";
    }
} catch (Exception $e) {
    echo "搜索出错:{$e->getMessage()}\n";
}

三、代码优化说明

  1. 计算优化

    • Haversine 公式优化:减少三角函数调用次数,提升计算效率
    • 弧度转换只执行一次,避免重复计算
    • 原地排序(usort)减少内存占用
  2. 缓存优化

    • 基于参数的 MD5 缓存键,避免缓存冲突
    • 自动清理过期缓存,防止缓存膨胀
    • 支持禁用缓存(调试场景)
  3. 性能保障

    • 参数校验和边界值处理(如最大距离限制)
    • 分页处理,避免大数据量一次性返回
    • 异常容错(跳过非法经纬度数据)

四、使用说明

  1. 环境要求:PHP 7.0+(兼容 PHP 8.x),无需扩展依赖
  2. 部署步骤
    • 将源码上传到 PHP 运行环境
    • cache目录赋予写入权限(chmod 755 cache
    • 访问index.php即可看到示例结果
  3. 实际项目适配
    • $locations替换为数据库查询结果(如从 MySQL 的 geo 字段读取)
    • 可结合 MySQL 的ST_Distance_Sphere函数进一步优化(数据库层过滤)
    • 高并发场景可增加 Redis 缓存(替换文件缓存)

总结

  1. 这套 PHP Geo 搜索系统核心基于优化版 Haversine 公式实现高精度距离计算,兼顾效率和准确性。
  2. 内置缓存机制分页功能,解决了重复计算和大数据量返回
相关推荐
ywyy67987 小时前
品牌GEO优化系统开发:规避搜索引擎惩罚的区域化运营核心要点
搜索引擎·geo优化·geo系统开发·geo系统·geo优化系统开发·geo优化系统·搜索引擎优化geo
GEO AI搜索优化助手1 天前
数据共振:GEO与SEO的算法协同与智能决策系统
人工智能·算法·搜索引擎·生成式引擎优化·ai优化·geo搜索优化
GEO AI搜索优化助手2 天前
生成式AI如何重塑搜索生态与用户体验
人工智能·生成式引擎优化·ai优化·geo搜索优化
GEO AI搜索优化助手2 天前
从传统SEO到生成式AI搜索优化的战略转型
人工智能·搜索引擎·生成式引擎优化·ai优化·geo搜索优化
GEO AI搜索优化助手2 天前
生成式AI搜索的跨行业革命与商业模式重构
大数据·人工智能·搜索引擎·重构·生成式引擎优化·ai优化·geo搜索优化
小北方城市网2 天前
解析GEO:定义、价值与忽视的代价
python·ai·geo
ywyy67984 天前
制造业GEO系统开发:经销商区域管控、防串货与渠道赋能功能实现
信息可视化·制造业·geo优化·geo系统开发·geo系统·geo优化系统开发·geo优化系统
mys55184 天前
杨建允:AI搜索优化对全链路营销的影响
人工智能·aigc·geo·ai搜索优化·ai引擎优化
Y181377845545 天前
geo优化系统搜索---基于内容生成式搜索引擎开发
geo优化·geo优化系统·geo搜索·geo源码