geocoder-php/geo-plugin-provider
GeoPlugin provider for the Geocoder PHP library. Turns IP addresses into location data (country, region, city, coordinates) using GeoPlugin’s API. Easy drop-in provider for apps that need basic IP geolocation and locale-aware results.
Installation Add the package via Composer:
composer require geocoder-php/geo-plugin-provider
Require the Geocoder\Provider\GeoPluginProvider in your Laravel app:
use Geocoder\Provider\GeoPluginProvider;
use Geocoder\Geocoder;
use Geocoder\HttpAdapter\Guzzle6Adapter;
Basic Usage
Initialize the provider with a Geocoder instance:
$geocoder = new Geocoder();
$geocoder->registerProvider(new GeoPluginProvider(new Guzzle6Adapter()));
First Query Fetch coordinates for an address:
$results = $geocoder->geocodeQuery('1600 Amphitheatre Parkway, Mountain View, CA');
foreach ($results as $hit) {
echo $hit->getLatitude() . ', ' . $hit->getLongitude();
}
Where to Look First
Reverse Geocoding Convert coordinates to an address:
$results = $geocoder->reverseQuery(37.422, -122.084);
Batch Processing
Use geocodeQueryBatch() for multiple addresses:
$addresses = ['NYC', 'London', 'Tokyo'];
$results = $geocoder->geocodeQueryBatch($addresses);
Integration with Laravel
Bind the provider to Laravel’s service container in AppServiceProvider:
public function register()
{
$this->app->singleton(Geocoder::class, function ($app) {
$geocoder = new Geocoder();
$geocoder->registerProvider(new GeoPluginProvider(new Guzzle6Adapter()));
return $geocoder;
});
}
Caching Responses Cache results to avoid API rate limits:
$cache = new \Geocoder\Cache\DoctrineCache();
$geocoder->registerCache($cache);
Error Handling Wrap queries in try-catch for API failures:
try {
$results = $geocoder->geocodeQuery('Invalid Address');
} catch (\Geocoder\Exception\UnsupportedOperationException $e) {
Log::error('GeoPlugin failed: ' . $e->getMessage());
}
Use Facades for Cleaner Code
Create a facade (e.g., GeoPlugin.php) to abstract the provider:
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class GeoPlugin extends Facade { protected static function getFacadeAccessor() { return 'geocoder'; } }
Then call GeoPlugin::geocodeQuery('...') in controllers/views.
Queue Long-Running Geocodes
Offload geocoding to a queue job (e.g., GeocodeAddressJob) to avoid timeouts.
Store Results in Database Use Eloquent events or observers to save geocoded data:
class AddressObserver {
public function saved(Address $address) {
if (empty($address->latitude)) {
$results = GeoPlugin::geocodeQuery($address->full_address);
$address->update(['latitude' => $results[0]->getLatitude(), ...]);
}
}
}
Rate Limits GeoPlugin has strict rate limits (e.g., 1,000 requests/day for free tier).
Geocoder\Provider\OpenStreetMapProvider) if limits are hit.Response Format Quirks
GeoPlugin returns nested JSON. The provider flattens it, but some fields (e.g., geoplugin_city) may require manual parsing:
$hit->getExtraProperties()['geoplugin_city']; // Access raw data if needed.
HTTP Adapter Issues
guzzlehttp/guzzle is installed (required for Guzzle6Adapter).$adapter = new Guzzle6Adapter(['timeout' => 10]);
Free Tier Limitations The free tier lacks accuracy for some regions. Test with your target addresses before production.
Enable Debug Mode
Set GEOCODER_DEBUG=1 in .env to log raw API responses:
$geocoder->registerProvider(new GeoPluginProvider(new Guzzle6Adapter(), [], true)); // Enable debug.
Check HTTP Status Codes
GeoPlugin returns 429 for rate limits. Handle it explicitly:
catch (\Geocoder\HttpException\UnprocessableEntityException $e) {
if ($e->getCode() === 429) {
// Retry or switch provider.
}
}
Custom Response Mapping
Override the provider’s getGeocodedPlace() method to map GeoPlugin’s JSON to your schema:
class CustomGeoPluginProvider extends GeoPluginProvider {
protected function getGeocodedPlace($data) {
$place = parent::getGeocodedPlace($data);
$place->setCustomProperty('timezone', $data['geoplugin_timezone']);
return $place;
}
}
Add Headers for API Key If using a paid plan, inject headers:
$adapter = new Guzzle6Adapter(['headers' => ['X-API-Key' => config('services.geoplugin.key')]]);
Mock for Testing
Use Geocoder\Provider\MockProvider in tests:
$geocoder = new Geocoder();
$geocoder->registerProvider(new MockProvider());
$geocoder->registerProvider(new GeoPluginProvider($adapter)); // Fallback.
How can I help you explore Laravel packages today?