msallehi / php-geolocation
A PHP package to restrict access based on user's country/IP location - Works with Laravel, WordPress, and pure PHP
Installs: 295
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/msallehi/php-geolocation
Requires
- php: ^8.0
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- phpunit/phpunit: ^10.0
Suggests
- illuminate/support: Required for Laravel integration (^9.0|^10.0|^11.0)
README
A PHP package to restrict user access based on their country/IP location. Works with pure PHP, Laravel, WordPress, and any PHP framework.
🇮🇷 مستندات فارسی | 📋 Changelog
✨ Features
- 🌍 Automatic country detection from IP address
- 🔒 Restrict access to specific countries
- ⚙️ Fully customizable configuration
- 🔧 Multiple API provider support
- 📝 Custom error messages
- 🔄 Automatic fallback when API fails (v1.1.0+)
- 🎯 Compatible with pure PHP, Laravel, and WordPress
📦 Installation
composer require msallehi/php-geolocation
🚀 Quick Start
Pure PHP
<?php require 'vendor/autoload.php'; use MSallehi\GeoLocation\GeoLocation; // Create instance with default settings (Iran only) $geo = new GeoLocation(); // Or with custom settings $geo = new GeoLocation([ 'allowed_countries' => ['IR', 'TR'], 'messages' => [ 'not_allowed' => 'Access from your country is not allowed.', ], ]); // Check access if ($geo->isAllowed()) { echo "Welcome!"; } else { echo "Access denied"; } // Or use guard for automatic blocking $geo->guard(); // Automatically returns 403 error if not allowed
Static Factory
use MSallehi\GeoLocation\GeoLocation; GeoLocation::create(['allowed_countries' => ['IR']])->guard();
📖 Full Documentation
Basic Usage
use MSallehi\GeoLocation\GeoLocation; $geo = new GeoLocation(); // Get user's country $country = $geo->getCountryFromIp(); echo "Your country: " . $country; // IR, US, GB, ... // Get user's IP $ip = $geo->getClientIp(); // Check if allowed if ($geo->isAllowed()) { // User is allowed } // Get full location details $location = $geo->getLocationDetails(); // [ // 'ip' => '5.160.139.15', // 'country_code' => 'IR', // 'country_name' => 'Iran', // 'city' => 'Tehran', // 'region' => 'Tehran', // 'is_local' => false, // ]
Exception Handling
use MSallehi\GeoLocation\GeoLocation; use MSallehi\GeoLocation\Exceptions\CountryNotAllowedException; use MSallehi\GeoLocation\Exceptions\GeoLocationException; $geo = new GeoLocation(['allowed_countries' => ['IR']]); try { $geo->validate(); // User is allowed } catch (CountryNotAllowedException $e) { echo $e->getMessage(); echo "Your country: " . $e->getDetectedCountry(); echo "Allowed countries: " . implode(', ', $e->getAllowedCountries()); // Convert to JSON echo $e->toJson(); } catch (GeoLocationException $e) { echo "Location detection error: " . $e->getMessage(); }
Dynamic Configuration
$geo = new GeoLocation(); // Change allowed countries $geo->setAllowedCountries(['IR', 'US', 'GB']); // Add country $geo->addAllowedCountry('DE'); // Remove country $geo->removeAllowedCountry('US'); // Change error message $geo->setMessage('not_allowed', 'This service is not available in your country.'); // Change API Provider $geo->setApiProvider('ipinfo', ['token' => 'your-token']); // Check specific country if ($geo->isCountryAllowed('IR')) { echo "Iran is allowed"; } // Get allowed countries list $countries = $geo->getAllowedCountries();
Check Specific IP
$geo = new GeoLocation(['allowed_countries' => ['IR']]); // Check specific IP $isAllowed = $geo->isAllowed('5.160.139.15'); $country = $geo->getCountryFromIp('8.8.8.8'); $location = $geo->getLocationDetails('1.1.1.1');
🔵 Laravel Integration
Register Service Provider
In config/app.php:
'providers' => [ // ... MSallehi\GeoLocation\Laravel\GeoLocationServiceProvider::class, ], 'aliases' => [ // ... 'GeoLocation' => MSallehi\GeoLocation\Laravel\GeoLocationFacade::class, ],
Publish Config
php artisan vendor:publish --tag=geolocation-config
Using Middleware
// routes/web.php // Only Iranian users Route::middleware(['geolocation'])->group(function () { Route::get('/iran-only', function () { return 'Welcome!'; }); }); // Specify countries in middleware Route::middleware(['geolocation:IR,US,GB'])->group(function () { Route::get('/multi-country', function () { return 'Welcome!'; }); });
Using Facade
use MSallehi\GeoLocation\Laravel\GeoLocationFacade as GeoLocation; if (GeoLocation::isAllowed()) { // User is allowed } $country = GeoLocation::getCountryFromIp();
🟢 WordPress Integration
Basic Setup
In your theme's functions.php or plugin:
require_once get_template_directory() . '/vendor/autoload.php'; require_once get_template_directory() . '/vendor/msallehi/php-geolocation/src/WordPress/functions.php';
Using Helper Functions
// Get country $country = geo_get_country(); // Check access if (geo_is_allowed()) { echo "Welcome!"; } // Automatic block geo_guard(); // Calls wp_die if not allowed // Set countries geo_set_countries(['IR', 'TR']); // Get full details $location = geo_get_location();
Using Shortcode
[geo_restrict country="IR"] This content is only visible to Iranian users. [/geo_restrict] [geo_restrict country="IR,US,GB" message="Only for selected countries"] Special content [/geo_restrict]
Restrict Entire Page
// In functions.php add_action('template_redirect', function() { if (is_page('iran-only')) { geo_wp_restrict(['IR']); } });
Custom Restriction in Template
// In template file <?php $geo = new \MSallehi\GeoLocation\GeoLocation([ 'allowed_countries' => ['IR'], 'messages' => ['not_allowed' => 'This page is not available in your country.'] ]); if (!$geo->isAllowed()): ?> <div class="access-denied"> <h2>Access Restricted</h2> <p>Your country: <?php echo $geo->getCountryFromIp(); ?></p> </div> <?php else: ?> <!-- Page content --> <?php endif; ?>
🌐 API Providers
ip-api (Default - Free)
$geo = new GeoLocation([ 'api_provider' => 'ip-api', ]);
ipinfo.io
$geo = new GeoLocation([ 'api_provider' => 'ipinfo', 'ipinfo_token' => 'your-api-token', ]);
ipdata.co
$geo = new GeoLocation([ 'api_provider' => 'ipdata', 'ipdata_api_key' => 'your-api-key', ]);
⚙️ Full Configuration
$config = [ // Allowed countries 'allowed_countries' => ['IR'], // API service 'api_provider' => 'ip-api', // ip-api, ipinfo, ipdata // API keys 'ipinfo_token' => '', 'ipdata_api_key' => '', // Request timeout 'timeout' => 5, // Local IP 'allow_local' => true, 'local_country' => 'LOCAL', // Error messages 'messages' => [ 'not_allowed' => 'Access from your country is not allowed.', 'api_error' => 'Unable to determine your location.', ], ]; $geo = new GeoLocation($config);
📝 Custom Error Messages
In Constructor
$geo = new GeoLocation([ 'messages' => [ 'not_allowed' => 'Your custom access denied message', 'api_error' => 'Custom API error message', ], ]);
Runtime
$geo->setMessage('not_allowed', 'Access denied from your country.');
With denyAccess
if (!$geo->isAllowed()) { $geo->denyAccess('Your custom message', 403); }
📋 Country Codes
Use ISO 3166-1 alpha-2 codes:
| Country | Code |
|---|---|
| Iran | IR |
| United States | US |
| United Kingdom | GB |
| Germany | DE |
| France | FR |
| Turkey | TR |
| Canada | CA |
| Australia | AU |
| UAE | AE |
| Saudi Arabia | SA |
📄 License
The MIT License (MIT). Please see License File for more information.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
👨💻 Author
- Mohammad Salehi - GitHub
⭐ Support
If you find this package useful, please give it a star on GitHub!