zoujingli/ip2region

ip2region v3.0 for PHP - 企业级 IP 地理位置查询库,支持 IPv4 和 IPv6,多种缓存策略,零依赖,开箱即用

Installs: 379 438

Dependents: 59

Suggesters: 0

Security: 0

Stars: 1 275

Watchers: 32

Forks: 206

Open Issues: 0

pkg:composer/zoujingli/ip2region

v3.0.5 2025-09-28 07:16 UTC

README

Latest Stable Version Total Downloads Monthly Downloads Daily Downloads PHP Version Require License

ip2region v3.0

🚀 企业级 IP 地理位置查询库支持 IPv4 和 IPv6,智能加载,零依赖,开箱即用

基于官方 ip2region 深度优化,专为 PHP 项目定制,提供毫秒级 IP 地理位置查询服务。支持 IPv4 和 IPv6 双协议查询,具备智能加载机制和错误处理,适用于企业级应用场景。

⚠️ 重要提示

  • IPv4 查询:✅ 开箱即用,无需下载
  • IPv6 查询:⚠️ 需要下载完整数据库(617MB),请使用 ./vendor/bin/ip2down download v6 命令下载

📢 v3.0 更新

  • 代码优化:工具代码减少 48.7%,更简洁高效
  • 开箱即用:IPv4 查询无需下载,直接使用内置数据库文件
  • 按需下载:IPv6 查询需要时再下载完整数据库
  • 多种缓存策略:支持 file、vectorIndex、content 三种缓存模式
  • 简化部署:直接使用未压缩的 xdb 文件,无需解压过程

💡 版本选择建议

  • V3.0:推荐使用,IPv4 开箱即用,IPv6 按需下载,自动缓存,代码更简洁

📦 核心特性

特性 描述
IPv4 支持 ✅ 开箱即用,内置数据库文件
IPv6 支持 ⚠️ 需要下载,完整数据库(617MB)
缓存策略 ✅ 支持 file、vectorIndex、content 三种模式
性能 ✅ 极快,微秒级响应
零依赖 ✅ 纯 PHP 实现,无需额外扩展
企业级 ✅ 完善的错误处理和性能监控

🎯 项目简介

ip2region 是一个高性能的 IP 地址定位库,支持 IPv4 和 IPv6 地址查询。通过多种缓存策略,实现了大数据库文件的高效管理,为企业和开发者提供准确、快速的 IP 地理位置查询服务。

V3.0 核心特性

  • 🚀 开箱即用:IPv4 查询无需下载,直接使用内置数据库文件
  • ⚠️ IPv6 需要下载:IPv6 查询需要下载完整数据库(617MB)
  • 多种缓存策略:支持 file、vectorIndex、content 三种缓存模式
  • 📦 简化部署:直接使用未压缩的 xdb 文件,无需解压过程

使用示例

echo ip2region('8.8.8.8'); 
// 输出:美国【Level3】

echo ip2region('114.114.114.114'); 
// 输出:中国江苏省南京市【114DNS】

✨ 核心特性

  • 🌍 双协议支持支持 IPv4 和 IPv6 地址查询,自动识别 IP 版本
  • ⚡ 高性能:基于官方 xdb 格式,查询速度极快,微秒级响应
  • 📦 零依赖:纯 PHP 实现,兼容 PHP 5.4+,无需额外扩展
  • 🚀 开箱即用:IPv4 查询无需下载,直接使用内置文件
  • ⚠️ IPv6 需要下载:IPv6 查询需要下载完整数据库(617MB)
  • 🔧 自定义数据库:支持自定义 IPv4/IPv6 数据库路径配置
  • 🔧 易集成:支持 Composer 安装,提供函数式和面向对象两种 API
  • 💾 智能加载:自动按优先级查找数据库文件,无需手动管理
  • ⚡ 多种缓存策略:支持 file、vectorIndex、content 三种缓存模式
  • 📦 简化部署:IPv4 使用未压缩数据库文件,无需解压过程
  • 🛡️ 企业级:完善的错误处理、异常管理和性能监控
  • 🔄 懒加载:IPv4/IPv6 查询器按需创建,优化内存使用
  • 📦 PHAR 支持:完全支持 PHAR 环境,自动检测并适配不同的文件系统,在 PHAR 中直接使用内置数据库

🏗️ 技术架构

自动加载机制

项目采用优化的 Composer 自动加载策略:

{
  "autoload": {
    "psr-4": {
      "ip2region\\": "src/ip2region/"
    },
    "classmap": [
      "src/Ip2Region.php"
    ],
    "files": [
      "function.php"
    ]
  }
}

设计特点

  • PSR-4 加载ip2region\xdb\* 类使用 PSR-4 标准自动加载
  • 全局类:主类 Ip2Region 使用全局命名空间,便于直接使用
  • 全局函数function.php 提供便捷的全局函数接口
  • 组件化:保持原有组件的命名空间和目录结构

类结构设计

Ip2Region (全局类)
├── 使用 ip2region\xdb\IPv4
├── 使用 ip2region\xdb\IPv6  
└── 使用 ip2region\xdb\Searcher

