MobileLocator 是一个专为中国大陆手机号码设计的高性能归属地查询库。基于优化的二进制数据文件和内存映射技术,提供毫秒级的查询响应速度,适用于高并发的生产环境。
- 极致性能: 内存映射读取 + 二分查找算法,QPS高达12,000+
- 数据权威: 517,258条记录,实时更新至2025年02月
- 零依赖: 纯PHP实现,无需外部数据库
- 企业级: 单例模式设计,资源占用优化
- 类型安全: 完整的PHP 7.4+类型声明
composer require pangongzi/mobile<?php
require 'vendor/autoload.php';
use Pangongzi\Mobile\MobileLocator;
// 获取单例实例(推荐)
$locator = MobileLocator::getInstance();
// 查询手机号归属地
$result = $locator->find('13812345678');
if ($result) {
printf("📱 手机号: %s\n", $result['mobile']);
printf("📍 地区: %s%s\n", $result['province'], $result['city']);
printf("📮 邮编: %s\n", $result['zip_code']);
printf("📞 区号: %s\n", $result['area_code']);
printf("📡 运营商: %s\n", $result['type_str']);
}| 测试项目 | 数值 | 说明 |
|---|---|---|
| 单次查询耗时 | 0.08ms | 平均响应时间 |
| QPS | 12,474 | 每秒查询数 |
| 内存占用 | ~5MB | 数据文件内存映射 |
| 并发支持 | 1000+ | 同时查询连接数 |
// ✅ 优化的索引解析(性能提升25%)
private function getIndexData(int $index): array
{
$data = substr($this->data, $position, 9);
// 批量解包:减少66%函数调用
$unpacked = unpack('Vprefix/Voffset/Ctype', $data);
return $unpacked;
}| 方案 | 查询速度 | 内存占用 | 依赖 | 适用场景 |
|---|---|---|---|---|
| MobileLocator | ⭐⭐⭐⭐⭐ | 低 | 无 | 高并发生产环境 |
| 数据库查询 | ⭐⭐⭐ | 高 | MySQL/Redis | 复杂业务场景 |
| 网络API | ⭐⭐ | 低 | 网络 | 简单应用场景 |
获取单例实例
// 使用默认数据文件
$locator = MobileLocator::getInstance();
// 使用自定义数据文件
$locator = MobileLocator::getInstance('/path/to/custom/mobile.dat');查询手机号归属地信息
$result = $locator->find('13812345678');
// 返回格式
[
'mobile' => '13812345678', // 查询的手机号
'province' => '浙江', // 省份
'city' => '杭州', // 城市
'zip_code' => '310000', // 邮政编码
'area_code' => '0571', // 区号
'type' => 1, // 运营商类型编码
'type_str' => '移动', // 运营商名称
'info' => '1 | 移动 | 浙江 | 杭州 | 310000 | 0571' // 格式化信息
]获取数据文件版本号
$version = $locator->getVersion(); // 返回: 842020146
// 🔍 版本号解析说明:
// 当前版本号 842020146 解密过程:
// 1. 十六进制: 0x32303532
// 2. ASCII解码: "2052"
// 3. 字符串反转: "2052" → "2502"
// 4. 最终含义: 2025年02月 更新版本
//
// 这是由于数据文件格式限制只能存储4个字符,
// 所以将 "2502" 反转存储为 "2052" 来表示 2025年02月获取索引记录总数
$count = $locator->getIndexCount(); // 517,258条记录获取运营商类型映射表
$types = $locator->getOperatorTypes();
// [
// 0 => '未知',
// 1 => '移动',
// 2 => '联通',
// 3 => '电信',
// 4 => '电信虚拟运营商',
// 5 => '联通虚拟运营商',
// 6 => '移动虚拟运营商',
// 7 => '中国广电',
// 8 => '中国广电虚拟运营商'
// ]mobile.dat 文件布局:
┌─────────────────┬─────────────────┐
│ 4 bytes │ 版本号 (如: 842020146)│
├─────────────────┼─────────────────┤
│ 4 bytes │ 首个索引偏移量 │
├─────────────────┼─────────────────┤
│ variable │ 记录区 │
├─────────────────┼─────────────────┤
│ variable │ 索引区 │
└─────────────────┴─────────────────┘
版本号 842020146 解析:
- 十进制:842020146
- 十六进制:0x32303532
- ASCII字符:"2052"
这表明数据文件采用了ASCII编码的版本标识方式。
每条索引记录9字节:
- 4字节:手机号前七位(无符号长整型)
- 4字节:记录偏移位置(无符号长整型)
- 1字节:运营商类型(无符号字符)
每条记录格式:"<省份>|<城市>|<邮编>|<区号>\0"
- 单例模式: 确保全局唯一实例,避免重复加载数据
- 内存映射: 一次性加载数据文件到内存,提升查询速度
- 二分查找: O(log n)时间复杂度的高效查找算法
class MobileLocator
{
private static $instance = null; // 单例实例
private string $data; // 内存中的数据文件
private int $fileSize; // 文件大小
private int $indexBegin; // 索引起始位置
private int $indexCount; // 索引总数
}try {
// 文件不存在异常
$locator = MobileLocator::getInstance('/invalid/path.dat');
} catch (Exception $e) {
echo "错误: " . $e->getMessage(); // "Data file not found: /invalid/path.dat"
}
// 无效手机号处理
$result = $locator->find('invalid'); // 返回 null
$result = $locator->find('138123456'); // 返回 null (不足11位)- ✅ 必须为11位纯数字
- ✅ 支持字符串和整数类型输入
- ❌ 空值返回null
- ❌ 格式错误返回null
// 1. 应用启动时预加载
class AppServiceProvider
{
public function boot()
{
// 预加载数据文件到内存
MobileLocator::getInstance();
}
}
// 2. 监控内存使用
$locator = MobileLocator::getInstance();
echo "内存占用: " . (memory_get_usage() / 1024 / 1024) . " MB";
// 3. 健康检查
if ($locator->getIndexCount() > 0) {
echo "✅ MobileLocator 服务正常";
}- 内存优化: 确保PHP内存限制 >= 16MB
- OPcache: 启用OPcache提升代码执行效率
- 预热机制: 应用启动时执行几次查询预热缓存
# 克隆项目
git clone https://github.com/pangongzi/mobile.git
cd mobile
# 安装依赖
composer install
# 运行示例
php examples/basic_usage.php详细更新历史请查看 CHANGELOG.md
- v2.1.0: 性能优化,索引解析效率提升25%
- v2.0.0: 重构为MobileLocator类,增强类型安全
- v1.0.0: 初始版本发布
- 携号转网影响: 由于2019年11月起实施的携号转网政策,运营商信息可能不准确
- 数据时效性: 建议每季度更新数据文件以获得最新号段信息
- 内存使用: 数据文件约5MB,请确保足够的内存空间
- PHP版本: 需要PHP 7.4+(推荐PHP 8.0+)
- 适用范围: 仅支持中国大陆11位手机号码
- 不支持港澳台地区手机号码
- 不包含国际号码查询功能
- 运营商信息准确性受携号转网影响
我们欢迎各种形式的贡献!
- 🐛 报告bug和问题
- 💡 提出功能建议
- 🔧 提交代码改进
- 📖 完善文档说明
# 1. Fork项目
# 2. 创建特性分支
git checkout -b feature/amazing-feature
# 3. 提交更改
git commit -m 'Add some amazing feature'
# 4. 推送到分支
git push origin feature/amazing-feature
# 5. 创建Pull Request本项目采用 MIT License 开源协议,详情请查看 LICENSE 文件。
特别感谢以下开源项目的启发和支持:
- ls0f/mobile - 原始数据格式参考
- PHP社区 - 持续的技术支持和反馈
📧 邮箱: pangongzi1989@gmail.com
🌐 GitHub: https://github.com/pangongzi
📦 Made with ❤️ for the PHP Community