PHP格式化全国省市区列表

概述

本文提供基于 PHP(Yii 框架)的全国省市区列表格式化方案,通过数据库查询与递归重组,将扁平化的地区数据转换为层级化结构(省→市→区/县),同时支持缓存优化以提升系统性能,适用于地址选择、数据统计等场景。

代码

核心逻辑

  1. 从数据库表 CoreRegion 中查询关键字段(地区编码、地区名称、父级ID、地区层级);

  2. 通过递归函数 assembleRegionData 按父级ID关联,构建层级化数据结构;

  3. 自动移除无下级地区的空列表字段,优化返回数据格式。

完整代码

/**
 * 获取全国省市区列表(格式化后,层级结构)
 * @return array 层级化省市区数据
 */
public function getRegionList()
{
    // 从数据库查询地区基础数据,仅保留必要字段
    $data = CoreRegion::find()
        ->select(['national_code', 'region_name', 'parent_id', 'region_level'])
        ->asArray()
        ->all();

    // 重组数据为层级结构(默认从顶级父ID=0开始)
    $hierarchicalData = $this->assembleRegionData($data);

    return $hierarchicalData;
}

/**
 * 递归重组地区数据,构建层级结构
 * @param array $data 原始扁平化地区数据
 * @param int $pid 父级ID(默认顶级为0)
 * @return array 层级化子地区列表
 */
private function assembleRegionData($data, $pid = 0)
{
    $children = [];

    foreach ($data as $item) {
        // 匹配当前父级ID对应的子地区
        if ($item['parent_id'] == $pid) {
            // 递归查询当前地区的下级地区(以当前地区编码作为父级ID)
            $item['list'] = $this->assembleRegionData($data, $item['national_code']);

            // 若当前地区无下级,移除空列表字段,精简数据
            if (empty($item['list'])) {
                unset($item['list']);
            }

            $children[] = $item;
        }
    }

    return $children;
}

缓存优化方案(推荐)

优化原因

省市区数据属于静态数据(极少变动),频繁查询数据库会浪费资源、降低响应速度。通过 Redis 缓存格式化后的结果,可大幅提升性能。

优化逻辑

  1. 先从缓存中查询数据,若缓存存在且非空,直接返回;

  2. 若缓存不存在或已过期,查询数据库并格式化后,存入缓存再返回;

  3. 基于 Yii 框架缓存组件实现,默认支持 Redis 等缓存驱动。

优化后代码

/**
 * 获取全国省市区列表(缓存优化版)
 * @return array 层级化省市区数据
 */
public function getRegionList()
{
    // 缓存键名(自定义,确保唯一)
    $cacheKey = 'region_list_hierarchical';

    // 尝试从缓存中获取数据
    $cachedData = \Yii::$app->cache->get($cacheKey);

    // 缓存命中且数据有效,直接返回
    if (!empty($cachedData)) {
        return $cachedData;
    }

    // 缓存未命中,查询数据库并格式化
    $data = CoreRegion::find()
        ->select(['national_code', 'region_name', 'parent_id', 'region_level'])
        ->asArray()
        ->all();

    $hierarchicalData = $this->assembleRegionData($data);

    // 存入缓存(默认缓存有效期可在Yii配置中设置,建议长期缓存)
    \Yii::$app->cache->set($cacheKey, $hierarchicalData);

    return $hierarchicalData;
}

// 注:assembleRegionData 函数与基础版一致,无需修改
private function assembleRegionData($data, $pid = 0)
{
    // 同基础版代码...
}

补充说明

  • 缓存更新:如果省市区数据发生更新(如新增地区、调整编码),需手动清除缓存键 region_list_hierarchical,确保数据同步;

  • 缓存配置:需在 Yii 框架配置文件中正确配置缓存组件(如 Redis 连接信息),确保缓存功能正常。

数据支持

数据来源

省市区原始数据 SQL 文件可通过以下链接下载:省市区SQL文件

表结构核心字段说明

字段名 类型 说明
national_code varchar/int 地区唯一编码(作为子地区父ID)
region_name varchar 地区名称(省/市/区/县)
parent_id int 父级地区ID(顶级地区为0)
region_level tinyint 地区层级(1=省,2=市,3=区/县)