ip2region\xdb\* (组件类)
├── Util.php       # 工具类
├── IPv4.php       # IPv4 处理
├── IPv6.php       # IPv6 处理
└── Searcher.php   # 搜索引擎

工具集成

  • 工具类设计bin/ip2down 使用内置类实现数据库管理功能
  • 代码优化:工具代码减少 48.7%,更简洁高效
  • 减少依赖:移除独立的 DatabaseManager.php 文件
  • 简化维护:所有工具功能集中在一个文件中

📁 项目结构

ip2region/
├── src/                    # 核心源码
│   ├── Ip2Region.php      # 主类(全局命名空间)
│   └── ip2region/
│       └── xdb/
│           ├── Util.php       # 工具类(ip2region\xdb\Util)
│           ├── IPv4.php       # IPv4 处理类(ip2region\xdb\IPv4)
│           ├── IPv6.php       # IPv6 处理类(ip2region\xdb\IPv6)
│           └── Searcher.php   # 搜索引擎类(ip2region\xdb\Searcher)
├── db/                    # 数据库文件目录(已包含)
│   └── ip2region_v4.xdb          # IPv4 数据库文件(未压缩)
├── vendor/
│   └── bin/
│       └── ip2data/       # 完整数据库文件目录(需要下载)
│           ├── ip2region_v4.xdb   # IPv4 完整数据库文件
│           └── ip2region_v6.xdb   # IPv6 完整数据库文件 ⚠️ 需要下载
├── bin/                   # 命令行工具
│   └── ip2down            # 数据库下载管理工具(内置类实现,支持实时进度显示)
├── tests/                 # 测试文件
│   ├── demo.php           # 演示程序
│   └── quick_performance_test.php # 性能测试脚本
├── function.php           # 全局函数入口
├── composer.json          # Composer 配置
└── README.md              # 项目文档

💡 重要提示

  • IPv4 查询:✅ 开箱即用,项目已包含数据库文件
  • IPv6 查询:⚠️ 需要下载完整数据库(617MB),使用 ip2down download v6 命令
  • 自定义数据库:支持通过构造函数指定自定义数据库路径
  • 数据库文件:IPv4 使用未压缩 xdb 文件,IPv6 必须使用完整数据库

🆕 v3.0 新增功能

数据库管理

  • 内置数据库:IPv4 数据库直接包含在项目中,无需额外下载
  • 简化部署:使用未压缩的 xdb 文件,避免解压过程
  • 智能加载:自动按优先级查找数据库文件,简化使用

增强的 API

  • 双协议支持ip2region() 函数自动识别 IPv4/IPv6
  • 面向对象Ip2Region 类提供完整的面向对象接口
  • 批量查询batchSearch() 方法支持批量 IP 查询
  • 性能监控getStats()getMemoryUsage() 方法监控性能

企业级特性

  • 错误处理:完善的异常处理和错误提示
  • 并发安全:支持多进程/多线程安全使用
  • 缓存策略:支持文件、VectorIndex、完整数据三种缓存方式
  • PHP 5.4+ 兼容:完全兼容 PHP 5.4 及以上版本

🚀 快速开始

1. 通过 Composer 安装

# 安装 V3.0 版本(推荐,功能完整)
composer require zoujingli/ip2region:^3.0

2. 下载数据库文件

⚠️ 重要:IPv6 查询需要下载完整数据库文件(617MB)

IPv4 查询:✅ 开箱即用,无需下载 IPv6 查询:⚠️ 需要下载完整数据库文件

方法一:使用下载工具(推荐)

# 下载 IPv6 数据库(617MB,支持实时进度显示)
./vendor/bin/ip2down download v6

# 下载所有数据库
./vendor/bin/ip2down download all

# 查看已下载的文件
./vendor/bin/ip2down list

# 测试数据库功能
./vendor/bin/ip2down test

# 清除下载的数据库文件
./vendor/bin/ip2down clear

💡 开发环境提示: 如果在开发环境中遇到 ./vendor/bin/ip2down: No such file or directory 错误,可以使用以下命令:

# 方法1:直接使用 PHP 运行
php bin/ip2down download v6

# 方法2:创建符号链接
ln -sf ../../bin/ip2down vendor/bin/ip2down

方法二:手动下载

# 创建数据库目录
mkdir -p db

# 下载 IPv6 数据库(617MB,推荐使用 Gitee 镜像,国内访问更快)
wget -O db/ip2region_v6.xdb "https://gitee.com/lionsoul/ip2region/raw/master/data/ip2region_v6.xdb?lfs=1"

# 或者使用 curl(如果 wget 不可用)
curl -L -o db/ip2region_v6.xdb "https://gitee.com/lionsoul/ip2region/raw/master/data/ip2region_v6.xdb?lfs=1"

💡 下载提示

  • IPv4:已包含在项目中,无需下载
  • IPv6:推荐使用 Gitee 镜像,国内访问速度更快更稳定
  • 备用链接:如果 Gitee 不可用,可使用 GitHub 原始链接

方法二:使用下载工具(推荐)

# 下载 IPv6 数据库(617MB,支持实时进度显示)
./vendor/bin/ip2down download v6

# 或者下载所有数据库
./vendor/bin/ip2down download all

