zhaiyuxin / japanpost
Fund package maintenance!
v1.0.0
2025-09-02 03:56 UTC
Requires
- guzzlehttp/guzzle: ^7.10
Requires (Dev)
- laravel/pint: ^1.24
- mockery/mockery: ^1.6
- orchestra/testbench: ^10.6
- pestphp/pest: ^4.0
- phpstan/phpstan: ^2.1
README
一个用于与日本邮政 API 交互的 PHP 包,提供地址查询、邮编搜索等功能。
✨ 特性
- 🔐 身份验证管理 - 自动处理 API 令牌获取和刷新
- 📍 地址查询 - 根据各种条件搜索日本地址信息
- 🏷️ 邮编搜索 - 通过邮编代码查找对应的地址信息
- 🚀 Laravel 集成 - 原生 Laravel 服务提供者支持
- 🎭 Facade 支持 - 统一的 Facade 接口,简化调用
- 🛡️ 异常处理 - 完善的错误处理和自定义异常
- ⚙️ 灵活配置 - 支持自定义 HTTP 客户端选项
- 💾 Token 缓存 - 自动缓存 API 令牌,提高性能
- 🌐 多环境支持 - 支持测试和生产环境切换
- 🔌 HTTP 抽象层 - 内置 HttpClient 封装,支持复用
📋 系统要求
- PHP >= 8.3
- Laravel >= 10.0
🚀 快速开始
通过 Composer 安装
composer require zhaiyuxin/japanpost
🔧 配置
环境变量
在您的 .env 文件中添加以下配置:
JAPANPOST_CLIENT_ID=your_client_id_here JAPANPOST_SECRET_KEY=your_secret_key_here JAPANPOST_BASE_URI=https://api.da.pf.japanpost.jp/
环境配置说明:
JAPANPOST_BASE_URI:API 基础 URL,支持测试和生产环境- 生产环境:
https://api.da.pf.japanpost.jp/(默认) - 测试环境:根据实际测试地址配置
- 生产环境:
配置文件
配置文件位于 config/services.php:
'japanpost' => [ 'client_id' => env('JAPANPOST_CLIENT_ID'), 'secret_key' => env('JAPANPOST_SECRET_KEY'), 'base_uri' => env('JAPANPOST_BASE_URI', 'https://api.da.pf.japanpost.jp/'), ],
📖 使用方法
🎭 Laravel Facade 使用
为了提供更简洁的 API,本包提供了一个统一的 Facade 接口。您可以通过 Facade 轻松访问所有服务:
use Yuxin\Japanpost\Facades\Japanpost; // 获取 Token 服务 $token = Japanpost::token()->getToken(); // 获取地址查询服务 $addresses = Japanpost::addressZip()->search([ 'prefecture' => '東京都', 'city' => '渋谷区', ]); // 获取邮编搜索服务 $addresses = Japanpost::searchCode()->search('150-0002');
Facade 优势:
- ✅ 统一接口:一个 Facade 访问所有服务
- ✅ 简洁语法:无需手动实例化或依赖注入
- ✅ 单例模式:每次调用返回相同的实例
- ✅ Laravel 集成:完美融入 Laravel 生态系统
- ✅ 类型提示:完整的 IDE 类型提示支持
1. 获取 API 令牌
use Yuxin\Japanpost\Token; use Psr\SimpleCache\CacheInterface; // 通过依赖注入获取(推荐,自动启用缓存) $token = app('japanpost.token')->getToken(); // 直接实例化(使用默认文件缓存) $tokenService = new Token($clientId, $secretKey, 'https://api.da.pf.japanpost.jp/'); $token = $tokenService->getToken(); // 自定义缓存实现 $tokenService = new Token($clientId, $secretKey, 'https://api.da.pf.japanpost.jp/', $cache); $token = $tokenService->getToken(); // 自定义 HTTP 客户端 use Yuxin\Japanpost\HttpClient; $httpClient = new HttpClient('https://api.da.pf.japanpost.jp/', ['timeout' => 30]); $tokenService = new Token($clientId, $secretKey, 'https://api.da.pf.japanpost.jp/', null, $httpClient); $token = $tokenService->getToken();
缓存机制:
- 自动缓存 API 令牌,默认缓存时间为 3600 秒(1小时)
- 使用 PSR-16 缓存标准,支持多种缓存实现
- Laravel 环境中自动使用 Laravel 缓存系统
- 独立使用时默认使用 Symfony 文件缓存
2. 地址查询
use Yuxin\Japanpost\AddressZip; // 通过依赖注入获取 $addressService = app('japanpost.address_zip'); // 搜索地址(page 默认 1,limit 默认 1000) $addresses = $addressService->search([ 'prefecture' => '東京都', 'city' => '渋谷区', 'street' => '渋谷', ], 1, 100); // 直接实例化 $addressService = new AddressZip($clientId, $secretKey, 'https://api.da.pf.japanpost.jp/', $token); $addresses = $addressService->search([ 'prefecture' => '東京都', 'city' => '渋谷区', ]);
3. 邮编搜索
use Yuxin\Japanpost\SearchCode; // 通过依赖注入获取 $searchService = app('japanpost.search_code'); // 通过邮编搜索地址 // 参数:code, page=1, limit=1000, choikitype=1, searchtype=1 $addresses = $searchService->search('150-0002', 1, 100); // 直接实例化 $searchService = new SearchCode($clientId, $secretKey, 'https://api.da.pf.japanpost.jp/', $token); $addresses = $searchService->search('150-0002');
SearchCode 参数说明:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
$code |
string | - | 邮编代码 |
$page |
int | 1 | 页码 |
$limit |
int | 1000 | 每页条数 |
$choikitype |
int | 1 | 町域类型 |
$searchtype |
int | 1 | 搜索类型 |
4. 自定义 HTTP 客户端
本包内置了 HttpClient 类,对 Guzzle HTTP 客户端进行了封装,支持客户端复用:
use Yuxin\Japanpost\HttpClient; // 创建自定义 HTTP 客户端 $httpClient = new HttpClient('https://api.da.pf.japanpost.jp/', [ 'timeout' => 30, 'verify' => false, 'headers' => [ 'User-Agent' => 'MyApp/1.0', ], ]); // 动态修改选项 $httpClient->setOptions(['timeout' => 60]); // 执行请求 $response = $httpClient->get('/api/v1/searchcode/150-0002'); $response = $httpClient->post('/api/v1/addresszip', ['json' => $data]);
也可以通过各服务类的 setGuzzleOptions() 方法配置:
$addressService = app('japanpost.address_zip'); $addressService->setGuzzleOptions([ 'timeout' => 30, 'verify' => false, 'headers' => [ 'User-Agent' => 'MyApp/1.0', ], ]);
5. 多环境配置示例
// 生产环境配置 $productionToken = new Token($clientId, $secretKey, 'https://api.da.pf.japanpost.jp/'); $productionAddress = new AddressZip($clientId, $secretKey, 'https://api.da.pf.japanpost.jp/', $token); $productionSearch = new SearchCode($clientId, $secretKey, 'https://api.da.pf.japanpost.jp/', $token); // 测试环境配置 $testBaseUri = 'https://test-api.example.com/'; $testToken = new Token($clientId, $secretKey, $testBaseUri); $testAddress = new AddressZip($clientId, $secretKey, $testBaseUri, $token); $testSearch = new SearchCode($clientId, $secretKey, $testBaseUri, $token);
🐛 异常处理
包提供了以下自定义异常:
Yuxin\Japanpost\Exceptions\HttpException- HTTP 请求异常Yuxin\Japanpost\Exceptions\AddressesNotFoundException- 地址未找到异常Yuxin\Japanpost\Exceptions\Exception- 通用异常
use Yuxin\Japanpost\Exceptions\AddressesNotFoundException; use Yuxin\Japanpost\Exceptions\HttpException; try { $addresses = $addressService->search(['prefecture' => '東京都']); } catch (AddressesNotFoundException $e) { // 处理地址未找到的情况 Log::warning('No addresses found for Tokyo'); } catch (HttpException $e) { // 处理 HTTP 错误 Log::error('HTTP error: ' . $e->getMessage()); }
🧪 测试
运行测试套件
composer test
运行代码质量检查
composer lint
代码重构检查
composer test:refactor # 预览 Rector 重构建议(dry-run) composer refactor # 执行 Rector 重构
测试框架
本项目使用 Pest PHP 作为测试框架,配合 Orchestra Testbench 进行 Laravel 包测试。
测试结构
tests/
├── Feature/ # 集成测试
│ ├── FacadeTest.php # Facade 功能测试
│ ├── IntegrationTest.php # 服务集成测试
│ └── ServiceProviderTest.php # 服务提供商测试
├── Unit/ # 单元测试
│ ├── AddressZipTest.php # AddressZip 类测试
│ ├── ExceptionsTest.php # 异常处理测试
│ ├── HelpersTest.php # 辅助函数测试
│ ├── SearchCodeTest.php # SearchCode 类测试
│ └── TokenTest.php # Token 类测试
├── Pest.php # Pest 配置文件
└── TestCase.php # 基础测试用例
测试特点
- 现代语法: 使用 Pest 的
test()和expect()函数 - 类型安全: 所有测试都包含严格类型声明
- 完整覆盖: 包含单元测试、集成测试和异常测试
- Laravel 集成: 使用 Orchestra Testbench 模拟 Laravel 环境
- 依赖注入: 完整测试 Laravel 服务容器绑定
- Facade 测试: 专门测试 Facade 功能和服务访问
编写测试示例
// 单元测试 test('token can be instantiated with required parameters', function () { $token = new Token('test_client_id', 'test_secret_key', 'https://api.da.pf.japanpost.jp/'); expect($token)->toBeInstanceOf(Token::class); }); // 集成测试 test('services can be used with dependency injection', function () { $token = app('japanpost.token'); $addressZip = app('japanpost.address_zip'); $searchCode = app('japanpost.search_code'); expect($token)->toBeInstanceOf(Token::class); expect($addressZip)->toBeInstanceOf(AddressZip::class); expect($searchCode)->toBeInstanceOf(SearchCode::class); });
测试覆盖率
目前测试覆盖率达到 100%,包含:
- ✅ 所有核心服务类的功能测试
- ✅ 异常处理和错误情况测试
- ✅ Laravel 服务提供商集成测试
- ✅ HTTP 客户端配置和选项测试
- ✅ 缓存机制测试
- ✅ Facade 功能和接口测试
- ✅ 辅助函数和工具类测试
🔧 开发
构建工作台
composer build
启动开发服务器
composer serve
📦 依赖
运行时依赖
| 包 | 版本 | 用途 |
|---|---|---|
guzzlehttp/guzzle |
^7.10 | HTTP 客户端 |
psr/simple-cache |
^3.0 | PSR-16 缓存接口 |
symfony/cache |
^7.3 | 默认缓存实现 |
开发依赖
| 包 | 版本 | 用途 |
|---|---|---|
pestphp/pest |
^4.0 | 测试框架 |
mockery/mockery |
^1.6 | Mock 库 |
laravel/pint |
^1.24 | 代码格式化 |
phpstan/phpstan |
^2.1 | 静态分析 |
orchestra/testbench |
^10.6 | Laravel 包测试 |
rector/rector |
^2.1 | 代码重构 |
🤝 贡献指南
欢迎提交 Issue 和 Pull Request!
- Fork 本项目
- 创建特性分支 (
git checkout -b feature/xxx) - 提交更改 (
git commit -m 'feat: add some xxx') - 推送到分支 (
git push origin feature/xxx) - 开启 Pull Request
📄 许可证
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。
📞 联系方式
- 项目主页: GitHub Repository
- 问题反馈: Issues
- 技术讨论: Discussions