germania-kg / ipstack
支持PSR-6缓存和Slim3中间件的ipstack API的PHP客户端
Requires
- php: ^7.0|^8.0
- guzzlehttp/guzzle: ^6.3|^7.0
- psr/cache: ^1.0
- psr/http-server-middleware: ^1.0
Requires (Dev)
- php-coveralls/php-coveralls: ^2.0
- phpspec/prophecy-phpunit: ^2.0
- phpunit/phpunit: ^9.0
- symfony/cache: ^5.0
README
带有缓存支持和中间件的ipstack API的PHP客户端
安装
$ composer require germania-kg/ipstack
使用ipstack
<?php use Germania\IpstackClient\IpstackClient; // Setup the Client $endpoint = "http://api.ipstack.com/"; $api_key = "your_api_key"; $ipstack = new IpstackClient( $endpoint, $api_key); // Ask ipstack $client_ip = "8.8.8.8"; $response = $ipstack->get( $client_ip );
响应示例
IpstackClient内部使用数组工作,因此要求ipstack返回JSON。以下是一个简化的示例;完整示例请参见ipstack在标准IP查找方面的文档
Array ()
[ip] => 8.8.8.8
[type] => ipv4
[continent_code] => EU
[continent_name] => Europe
[country_code] => DE
[country_name] => Germany
[region_code] => SH
[region_name] => Schleswig-Holstein
[latitude] => 54.3667
[longitude] => 10.2
...
)
自定义响应
您可以通过向底层请求添加某些字段来自定义ipstack响应,如ipstack在“指定响应字段”文档中所述。只需传递一个包含查询字段的数组,这些字段将添加到GET请求中
$response = $ipstack->get( "8.8.8.8", array( 'language' => "de", 'fields' => "ip,country_code,country_name,latitude,longitude,region_name" ));
缓存ipstack响应
如果您正在使用每月限制为10,000个请求的ipstack 免费计划,您可能希望通过将查找结果保存到PSR-6缓存来节省请求。 IpstackClientPsr6CacheDecorator 实现了 IpstackClientInterface,因此可以透明地替换 IpstackClient。
其构造函数接受您的 IpstackClient 实例和一个 PSR-6 CacheItemPool 实例。此示例使用Stash的缓存实现
<?php use Germania\IpstackClient\IpstackClientPsr6CacheDecorator; use Germania\IpstackClient\IpstackClient; use Stash\Pool as CacheItemPool; // Setup your client as shown above $ipstack = new IpstackClient( $endpoint, $api_key); // Example cache $cache = new \Stash\Pool( new \Stash\Driver\Sqlite( array('path' => "/tmp" )) ); // Setup the decorator $caching_ipstack = new IpstackClientPsr6CacheDecorator($ipstack, $cache); // Optional: Set lifetime in seconds (or null) $caching_ipstack->setCacheLifeTime( 3600 ); // Use as usual $response = $caching_ipstack->get( "8.8.8.8" );
中间件
IpstackMiddleware可以用作PSR-15中间件,也可以用作传统的Slim3风格的“双重传递”中间件。它需要IpstackClient实例,并将一个携带IpstackClient's响应的ipstack属性注入到Request对象中。此示例展示了“双重传递”方法
<?php use Germania\IpstackClient\IpstackMiddleware; // Setup your client as shown above $ipstack = new IpstackClient( $endpoint, $api_key); // The middleware: $ipstack_middleware = new IpstackMiddleware( $ipstack ); // Setup Slim app $app = new \Slim\App; $app->add( $ipstack_middleware );
然后在您的控制器中,您只需从Request对象中获取ipsatck信息即可
$ipstack_attr = $request->getAttribute( "ipstack" ); echo $ipstack_attr['ip']; echo $ipstack_attr['country_code']; echo $ipstack_attr['country_name'];
关于IP地址的话
ipstack请求中使用的IP地址默认由$_SERVER['REMOTE_ADDR']
确定。建议使用Rob Allen(又名akrabat)的客户端IP地址中间件来更安全地确定IP地址。
陷阱1:Akrabats中间件必须在IpstackMiddleware之前使用。它必须作为第二个添加到Slim应用中。
陷阱2:Akrabats中间件允许自定义客户端IP地址的请求属性名称。根据文档
默认情况下,属性名称为'
ip_address
'。这可以通过第三个构造函数参数进行更改。
这意味着,IP可能存储在自定义请求属性中。因此,IpstackMiddleware必须知道此属性名称。
只需将IP地址属性名称作为第二个构造函数传递,无论是默认还是自定义。记住,如果您省略此参数,将使用$_SERVER['REMOTE_ADDR']
作为后备。
<?php use RKA\Middleware\IpAddress as IpAddressMiddleware; use Germania\IpstackClient\IpstackMiddleware; // Setup Slim app $app = new \Slim\App; // Executed second $ipstack_middleware = new IpstackMiddleware( $ipstack, "ip_address" ); $app->add( $ipstack_middleware ); // Executed first $checkProxyHeaders = true; // Note: Never trust the IP address for security processes! $trustedProxies = ['10.0.0.1', '10.0.0.2']; // example $akrabats_middleware = new IpAddressMiddleware($checkProxyHeaders, $trustedProxies); $app->add( $akrabats_middleware );
异常
IpstackClient在请求期间检查Guzzle异常并评估ipstack错误响应。这两者都将被抽象为IpstackRequestException或IpstackResponseException,它们都实现了IpstackExceptionInterface。
<?php use Germania\IpstackClient\IpstackExceptionInterface; use Germania\IpstackClient\IpstackRequestException; use Germania\IpstackClient\IpstackResponseException; try { $ipstack = new IpstackClient( $endpoint, $api_key); $response = $ipstack->get( $client_ip ); } catch( IpstackExceptionInterface $e ) { // a) IpstackResponseException // b) IpstackRequestException echo $e->getMessage(); echo $e->getCode(); // to get Guzzle's original exception: $original_guzzle_exception = $e->getPrevious(); }
开发
$ git clone https://github.com/GermaniaKG/ipstack.git
$ cd ipstack
$ composer install
单元测试
将 phpunit.xml.dist 复制到 phpunit.xml 并调整与ipstack相关的全局变量。端点和API密钥解释自明;虚拟的 IP4 和 IP6 是测试运行期间要检查的IP地址。这里使用的IP示例是 谷歌的DNS服务器。
<php> <var name="IPSTACK_ENDPOINT" value="http://api.ipstack.com/" /> <var name="IPSTACK_APIKEY" value="your_api_key" /> <var name="IPSTACK_DUMMY_IP4" value="8.8.4.4" /> <var name="IPSTACK_DUMMY_IP6" value="2001:4860:4860::8888" /> </php>
使用供应商的二进制文件或composer test 脚本来运行 phpunit
$ vendor/bin/phpunit # or $ composer test