IPstack PHP Wrapper: Accurate IP Geolocation API Integration for Developers & Businesses
If you’ve used the package before, this release is a major quality step forward.
If you’re new to it, this is the right time to start.
The new sudiptpa/ipstack release modernizes the SDK with a cleaner architecture, stronger typing, better error handling, improved documentation, and practical production patterns for both plain PHP and Laravel-style integrations.
Table of Contents
- What’s New in This Release
- Why This Upgrade Matters
- Installation
- Quick Start (Framework-Agnostic PHP)
- Core Features and How to Use Them
- Advanced Usage Patterns
- Laravel Integration Example
- Error Handling Strategy
- Testing and Quality
- Migration Notes
- Open for Contributions
- Related Reading (SEO/Previous Blogs)
- Conclusion
1) What’s New in This Release
Here are the most important updates shipped in the latest modernized version:
- New factory/client architecture
- PSR-18 based transport layer
- Typed models for ipstack responses
- Bulk lookup support with edge-case safety
- Better exception mapping (API + transport errors)
- Expanded test coverage for real-world failure paths
- PHP 8.3 to 8.5 support
- Improved README with migration guide and advanced examples
This isn’t just a feature release. It’s a reliability release.
2) Why This Upgrade Matters
IP geolocation often starts as a minor utility but quickly becomes central to:
- authentication risk signals
- geo personalization
- analytics enrichment
- fraud and abuse detection
In those contexts, consistency matters more than convenience.
This release focuses on consistency: explicit construction, typed data, predictable errors, and testable boundaries.
3) Installation
composer require sudiptpa/ipstack
If you want the same PSR-18 adapter stack used in examples:
composer require symfony/http-client nyholm/psr7
4) Quick Start (Framework-Agnostic PHP)
<?php
declare(strict_types=1);
use Ipstack\Ipstack;
use Nyholm\Psr7\Factory\Psr17Factory;
use Symfony\Component\HttpClient\Psr18Client;
$client = Ipstack::factory()
->withAccessKey($_ENV['IPSTACK_ACCESS_KEY'])
->withPsr18(new Psr18Client(), new Psr17Factory())
->build();
$result = $client->lookup('8.8.8.8');
echo $result->formatted(); // Mountain View, 94035, California, United States
5) Core Features and How to Use Them
Single IP Lookup
$result = $client->lookup('1.1.1.1');
echo $result->country->name;
echo $result->region->name;
echo $result->city;
Requester IP (/check)
$mine = $client->lookupRequester();
echo $mine->ip;
Bulk Lookup
$collection = $client->lookupBulk(['8.8.8.8', '1.1.1.1']);
foreach ($collection as $row) {
echo $row->ip . ' => ' . $row->formatted() . PHP_EOL;
}
Query Options
use Ipstack\Client\Options;
$options = Options::create()
->fields(['ip', 'country_name', 'region_name', 'city'])
->language('en')
->security(true)
->hostname(true);
$result = $client->lookup('8.8.8.8', $options);
6) Advanced Usage Patterns
A) Use a Custom Transport (great for testing/offline dev)
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',
'region_name' => 'California',
'city' => 'Mountain View',
'zip' => '94035',
];
}
}
Then inject:
$client = Ipstack::factory()
->withAccessKey('DUMMY')
->withTransport(new DemoTransport())
->build();
B) Build robust error handling
Catch by exception type, not message string:
use Ipstack\Exception\RateLimitException;
use Ipstack\Exception\TransportException;
use Ipstack\Exception\InvalidResponseException;
use Ipstack\Exception\IpstackException;
try {
$result = $client->lookup($ip);
} catch (RateLimitException $e) {
// quota policy
} catch (TransportException|InvalidResponseException $e) {
// network/upstream policy
} catch (IpstackException $e) {
// fallback domain policy
}
C) Keep raw payload for audit/debug
$raw = $result->raw();
$asJson = json_encode($result); // JsonSerializable raw payload
7) Laravel Integration Example
Even though the package is framework-agnostic, it fits Laravel very naturally.
Service Provider Binding
use Ipstack\Ipstack;
use Nyholm\Psr7\Factory\Psr17Factory;
use Symfony\Component\HttpClient\Psr18Client;
$this->app->singleton(\Ipstack\Client\IpstackClient::class, function () {
return Ipstack::factory()
->withAccessKey(config('services.ipstack.key'))
->withPsr18(new Psr18Client(), new Psr17Factory())
->build();
});
Usage in Controller/Service
public function show(Request $request, \Ipstack\Client\IpstackClient $ipstack)
{
$geo = $ipstack->lookup($request->ip());
return response()->json([
'ip' => $geo->ip,
'country' => $geo->country->name,
'region' => $geo->region->name,
'city' => $geo->city,
]);
}
Middleware pattern (recommended)
- resolve client once
- lookup requester IP once
- attach context to request attributes
- consume context in downstream handlers
This avoids duplicate lookups and keeps geo context consistent per request.
8) Error Handling Strategy
This release maps known ipstack API errors to dedicated exceptions:
- RateLimitException (104)
- InvalidFieldsException (301)
- TooManyIpsException (302)
- BatchNotSupportedException (303)
- plus transport/response exceptions
This is useful for real policy behavior:
- retry only where appropriate
- fail fast on invalid caller parameters
- monitor rate limits separately from transport instability
9) Testing and Quality
The package now includes stronger coverage around:
- requester lookup behavior
- bulk edge cases and limits
- factory misconfiguration
- PSR-18 transport failure modes
Quality pipeline includes:
- PHPUnit
- PHPStan
- CI matrix across PHP 8.3 / 8.4 / 8.5
10) Migration Notes
If you used older versions:
- move from constructor-style direct calls to factory-built client
- replace legacy convenience method patterns with:
- lookup()
- lookupRequester()
- lookupBulk()
- consume typed model fields instead of manual payload array parsing
The README migration table gives direct old->new mapping.
11) Open for Contributions
Contributions are welcome and appreciated.
Good contribution areas:
- transport adapters/examples
- additional integration examples (Symfony, Laravel, Slim, etc.)
- test coverage improvements for edge payload variants
- docs improvements and migration tips from real projects
If you open a PR, include tests and update docs where behavior changes.
12) Conclusion
This release is focused on real-world reliability, not just syntactic modernization.
You now get a cleaner architecture, typed outputs, better error semantics, stronger tests, and clearer integration patterns for both plain PHP and Laravel-style projects. If you’re using IP intelligence in auth, personalization, or analytics, this release reduces risk and improves maintainability immediately.
Thanks for reading.
If you’re using the package in production, feedback and PRs are welcome.
Also Read: V1:: A Simple IP to Geo Location solution for PHP