# 尝试自动下载(可能因网络问题失败)
composer download-db

# 查看已下载的文件
./vendor/bin/ip2down list

# 测试数据库功能
./vendor/bin/ip2down test

进度显示特性

  • 实时进度:显示下载速度和预计剩余时间
  • 自动估算:基于文件大小估算完成时间
  • 流式下载:避免大文件内存溢出
  • 断点续传:支持网络中断后重新下载

进度显示示例

正在下载 IPv6 数据库...
已下载: 9.3 MB - 4.65 MB/s - 预计剩余 127s
已下载: 22.62 MB - 5.65 MB/s - 预计剩余 102s
已下载: 41.84 MB - 6.97 MB/s - 预计剩余 80s
...
✅ 下载完成: IPv6 数据库 (617.1 MB)

📝 注意

  • IPv4 数据库可以正常自动下载(10.5MB)
  • IPv6 数据库较大(617MB),建议使用下载工具或手动下载

数据库优先级

系统按以下优先级查找数据库文件:

  1. 自定义数据库:通过构造函数指定的 .xdb 文件路径
  2. 下载的数据库:通过 ip2down 工具下载的完整数据库文件
  3. 默认路径db/ 目录下的内置文件(仅 IPv4)

⚠️ 重要

  • IPv4:使用未压缩 xdb 文件,开箱即用
  • IPv6:需要下载完整数据库文件(617MB)

3. 自定义数据库配置

项目已包含 IPv4 数据库文件,可直接使用。如需使用自定义数据库:

<?php
require 'vendor/autoload.php';

