Search by

youvision / think-regions

indiboy-create

ThinkPHP 8 省市区(县)街道四级联动扩展,支持中文、拼音、首字母搜索,内置数据安装命令。

Package info

github.com/indiboy-create/think-regions

pkg:composer/youvision/think-regions

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-11-08 19:13 UTC

This package is auto-updated.

Last update: 2026-11-11 03:18:47 UTC


README

面向 ThinkPHP 的开源工程索引:组件、框架、服务与发布工具,按能力组织,持续整理。 仓库地址:https://github.com/indiboy-create/ThinkPHP-PanGu/ 在线站点:https://indiboy-create.github.io/ThinkPHP-PanGu/

youvision/think-regions

ThinkPHP 8 省市区(县)街道四级联动扩展。

使用模型查询、服务注册、自动路由与独立安装命令,支持中文名称、拼音、首字母搜索。

特性

  • 四级联动:省、市、区(县)、街道,按 parent_id 逐级获取
  • 关键字搜索:支持中文、全拼、首字母
  • 模型查询:全部查询通过 ThinkPHP Model 完成,不直接写 Db:: 查询
  • 自动路由:服务启动时自动注册 /regions/* 接口,可通过配置关闭
  • 一键安装:内置 data/regions.csv,php think regions:install 自动建表并导入全国数据
  • 多数据源:支持远程或本地 CSV,适合内网离线部署
  • 配置化:表名、连接、字段、排序、缓存、搜索字段、路由前缀均可配置
  • 多数据库:建表逻辑支持 MySQL、SQLite、PostgreSQL、SQL Server
  • 门面与依赖注入:支持 Regions 门面、容器注入与直接实例化

环境要求

  • PHP >= 8.0
  • ThinkPHP 8
  • 数据库:MySQL / SQLite / PostgreSQL / SQL Server
  • PHP 扩展:pdo(可选 mbstring,用于自动识别 GBK 编码)

安装

composer require youvision/think-regions

服务通过 Composer 的 extra.think.services 声明。若项目配置了 service:discover,安装后会自动注册;也可手动执行:

php think service:discover

初始化数据

一键安装(推荐)

包内已内置 data/regions.csv,可直接执行安装;也可通过 csv_file、csv_url、--file 或 --url 指定其他数据源。

php think regions:install

该命令会:

  1. 检查数据表是否存在,不存在时自动创建;
  2. 表内没有数据时,优先使用 --file、--url、csv_file、csv_url,均未指定时使用包内 data/regions.csv;
  3. 表内已有数据时停止导入,避免误覆盖。

常用参数:

# 删除并重建数据表后重新导入
php think regions:install --force

# 使用本地 CSV 文件
php think regions:install --file=/data/regions.csv

# 临时指定远程 CSV 地址
php think regions:install --url=http://example.com/regions.csv

# 调整每批写入条数
php think regions:install --chunk=1000

CSV 首行建议包含表头,支持 id、pid、deep、name、pinyin_prefix、pinyin、ext_id、ext_name;也兼容旧字段名与无表头解析。编码支持 UTF-8 与 GBK。

配置

包内默认配置会在服务注册时自动合并,无需发布即可使用。需要修改默认值时:

php think regions:publish

配置文件会发布到项目 config/regions.php。目标文件已存在时跳过,追加 --force 可覆盖。

配置项 类型 默认值 说明
table string regions 数据表名,不含数据库前缀
connection string '' 数据库连接标识,留空使用默认连接
field string id,name,parent_id,level 列表查询返回字段
order string adcode asc,id asc 查询排序
cache int|false 86400 查询缓存秒数,false 关闭
cache_key string think-regions 查询缓存键前缀
search_fields array ['name','pinyin_prefix','pinyin','ext_name'] 关键字搜索字段,支持 CSV 字段名
max_level int 4 数据最大层级
level_names array 省/市/区县/街道 层级名称映射
route bool true 是否自动注册路由
route_prefix string regions 自动路由前缀
route_middleware array [] 自动路由中间件
csv_url string '' 远程 CSV 下载地址,为空时使用包内数据
csv_file string '' 本地 CSV 文件,非空时优先于 csv_url
chunk_size int 500 批量写入条数

以上配置均已在实际查询、建表、导入和路由注册流程中生效;getPath() 与 getAddress() 会自动使用必要字段,不受 field 限制。

路由

开启 route 后,服务会自动注册以下接口,默认前缀为 /regions,同时响应 GET 与 POST 请求:

地址 参数 说明
/regions/getRegion parent_id,默认 0 获取指定父级下的地区,0 返回省份
/regions/getProvince 无 获取省份
/regions/getCity parent_id 获取城市
/regions/getDistrict parent_id 获取区(县)
/regions/getStreet parent_id 获取街道
/regions/searchRegion keywords、parent_id 搜索地区
/regions/searchProvince keywords 搜索省份
/regions/searchCity keywords、parent_id 搜索城市
/regions/searchDistrict keywords、parent_id 搜索区(县)
/regions/searchStreet keywords、parent_id 搜索街道
/regions/getById id 根据主键获取单条地区
/regions/getByAdcode adcode 根据行政区划编码获取单条地区
/regions/getPath id 获取从省份到当前地区的路径
/regions/getAddress id、separator 获取完整地址名称

返回值为 JSON 数组,例如:

[
    { "id": 1, "name": "北京市", "parent_id": 0, "level": 1 }
]

手动注册路由

关闭自动路由:

// config/regions.php
'route' => false,

然后在路由文件中自行注册:

use think\facade\Route;
use Youvision\ThinkRegions\RegionController;

Route::group('regions', function () {
    Route::rule('getRegion', RegionController::class . '@getRegion', 'GET|POST');
    Route::rule('getProvince', RegionController::class . '@getProvince', 'GET|POST');
    Route::rule('getCity', RegionController::class . '@getCity', 'GET|POST');
    Route::rule('getDistrict', RegionController::class . '@getDistrict', 'GET|POST');
    Route::rule('getStreet', RegionController::class . '@getStreet', 'GET|POST');
    Route::rule('searchRegion', RegionController::class . '@searchRegion', 'GET|POST');
});

门面

use Youvision\ThinkRegions\Facade\Regions;

Regions::getProvince();
Regions::getCity(1);
Regions::getDistrict(2);
Regions::getStreet(3);
Regions::searchProvince('广东');
Regions::searchCity('sz', 1);
Regions::getById(4);
Regions::getByAdcode('440515');
Regions::getPath(4);
Regions::getAddress(4, '/');
Regions::getLevelName(4);

依赖注入

use Youvision\ThinkRegions\Regions;

class Address
{
    public function __construct(protected Regions $regions)
    {
    }

    public function cities(int $provinceId): array
    {
        return $this->regions->getCity($provinceId);
    }
}

直接实例化

use Youvision\ThinkRegions\Regions;

$regions = new Regions([
    'table'  => 'regions',
    'cache'  => false,
    'order'  => 'name asc',
]);

$provinces = $regions->getProvince();

数据格式

导入数据为 CSV,推荐使用以下格式:

id,pid,deep,name,pinyin_prefix,pinyin,ext_id,ext_name
11,0,0,"北京","b","bei jing","110000000000","北京市"
1101,11,1,"北京","b","bei jing","110100000000","北京市"
110101,1101,2,"东城","d","dong cheng","110101000000","东城区"

字段映射:

  • pid → parent_id
  • deep → level,导入时自动加 1(0 省、1 市、2 区县、3 街道)
  • ext_id → adcode
  • ext_name → name,无 ext_name 时回退到 name
  • pinyin_prefix → initial
  • pinyin 导入时自动去除空格
  • 缺少 citycode、lng_lat 时写入空字符串

兼容性:

  • 编码支持 UTF-8、GBK/GB18030
  • 表头支持英文字段名或常用中文表头,如“名称”“父级”“区域编码”
  • 无表头时按 id,pid,deep,name,pinyin_prefix,pinyin,ext_id,ext_name 顺序解析
  • 字段包含逗号、引号或换行时,使用双引号包裹并按 CSV 规则转义
  • 层级约定:1 省、2 市、3 区/县、4 街道

多应用模式

在多应用模式下,自动路由会注册为全局路由,前缀为 /regions。如果多个应用需要独立接口,建议:

  • 将 route_prefix 改为 api/regions、v1/regions 等;
  • 或关闭 route,在对应应用的路由文件中单独注册;
  • 不同应用使用不同的 table 或 connection 实现数据隔离。

数据库与缓存说明

  • 建表支持 MySQL、SQLite、PostgreSQL、SQL Server;索引会自动创建。
  • 导入数据使用事务与分批写入,SQLite、SQL Server 会根据绑定参数上限自动调小批次。
  • 查询缓存默认开启 1 天。重新导入数据后可清理 cache_key 前缀对应的缓存,或临时将 cache 设为 false。

示例

examples/region.html 是基于 layui 的四级联动与关键字搜索示例,将文件放入项目 public 目录后访问,并按需修改接口前缀。

测试

composer install
php -d extension=pdo_sqlite -d extension=sqlite3 vendor/bin/phpunit

测试使用 SQLite 内存数据库,覆盖逐级查询、中文/拼音/首字母搜索、路径与地址、配置项生效、本地 CSV 导入、编码与表头解析、建表与清空等场景。

许可

MIT