sudiptpa/ipstack
Composer 安装命令:
composer require sudiptpa/ipstack
包简介
A simple package for IP to Location implementation with PHP.
README 文档
README
If this package has been useful to you, GitHub Sponsors is a simple way to support ongoing maintenance, improvements, and future releases.
A modern, PSR-based PHP client for the ipstack API.
Highlights
- PSR-18 transport architecture
- Factory-based client construction
- Typed result models (
IpstackResult,Country,Region, etc.) - Bulk lookup support (up to 50 IPs per request)
- Domain exceptions mapped from ipstack API error codes
Requirements
- PHP
8.3to8.5(>=8.3 <8.6) psr/http-clientpsr/http-factorypsr/http-message- A concrete PSR-18 client + PSR-17 factory implementation (for example
symfony/http-client+nyholm/psr7)
Installation
composer require sudiptpa/ipstack
Optional (for the PSR-18 quick-start adapter stack shown below):
composer require symfony/http-client nyholm/psr7
Architecture
Core layers:
Ipstack::factory()configures and builds the clientIpstackClientruns lookup operationsTransportInterfaceabstracts HTTP transport (Psr18Transportincluded)IpstackResultMappermaps API payloads to typed models
Main entry points:
Ipstack\\IpstackIpstack\\Factory\\IpstackFactoryIpstack\\Client\\IpstackClientIpstack\\Client\\Options
Quick Start (PSR-18)
<?php declare(strict_types=1); use Ipstack\Ipstack; use Nyholm\Psr7\Factory\Psr17Factory; use Symfony\Component\HttpClient\Psr18Client; $client = Ipstack::factory() ->withAccessKey('YOUR_ACCESS_KEY') ->withPsr18(new Psr18Client(), new Psr17Factory()) ->build(); $result = $client->lookup('8.8.8.8'); echo $result->formatted();
Full Usage Examples
1) Reusable bootstrap
use Ipstack\Client\IpstackClient; use Ipstack\Ipstack; use Nyholm\Psr7\Factory\Psr17Factory; use Symfony\Component\HttpClient\Psr18Client; function ipstackClient(string $accessKey): IpstackClient { return Ipstack::factory() ->withAccessKey($accessKey) ->withPsr18(new Psr18Client(), new Psr17Factory()) ->build(); }
2) Override base URL (advanced)
$client = Ipstack::factory() ->withAccessKey('YOUR_ACCESS_KEY') ->withBaseUrl('https://api.ipstack.com') ->withPsr18(new Psr18Client(), new Psr17Factory()) ->build();
3) Single IP lookup + options
use Ipstack\Client\Options; $options = Options::create() ->fields(['ip', 'country_name', 'region_name', 'city', 'zip']) ->language('en') ->security(true) ->hostname(true); $result = $client->lookup('8.8.8.8', $options); echo $result->ip . PHP_EOL; echo $result->formatted() . PHP_EOL; echo ($result->country->name ?? 'unknown') . PHP_EOL;
4) Requester IP (/check)
$result = $client->lookupRequester(); echo $result->ip . PHP_EOL;
5) Bulk lookup
$results = $client->lookupBulk(['8.8.8.8', '1.1.1.1']); echo 'count=' . count($results) . PHP_EOL; foreach ($results as $row) { echo $row->ip . ' => ' . $row->formatted() . PHP_EOL; }
Notes:
- Empty list returns an empty
Ipstack\\Model\\IpstackCollection - More than 50 IPs throws
Ipstack\\Exception\\IpstackException
6) Access raw payload and JSON output
$result = $client->lookup('8.8.8.8'); $raw = $result->raw(); $json = json_encode($result, JSON_PRETTY_PRINT); echo $json . PHP_EOL;
7) Custom transport (local smoke test)
use Ipstack\Ipstack; use Ipstack\Transport\TransportInterface; final class DemoTransport implements TransportInterface { public function get(string $url, array $query): array { return [ 'ip' => '8.8.8.8', 'country_name' => 'United States', 'country_code' => 'US', 'region_name' => 'California', 'region_code' => 'CA', 'city' => 'Mountain View', 'zip' => '94035', ]; } } $client = Ipstack::factory() ->withAccessKey('DUMMY_KEY') ->withTransport(new DemoTransport()) ->build(); echo $client->lookup('8.8.8.8')->formatted();
8) Typed exception handling
use Ipstack\Exception\ApiErrorException; use Ipstack\Exception\BatchNotSupportedException; use Ipstack\Exception\InvalidFieldsException; use Ipstack\Exception\InvalidResponseException; use Ipstack\Exception\IpstackException; use Ipstack\Exception\RateLimitException; use Ipstack\Exception\TooManyIpsException; use Ipstack\Exception\TransportException; try { $result = $client->lookup('8.8.8.8'); } catch (RateLimitException $e) { // 104 } catch (InvalidFieldsException $e) { // 301 } catch (TooManyIpsException $e) { // 302 } catch (BatchNotSupportedException $e) { // 303 } catch (TransportException | InvalidResponseException $e) { // network/HTTP/JSON transport failure } catch (ApiErrorException $e) { // other API-side errors } catch (IpstackException $e) { // any other library-level exception }
Models
lookup*() returns Ipstack\\Model\\IpstackResult with nested typed objects:
country(Country)region(Region)location(Location|null)connection(Connection|null)security(Security|null)routing(Routing|null)
Helpers:
$result->formatted()returns a readable location string$result->raw()returns original decoded payloadjson_encode($result)serializes raw payload (JsonSerializable)
Error Model
All package exceptions extend Ipstack\\Exception\\IpstackException.
Transport/response exceptions:
TransportExceptionInvalidResponseException
API exceptions:
ApiErrorException(base)RateLimitExceptionfor code104InvalidFieldsExceptionfor code301TooManyIpsExceptionfor code302BatchNotSupportedExceptionfor code303
Real API Smoke Test
Use an environment variable and run this one-liner:
IPSTACK_ACCESS_KEY=your_key php -r 'require "vendor/autoload.php"; $c=Ipstack\Ipstack::factory()->withAccessKey(getenv("IPSTACK_ACCESS_KEY"))->withPsr18(new Symfony\Component\HttpClient\Psr18Client(), new Nyholm\Psr7\Factory\Psr17Factory())->build(); echo $c->lookup("8.8.8.8")->formatted(), PHP_EOL;'
Troubleshooting
InvalidArgumentException: Access key is required.- Call
->withAccessKey('...')before->build().
- Call
InvalidArgumentException: No transport configured...- Configure either
->withPsr18(...)or->withTransport(...).
- Configure either
TransportException: Unexpected HTTP status ...- Check network access, endpoint, and ipstack key validity.
InvalidResponseException: Invalid JSON response- Usually an upstream/proxy response issue; inspect raw HTTP response.
RateLimitException(104)- Monthly/request quota reached on your ipstack account.
API Plan Notes
Some ipstack fields/features may depend on plan tier (for example security, hostname, and parts of connection/routing data). If a field is unavailable on your plan, ipstack may omit it or return an API error.
Breaking Changes
Compared to the legacy API style:
Sujip\\Ipstack\\Ipstackis replaced byIpstack\\Ipstack- Constructor-style usage is replaced by factory-style configuration
- Legacy root convenience accessors are replaced by typed result objects from lookup methods
secure()is no longer the documented toggle pattern- Transport wiring is explicit and PSR-based
- Bulk lookup is now
lookupBulk(array $ips)with a strict max of 50 IPs/request
Migration Guide (v1 -> v2)
Use this quick mapping to migrate legacy usage to the current API.
| v1 (legacy) | v2 (current) |
|---|---|
new Sujip\\Ipstack\\Ipstack($ip) |
Build once, then call lookup: Ipstack::factory()->withAccessKey(...)->withPsr18(...)->build()->lookup($ip) |
new Sujip\\Ipstack\\Ipstack($ip, $apiKey) |
Ipstack::factory()->withAccessKey($apiKey)->withPsr18(...)->build() |
$ipstack->country() |
$client->lookup($ip)->country->name |
$ipstack->region() |
$client->lookup($ip)->region->name |
$ipstack->city() |
$client->lookup($ip)->city |
$ipstack->formatted() |
$client->lookup($ip)->formatted() |
$ipstack->secure() |
Use configured base URL + transport: withBaseUrl(...) + withPsr18(...) |
| N/A (or ad-hoc loops) | Native bulk call: $client->lookupBulk([$ip1, $ip2]) |
| Generic runtime/API failures | Typed exception model (RateLimitException, InvalidFieldsException, TransportException, etc.) |
Suggested migration steps
- Replace direct constructor usage with factory-based client construction.
- Create one reusable
IpstackClientservice and inject it where needed. - Replace legacy convenience getters with
lookup()result model access. - Add typed exception handling around lookup calls.
- Add a smoke test (local fake transport + real API env test) before release.
Quality Gates
CI runs the following checks across PHP 8.3, 8.4, and 8.5:
composer testcomposer stan(onprefer-stablematrix jobs)
Development
composer test
composer stan
composer rector
composer rector:check
Changelog
See CHANGELOG.md for release notes (latest hardening release: v2.1.0).
Author
- Sujip Thapa (
sudiptpa@gmail.com)
License
MIT. See LICENSE.
sudiptpa/ipstack 适用场景与选型建议
sudiptpa/ipstack 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 26.67k 次下载、GitHub Stars 达 4, 最近一次更新时间为 2018 年 07 月 06 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「geoip」 「ip to location」 「ipstack」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 sudiptpa/ipstack 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 sudiptpa/ipstack 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 sudiptpa/ipstack 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A GeoIP decorator/processor for monolog
The official PHP library for apiip.net that allowing customers to automate IP address validation and geolocation lookup in websites, applications and back-office system. Visit our API docs at https://apiip.net/documentation
A Symfony2 Bundle to handle geographic location of your entities
PHP GeoIP client
Laravel geolocation with built-in fraud prevention, risk scoring, MFA triggers, IP blocking, threat intelligence, and security auditing. 6 providers (IP2Location.io, MaxMind, IpInfo, IpStack, IpApi, IpGeolocation), proxy/VPN/Tor detection, login tracking, timezone/currency personalization for Larave
A modern, feature-rich Laravel package for managing addresses with geocoding, validation, caching, and spatial operations. Perfect for e-commerce, CRM systems, and any application requiring robust address management.
统计信息
- 总下载量: 26.67k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 4
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2018-07-06