try {
    // 使用自定义数据库路径(建议使用绝对路径)
    $ip2region = new \Ip2Region('file', 
        '/path/to/your/ip2region_v4.xdb',  // IPv4 数据库路径
        '/path/to/your/ip2region_v6.xdb'   // IPv6 数据库路径
    );
    
    // 查询示例
    echo $ip2region->simple('61.142.118.231'); // 中国广东省中山市【电信】
    echo $ip2region->simple('2001:4860:4860::8888'); // Google DNS
?>

获取数据库文件

3. 一行代码开始使用

<?php
require 'vendor/autoload.php';

// 最简单的使用方式
echo ip2region('61.142.118.231') . "\n"; // 中国广东省中山市【电信】(使用内置数据库)
echo ip2region('2001:4860:4860::8888') . "\n"; // 美国加利福尼亚州圣克拉拉【专线用户】(需要下载完整数据库)

// 使用不同查询方法
echo ip2region('61.142.118.231', 'search'); // 中国|广东省|中山市|电信
echo ip2region('61.142.118.231', 'memory'); // 返回数组格式

// 或者使用类方式
$ip2region = new \Ip2Region();
echo $ip2region->simple('61.142.118.231'); // 中国广东省中山市【电信】
?>

4. 验证安装

# 运行演示程序
composer demo

# 查询指定 IP
composer query 61.142.118.231

# 批量查询 IP
composer query:batch "8.8.8.8,114.114.114.114"

# 运行性能测试
composer performance

在项目中快速调用

函数式调用

<?php
require 'vendor/autoload.php';

// 简单查询
echo ip2region('61.142.118.231') . "\n";        // 中国广东省中山市【电信】
echo ip2region('2001:4860:4860::8888') . "\n"; // 美国加利福尼亚州圣克拉拉【专线用户】

// 使用不同查询方法
echo ip2region('61.142.118.231', 'search') . "\n"; // 中国|广东省|中山市|电信
echo ip2region('61.142.118.231', 'memory') . "\n"; // 返回数组格式

// 批量查询
$ips = ['61.142.118.231', '114.114.114.114', '2001:4860:4860::8888'];
foreach ($ips as $ip) {
    echo "$ip => " . ip2region($ip) . "\n";
}
?>

面向对象调用

<?php
require 'vendor/autoload.php';

try {
    // 默认模式(使用内置数据库)
    $ip2region = new \Ip2Region();
    
    // 如需使用自定义数据库,请参考下面的"自定义数据库配置"部分
    // $ip2region = new \Ip2Region('file', '/path/to/your/ip2region_v4.xdb', '/path/to/your/ip2region_v6.xdb');

    // 基础查询
    echo $ip2region->simple('61.142.118.231') . "\n";
    echo $ip2region->search('2001:4860:4860::8888') . "\n";

    // 获取详细信息
    $info = $ip2region->getIpInfo('61.142.118.231');
    print_r($info);
    // 输出: Array(
    //   [country] => 中国
    //   [region] => 广东省
    //   [province] => 中山市
    //   [city] => 电信
    //   [isp] =>
    //   [ip] => 61.142.118.231
    //   [version] => v4
    // )

    // 批量查询
    $results = $ip2region->batchSearch(['61.142.118.231', '114.114.114.114']);
    print_r($results);

    // 性能监控
    $stats = $ip2region->getStats();
    echo "内存使用: " . $stats['memory_usage'] . " bytes\n";
    echo "IPv4 已加载: " . ($stats['v4_loaded'] ? '' : '') . "\n";
    echo "IPv6 已加载: " . ($stats['v6_loaded'] ? '' : '') . "\n";

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}
?>

自定义数据库配置

<?php
require 'vendor/autoload.php';

try {
    // 使用自定义数据库路径(建议使用绝对路径)
    $ip2region = new \Ip2Region('file', '/path/to/your/ip2region_v4.xdb', '/path/to/your/ip2region_v6.xdb');

    // 查询IP
    echo $ip2region->simple('8.8.8.8') . "\n";

    // 检查是否使用自定义数据库
    $customStatus = $ip2region->isUsingCustomDb();
    echo "IPv4 使用自定义数据库: " . ($customStatus['v4'] ? '' : '') . "\n";
    echo "IPv6 使用自定义数据库: " . ($customStatus['v6'] ? '' : '') . "\n";

    // 动态设置数据库路径
    $ip2region->setCustomDbPaths('/path/to/v4.xdb', '/path/to/v6.xdb');

    // 获取数据库配置信息
    $dbInfo = $ip2region->getDatabaseInfo();
    echo "IPv4 路径: " . ($dbInfo['custom_v4_path'] ?: '默认内置') . "\n";
    echo "IPv6 路径: " . ($dbInfo['custom_v6_path'] ?: '需要下载') . "\n";

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}
?>

数据库文件准备

数据库加载优先级

ip2region 库按照以下优先级自动查找数据库文件:

  1. 自动路径:通过构造函数指定的自定义数据库路径
  2. vendor 目录vendor/bin/ip2data/ 目录下的下载文件
  3. 默认路径db/ 目录下的内置文件(仅 IPv4)

使用预置数据库

项目已包含 IPv4 数据库文件,位于 db/ 目录:

  • ip2region_v4.xdb - IPv4 数据库文件(已包含)
  • IPv6 需要下载完整数据库文件

PHAR 环境使用

在 PHAR 环境中,ip2region 库会自动检测环境并调整数据库加载策略:

// PHAR 环境中的使用方式
$searcher = new Ip2Region(); // 默认文件缓存模式

// 或使用其他缓存策略
$searcher = new Ip2Region('vectorIndex'); // 向量索引模式
$searcher = new Ip2Region('content');     // 内容缓存模式

// IPv4 查询(使用内置数据库)
echo $searcher->simple('8.8.8.8'); // 美国【Level3】

// IPv6 查询(需要预先将数据库文件放入 PHAR)
echo $searcher->simple('2001:4860:4860::8888'); // 美国加利福尼亚州圣克拉拉【专线用户】

PHAR 环境特点

  • ✅ IPv4 查询:开箱即用,使用内置数据库
  • ⚠️ IPv6 查询:需要预先将 ip2region_v6.xdb 放入 PHAR 的 db/ 目录
  • 🔧 自定义路径:支持通过构造函数指定自定义数据库路径
  • 📦 自动检测:无需手动配置,库会自动检测 PHAR 环境

使用自定义数据库

如果需要使用自定义的数据库文件,请按以下步骤操作:

1. 获取完整数据库文件

重要:IPv4 数据库文件已包含在 db/ 目录,可直接使用:

db/
└── ip2region_v4.xdb    # IPv4 数据库文件(已包含)

文件说明

  • IPv4 数据库:已包含在 db/ 目录,可直接使用
  • IPv6 数据库:需要从官方仓库下载到 db/ 目录
  • 文件大小:IPv4 约 11MB,IPv6 约 617MB
  • 文件格式:必须是有效的 xdb 格式文件

获取数据库文件

  • 免费版本:从 ip2region 官方仓库 下载
  • IPv4 数据库:ip2region_v4.xdb (10.5MB)
  • IPv6 数据库:ip2region_v6.xdb (617MB)
  • 商业版本:从 ip2region 官网 购买或下载
  • 格式要求:确保下载的是 .xdb 格式,不是 .txt 或其他格式
  • 版本选择:建议使用最新版本以获得最准确的地理位置数据
  • 重要提醒:自定义数据库文件需要从官网下载或购买,确保使用正版数据源

2. 放置数据库文件

将下载的数据库文件放置到 db/ 目录:

db/
├── ip2region_v4.xdb    # IPv4 数据库文件(已包含)
└── ip2region_v6.xdb    # IPv6 数据库文件(需要下载)

3. 验证数据库文件

# 测试 IPv4 查询
$ composer query 8.8.8.8
美国【Level3】

# 测试 IPv6 查询(需要先下载 IPv6 数据库)
$ composer query 2001:4860:4860::8888
美国加利福尼亚州圣克拉拉【专线用户】

Composer 脚本

项目提供了便捷的 Composer 脚本命令:

核心功能

# 运行演示程序
composer demo

# 运行测试程序
composer test

# 查询单个 IP 地址
composer query 61.142.118.231

# 批量查询 IP 地址(逗号分隔)
composer query:batch "8.8.8.8,114.114.114.114,2001:4860:4860::8888"

数据库管理

# 下载所有数据库
composer download

# 下载 IPv4 数据库
composer download:v4

# 下载 IPv6 数据库(IPv6 需要完整数据库)
composer download:v6

工具命令

# 运行性能测试
composer performance

# 查看性能统计
composer stats

# 查看版本信息
composer version

API 参考

全局函数

ip2region($ip, $method = 'simple')

  • 功能:全局 IP 地理位置查询函数,提供统一的查询接口

  • 特性

    • 自动识别 IPv4/IPv6 地址类型
    • 支持多种查询方法和返回格式
    • 内置 IP 地址格式验证
    • 懒加载机制,按需初始化查询器
    • 异常安全,提供详细的错误信息
  • 参数

    • $ip (string) - IP 地址,支持 IPv4 和 IPv6 格式
    • $method (string) - 查询方法,可选值:simple, search, memory, binary, btree
  • 返回string|array|null - 查询结果,失败时返回 null

  • 异常:当 IP 地址格式无效时抛出 Exception

  • 示例

    // 简单查询(默认)
    echo ip2region('61.142.118.231');
    // 输出: 中国广东省中山市【电信】
    
    // 详细查询
    echo ip2region('61.142.118.231', 'search');
    // 输出: 中国|广东省|中山市|电信
    
    // 内存查询(返回数组)
    $result = ip2region('61.142.118.231', 'memory');
    // 输出: Array([city_id] => 0, [region] => 中国|广东省|中山市|电信)
    
    // IPv6 查询
    echo ip2region('2001:4860:4860::8888');
    // 输出: 美国加利福尼亚州圣克拉拉【专线用户】
    
    // 异常处理
    try {
        $result = ip2region('invalid-ip');
    } catch (Exception $e) {
        echo "错误: " . $e->getMessage();
        // 如果是 IPv6 查询失败,提示下载数据库
        if (strpos($e->getMessage(), 'IPv6') !== false) {
            echo "\n提示: IPv6 查询需要下载完整数据库,请运行: ./vendor/bin/ip2down download v6";
        }
    }

查询方法对比

方法名 描述 返回值类型 性能特点 适用场景 示例输出
simple 简单查询(默认) string 最快 一般查询,用户友好显示 中国广东省中山市【电信】
search 详细查询 string 需要原始数据格式 中国|广东省|中山市|电信
memory 内存查询 array 需要结构化数据 {"city_id":0,"region":"中国|广东省|中山市|电信"}
binary 二进制搜索 array 中等 有序数据快速查找 {"city_id":0,"region":"中国|广东省|中山市|电信"}
btree B 树索引 array 中等 大规模数据平衡查询 {"city_id":0,"region":"中国|广东省|中山市|电信"}

使用建议

  • 一般查询:使用 simple 方法,返回格式化的地理位置字符串
  • 数据处理:使用 search 方法,获取原始数据格式便于解析
  • 程序集成:使用 memory 方法,获取结构化数组数据
  • 性能优化:根据数据量选择 binarybtree 方法
  • 异常处理:始终使用 try-catch 包装函数调用
  • IPv6 支持:⚠️ IPv6 查询需要先下载完整数据库(617MB)

Ip2Region 类

构造函数

new Ip2Region($cachePolicy = 'file', $dbPathV4 = null, $dbPathV6 = null)
  • 参数

    • $cachePolicy (string) - 缓存策略:'file', 'vectorIndex', 'content'
    • $dbPathV4 (string|null) - IPv4 数据库文件路径,null 表示使用默认路径
    • $dbPathV6 (string|null) - IPv6 数据库文件路径,null 表示需要下载
  • 缓存策略说明

    • file:文件缓存模式(默认),适合大文件,内存占用少
    • vectorIndex:向量索引模式,减少 IO 操作,提升查询速度
    • content:内容缓存模式,零 IO 操作,但占用更多内存
  • 示例

    // 默认文件缓存模式
    $ip2region = new Ip2Region();
    
    // 向量索引缓存模式(减少 IO 操作)
    $ip2region = new Ip2Region('vectorIndex');
    
    // 内容缓存模式(零 IO,但占用更多内存)
    $ip2region = new Ip2Region('content');
    
    // 使用自定义数据库路径
    $ip2region = new Ip2Region('file', '/path/to/your/ip2region_v4.xdb', '/path/to/your/ip2region_v6.xdb');
    
    // 自定义缓存策略 + 自定义数据库路径
    $ip2region = new Ip2Region('vectorIndex', '/path/to/v4.xdb', '/path/to/v6.xdb');

核心查询方法

simple($ip)
  • 功能:简单查询,返回格式化结果
  • 参数$ip (string) - IP 地址
  • 返回string|null - 格式化查询结果
  • 示例$ip2region->simple('61.142.118.231'); // 中国广东省中山市【电信】
search($ip)
  • 功能:基础查询,返回原始结果
  • 参数$ip (string) - IP 地址
  • 返回string|null - 原始查询结果
  • 示例$ip2region->search('61.142.118.231'); // 中国|广东省|中山市|电信
memorySearch($ip)
  • 功能:内存查询,返回数组格式
  • 参数$ip (string) - IP 地址
  • 返回array - 包含 city_id 和 region 的数组
  • 示例$ip2region->memorySearch('61.142.118.231'); // ['city_id' => 0, 'region' => '中国|广东省|中山市|电信']
batchSearch($ips)
  • 功能:批量查询多个 IP
  • 参数$ips (array) - IP 地址数组
  • 返回array - IP 地址为键的查询结果数组
  • 示例$ip2region->batchSearch(['61.142.118.231', '114.114.114.114']);
getIpInfo($ip)
  • 功能:获取详细的 IP 信息
  • 参数$ip (string) - IP 地址
  • 返回array|null - 包含 country, region, province, city, isp, ip, version 的数组
  • 示例$ip2region->getIpInfo('61.142.118.231');

兼容性方法

binarySearch($ip)
  • 功能:二进制搜索(兼容旧版本)
  • 参数$ip (string) - IP 地址
  • 返回array - 查询结果数组
btreeSearch($ip)
  • 功能:B 树搜索(兼容旧版本)
  • 参数$ip (string) - IP 地址
  • 返回array - 查询结果数组
searchByBytes($ipBytes)
  • 功能:二进制字节搜索
  • 参数$ipBytes (string) - 二进制 IP 地址
  • 返回string|null - 查询结果

工具方法

getStats()
  • 功能:获取统计信息
  • 返回array - 包含内存使用、IO 计数、加载状态等
  • 示例$stats = $ip2region->getStats();
getMemoryUsage()
  • 功能:获取内存使用情况
  • 返回array - 包含当前内存、峰值内存、加载状态等
  • 示例$memory = $ip2region->getMemoryUsage();
getIOCount()
  • 功能:获取 IO 计数
  • 返回array - 包含 IPv4、IPv6 和总 IO 计数
  • 示例$io = $ip2region->getIOCount();
getProtocolVersion($ip)
  • 功能:获取 IP 协议版本
  • 参数$ip (string) - IP 地址
  • 返回string - 'v4', 'v6' 或 'unknown'
isIPv4Supported()
  • 功能:检查是否支持 IPv4
  • 返回bool - 是否支持 IPv4
isIPv6Supported()
  • 功能:检查是否支持 IPv6
  • 返回bool - 是否支持 IPv6
getDatabaseInfo()
  • 功能:获取数据库信息
  • 返回array - 包含加载状态、缓存策略、版本信息、自定义路径等
setCustomDbPaths($v4Path, $v6Path)
  • 功能:动态设置自定义数据库路径
  • 参数
    • $v4Path (string|null) - IPv4 数据库文件路径
    • $v6Path (string|null) - IPv6 数据库文件路径
  • 示例$ip2region->setCustomDbPaths('/path/to/v4.xdb', '/path/to/v6.xdb');
isUsingCustomDb()
  • 功能:检查是否使用自定义数据库
  • 返回array - 包含 IPv4 和 IPv6 的使用状态
  • 示例$status = $ip2region->isUsingCustomDb();
getCustomDbInfo()
  • 功能:获取自定义数据库文件信息
  • 返回array - 包含自定义数据库文件的大小、修改时间等信息
  • 示例$info = $ip2region->getCustomDbInfo();

静态方法

Ip2Region::getStats()
  • 功能:获取性能统计信息
  • 返回array - 包含内存使用、IO次数、加载状态等信息的数组
  • 示例$stats = $searcher->getStats();
Ip2Region::getDatabaseInfo()
  • 功能:获取数据库信息
  • 返回array - 包含数据库加载状态、缓存策略、自定义路径等信息的数组
  • 示例$info = $searcher->getDatabaseInfo();

性能监控示例

<?php
require 'vendor/autoload.php';

try {
    // 默认模式(使用内置数据库)
    $ip2region = new \Ip2Region();
    
    // 或者使用自定义数据库(建议使用绝对路径)
    // $ip2region = new \Ip2Region('file', '/path/to/your/ip2region_v4.xdb', '/path/to/your/ip2region_v6.xdb');

    // 查询前状态
    $statsBefore = $ip2region->getStats();
    echo "查询前内存使用: " . $statsBefore['memory_usage'] . " bytes\n";

    // 执行查询
    $result = $ip2region->simple('61.142.118.231');
    echo "查询结果: " . $result . "\n";

    // 查询后状态
    $statsAfter = $ip2region->getStats();
    echo "查询后内存使用: " . $statsAfter['memory_usage'] . " bytes\n";
    echo "IPv4 已加载: " . ($statsAfter['v4_loaded'] ? '' : '') . "\n";
    echo "IPv6 已加载: " . ($statsAfter['v6_loaded'] ? '' : '') . "\n";
    echo "IPv4 IO 次数: " . $statsAfter['v4_io_count'] . "\n";
    echo "IPv6 IO 次数: " . $statsAfter['v6_io_count'] . "\n";

    // 内存使用详情
    $memory = $ip2region->getMemoryUsage();
    echo "当前内存: " . $memory['current'] . "\n";
    echo "峰值内存: " . $memory['peak'] . "\n";

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}
?>

缓存管理示例

<?php
require 'vendor/autoload.php';

// 获取缓存统计信息
$dbInfo = $searcher->getDatabaseInfo();
echo "IPv4已加载: " . ($dbInfo['v4_loaded'] ? '' : '') . "\n";
echo "IPv6已加载: " . ($dbInfo['v6_loaded'] ? '' : '') . "\n";
echo "缓存策略: " . $dbInfo['cache_policy'] . "\n";

// 获取性能统计
$stats = $searcher->getStats();
echo "内存使用: " . round($stats['memory_usage'] / 1024 / 1024, 2) . " MB\n";
echo "缓存策略: " . $stats['cache_policy'] . "\n";
?>

FPM 环境优化

缓存策略优化

ip2region 支持三种缓存策略,可根据不同使用场景选择最优策略:

缓存策略说明

  1. file 模式(默认):

    • 适合大文件,内存占用少
    • 首次查询较慢,后续查询快
    • 适合单次查询或低频查询场景
  2. vectorIndex 模式

    • 减少 IO 操作,提升查询速度
    • 内存占用适中
    • 适合频繁查询场景
  3. content 模式

    • 零 IO 操作,查询最快
    • 占用大量内存
    • 适合高并发场景

使用示例

<?php
// 文件缓存模式(默认)
$searcher = new Ip2Region('file');

// 向量索引模式
$searcher = new Ip2Region('vectorIndex');

// 内容缓存模式
$searcher = new Ip2Region('content');

// 查询 IP
echo $searcher->simple('8.8.8.8');
?>

性能对比

缓存策略 内存使用 IO 次数 查询速度 适用场景
file 中等 单次查询
vectorIndex 中等 频繁查询
content 最快 高并发

性能测试

快速性能测试

运行 composer performance 进行快速性能测试:

composer performance

测试结果示例

测试环境信息:
==================
操作系统: Darwin 25.0.0
PHP版本: 8.1.29
内存限制: 128M
最大执行时间: 0秒
时区: UTC
当前时间: 2025-09-18 02:46:44
系统负载: 4.05, 3.18, 2.77
当前内存使用: 4MB
峰值内存使用: 4MB
磁盘空间: 587.81GB 可用 / 926.35GB 总计
CPU: Apple M4 Pro
CPU核心数: 14

首次加载 vs 缓存命中:
  IPv4: 32.02ms → 0.5ms (提升 98.4%) (new Ip2Region() + simple())
  IPv6: 1174.68ms → 1.03ms (提升 99.9%) (new Ip2Region() + simple())

查询方法性能:
  simple: 0.17ms (ip2region->simple())
  search: 0.01ms (ip2region->search())
  memorySearch: 0.01ms (ip2region->memorySearch())

批量处理性能:
  10个IP: 0.73ms (ip2region->batchSearch())
  10000个IP: 99.67ms (ip2region->batchSearch())
  10000次循环: 54.09ms (10000次 ip2region->simple())

QPS性能:
  10个IP: 13699 QPS
  10000个IP: 100331 QPS
  10000次循环: 184877 QPS

性能监控:
  统计信息: 0.01ms (getStats() + getDatabaseInfo())

性能评分: 100/100
性能等级: 优秀 ⭐⭐⭐⭐⭐

性能测试内容

快速性能测试包含以下项目:

  • 首次加载测试(无缓存)
  • 缓存命中测试
  • 不同查询方法性能对比
  • 批量查询测试(10个IP + 10000个IP)
  • 循环查询测试(10000次)
  • 内存使用测试
  • 缓存清理性能测试
  • 系统环境信息展示
  • 性能评分和等级评定

性能特点

测试环境

  • 硬件配置:Apple M4 Pro (14核心),16GB+ 内存
  • 操作系统:macOS 15.0 (Darwin 25.0.0)
  • PHP版本:8.1.29
  • 磁盘空间:587GB+ 可用空间

性能指标

  1. 首次加载:直接使用数据库文件,IPv4 约 0.59ms,IPv6 约 0.16ms (new Ip2Region() + simple())
  2. 后续查询:直接使用数据库文件,IPv4 约 0.03ms,IPv6 约 0.03ms (new Ip2Region() + simple())
  3. 性能表现:查询速度快,内存占用低
  4. 查询方法
    • simple():约 0.02ms (格式化输出)
    • search():约 0.01ms (原始数据)
    • memorySearch():约 0.01ms (数组格式)
  5. 批量查询
    • 10个IP:约 0.73ms (13699 QPS) (ip2region->batchSearch())
    • 10000个IP:约 99.67ms (100331 QPS) (ip2region->batchSearch())
    • 10000次循环:约 54.09ms (184877 QPS) (10000次 ip2region->simple())
  6. 内存使用:当前 4MB,峰值 4MB
  7. 性能监控:约 0.01ms (getStats() + getDatabaseInfo())
  8. 性能评分:100/100 (优秀 ⭐⭐⭐⭐⭐)

最新性能测试结果 (2025-09-25)

测试环境

  • 操作系统:Darwin 25.0.0 (macOS)
  • PHP版本:8.1.29
  • CPU:Apple M4 Pro (14核心)
  • 内存:4MB (峰值4MB)

详细性能数据

  • IPv4查询:平均 0.006ms,QPS 167,972
  • IPv6查询:平均 0.013ms,QPS 75,819
  • IO统计:IPv4 IO 3次,IPv6 IO 3次,总IO 6次
  • 内存效率:极低内存占用,仅4MB
  • 缓存性能:首次加载后缓存命中率接近100%

性能等级说明

  • 90-100分:优秀 ⭐⭐⭐⭐⭐ (企业级性能)
  • 80-89分:良好 ⭐⭐⭐⭐ (生产环境推荐)
  • 70-79分:中等 ⭐⭐⭐ (一般应用)
  • 60-69分:及格 ⭐⭐ (基础应用)
  • 0-59分:需要优化 ⭐ (性能不足)

故障排除

常见问题

1. 数据库文件不存在

错误信息数据库文件不存在: /path/to/ip2region_v4.xdb 解决方案

  • 检查文件位置:确保 IPv4 源数据库文件存在于 tools/ 目录下
  • 检查文件名:IPv4 源文件必须严格按照 ip2region_v4.xdb 命名
  • 检查文件权限:确保文件可读
  • 下载 IPv6 数据库:从官方仓库下载 IPv6 的 .xdb 文件到 tools/ 目录
  • 获取数据源
  • 数据库文件:直接使用未压缩的 xdb 文件,无需额外处理

文件摆放检查

# 检查文件是否存在
ls -la db/ip2region_v*.xdb*

# 应该看到类似输出:
# -rw-r--r-- 1 user staff 11042429 Dec 19 10:00 db/ip2region_v4.xdb
# -rw-r--r-- 1 user staff 617000000 Dec 19 10:00 db/ip2region_v6.xdb

2. 内存不足

错误信息Fatal error: Allowed memory size exhausted 解决方案

  • 增加 PHP 内存限制:ini_set('memory_limit', '256M');
  • 使用文件缓存策略:new Ip2Region('file')
  • 检查数据库文件是否完整

3. 数据库文件损坏

错误信息数据库文件不存在无法读取数据库文件 解决方案

  • 检查 db/ 目录下的数据库文件是否完整
  • 重新下载数据库文件:./vendor/bin/ip2down download v4
  • 检查文件权限是否正确

4. 并发使用问题

错误信息Too many open files 解决方案

  • 每个进程/线程创建独立的 Ip2Region 实例
  • 增加系统文件描述符限制
  • 使用内存缓存策略:new Ip2Region('content')

性能优化建议

  1. 选择合适的缓存策略

    • file 模式:适合大文件,内存占用少,首次查询较慢
    • vectorIndex 模式:减少 IO 操作,提升查询速度,内存占用适中
    • content 模式:零 IO 操作,查询最快,但占用大量内存
  2. 根据使用场景选择

    • 单次查询:使用 file 策略
    • 频繁查询:使用 vectorIndex 策略
    • 高并发:使用 content 策略
  3. 批量查询优化

    • 使用 batchSearch() 方法进行批量查询
    • 避免在循环中重复创建实例
  4. 内存管理

    • 定期清理过期缓存
    • 监控内存使用情况
    • 使用懒加载特性
  5. 文件管理

    • 定期检查文件完整性
    • 使用 getStats() 监控性能状态
    • 根据使用场景选择合适的缓存策略
  6. 性能优化建议

    • 选择合适的缓存策略:根据使用场景选择 file、vectorIndex 或 content 模式
    • 定期检查文件完整性:确保数据库文件完整无损
    • 监控内存使用:根据内存情况选择合适的缓存策略

许可证

本项目基于 Apache-2.0 许可证开源。

🔧 通用查询函数

IP2Region 提供了通用的 ip2region() 函数,支持多种查询方法:

函数签名

ip2region(string $ip, string $method = 'simple'): string|array|null

支持的查询方法

方法 描述 返回值 示例
simple 简单查询(默认) 格式化的地理位置字符串 "美国【Level3】"
search 详细查询 管道分隔的详细信息 "美国|0|0|Level3"
binary 二进制查询 原始二进制数据 二进制字符串
btree B 树查询 B 树索引查询结果 查询结果字符串
memory 内存查询 内存中的查询结果 查询结果字符串

使用示例

<?php
require 'vendor/autoload.php';

// 简单查询(默认方法)
echo ip2region('61.142.118.231'); // 输出: 中国广东省中山市【电信】

// 详细查询
echo ip2region('61.142.118.231', 'search'); // 输出: 中国|广东省|中山市|电信

// 内存查询(返回数组)
$result = ip2region('61.142.118.231', 'memory');
print_r($result); // 输出: Array([city_id] => 0, [region] => 中国|广东省|中山市|电信)

// IPv6查询
echo ip2region('2001:4860:4860::8888'); // 输出: 美国加利福尼亚州圣克拉拉【专线用户】

// 异常安全
$result = ip2region('invalid-ip'); // 返回: null
if ($result === null) {
    echo "IP地址无效或查询失败";
}

特性说明

  • 自动识别:自动识别 IPv4 和 IPv6 地址
  • 多种缓存策略:支持 file、vectorIndex、content 三种缓存模式
  • 智能加载:自动按优先级查找数据库文件
  • 异常安全:查询失败返回 null,不会抛出异常
  • 静态实例:使用静态实例,避免重复初始化
  • IPv6 支持:⚠️ IPv6 查询需要先下载完整数据库(617MB)

📚 相关文档

贡献

欢迎提交 Issue 和 Pull Request 来改进这个项目。

联系方式

如有问题或建议,请通过以下方式联系: