rumenx/php-geolocation
最新稳定版本:v1.0.2
Composer 安装命令:
composer require rumenx/php-geolocation
包简介
Framework-agnostic PHP utility for CloudFlare geolocation detection with multi-language support and local development simulation.
关键字:
README 文档
README
A simple, framework-agnostic PHP utility for Cloudflare geolocation detection and client information extraction. Provides helpers to access geolocation, language, and client information (OS, browser, device, resolution) from HTTP headers.
Features
- ???? Detects Cloudflare geolocation headers (country, IP, etc.)
- ???? Helper methods to access geolocation, language, and client info (OS, browser, device, resolution)
- ???? Configurable country-to-language mapping (supports multiple official languages per country)
- ???? Language negotiation: matches browser and available site languages for multi-language countries
- ???? Configurable language cookie name
- ⚙️ Configurable fields for returned visitor info
- ????️ Local development simulation - Fake Cloudflare headers for testing without production setup
- ???? Auto-detection of local environments (localhost, local IPs, missing Cloudflare headers)
- ???? Fully tested with Pest (100% coverage)
- ✅ PSR-12 compliant, static analysis and style checks
- ???? Simple utility class - no framework dependencies or complex setup required
???? Documentation & Wiki
For comprehensive documentation, examples, and advanced usage patterns, visit our Complete Wiki Documentation:
???? Quick Links
- Quick Start Guide - Get running in minutes
- Framework Integration - Laravel, Symfony, CodeIgniter guides
- CloudFlare Setup - Production configuration
- Local Development - Testing without CloudFlare
- Multi-language Websites - International applications
- Production Deployment - Best practices & monitoring
- API Development - RESTful APIs with geolocation
- Configuration Reference - Complete options guide
???? Advanced Topics
- Error Handling - Robust error management
- Caching Strategies - Performance optimization
- Analytics Integration - Geographic tracking
- Troubleshooting - Common issues & solutions
Why This Design?
This package is intentionally designed as a simple utility library rather than a complex framework integration. Here's why:
???? Focused Purpose
- Single responsibility: Extract and process geolocation data from HTTP headers
- Pure functions: No side effects, no global state, predictable behavior
- Framework-agnostic: Works with any PHP application or framework
???? Easy Integration
- No service providers needed: Just instantiate the class when you need it
- No configuration files: Pass configuration directly to the constructor
- No middleware complexity: Use it exactly where and when you need it
- Developer control: You decide how and when to use geolocation data
???? Minimal Dependencies
- Zero runtime dependencies: Only requires PHP 8.3+
- Small footprint: Single class, focused functionality
- Fast installation: No complex dependency trees
- Version compatibility: No framework version constraints
This approach makes the package more reliable, easier to understand, and simpler to maintain - following the Unix philosophy of "do one thing and do it well."
Installation
composer require rumenx/php-geolocation
Local Development Simulation
When developing locally where Cloudflare is not available, you can simulate its functionality:
Quick Simulation
use Rumenx\Geolocation\Geolocation; // Create a simulated instance for a specific country $geo = Geolocation::simulate('DE', [ 'DE' => ['de'], 'CA' => ['en', 'fr'] ]); echo $geo->getCountryCode(); // 'DE' echo $geo->getIp(); // Simulated IP like '192.168.4.123'
Advanced Simulation
use Rumenx\Geolocation\GeolocationSimulator; // Generate fake Cloudflare headers $headers = GeolocationSimulator::fakeCloudflareHeaders('JP', [ 'user_agent' => 'Custom User Agent', 'server_name' => 'dev.example.com' ]); // Create instance with simulated server data $geo = new Geolocation($headers, ['JP' => ['ja', 'en']]);
Auto-Detection of Local Environment
$geo = new Geolocation(); if ($geo->isLocalDevelopment()) { // Automatically detected: localhost, local IPs, or missing Cloudflare headers echo "Running in local development mode"; }
Available Countries for Simulation
// Get list of built-in countries $countries = GeolocationSimulator::getAvailableCountries(); // ['US', 'CA', 'GB', 'DE', 'FR', 'JP', 'AU', 'BR'] // Get random country for testing $randomCountry = GeolocationSimulator::randomCountry();
Framework Integration for Development
For Laravel and Symfony, check the /examples directory for middleware and event listeners that automatically inject simulated Cloudflare headers in development environments.
Usage
Basic Usage
use Rumenx\Geolocation\Geolocation; // Simple usage with defaults $geo = new Geolocation(); $country = $geo->getCountryCode(); $ip = $geo->getIp(); $info = $geo->getGeoInfo(); // Advanced usage with custom configuration $countryToLanguage = [ 'CA' => ['en', 'fr'], // Canada: English (default), French 'DE' => ['de'], // Germany: German 'CH' => ['de', 'fr', 'it'], // Switzerland: German, French, Italian // Add more countries as needed... ]; $geo = new Geolocation( $_SERVER, // HTTP server array (optional, defaults to $_SERVER) $countryToLanguage, // Country-to-language mapping (optional) 'my_lang_cookie' // Custom cookie name (optional, defaults to 'lang') );
Language Detection
// Get best language for visitor based on country and browser preferences $availableSiteLanguages = ['en', 'fr', 'de', 'es']; $lang = $geo->getLanguageForCountry(null, $availableSiteLanguages); // Language selection logic: // 1. If browser preferred language matches a country language and is available, use it // 2. Else, check all browser languages for a match with available languages // 3. Else, use the first country language as fallback // 4. Returns null if no match found // Check if language should be set (based on cookie) if ($geo->shouldSetLanguage()) { // Set language in your application setcookie($geo->languageCookieName, $lang); }
Client Information
// Get specific information $country = $geo->getCountryCode(); // 'US', 'CA', 'DE', etc. $ip = $geo->getIp(); // '192.168.1.1' $browser = $geo->getBrowser(); // ['name' => 'Chrome', 'version' => '91.0'] $os = $geo->getOs(); // 'Windows 10', 'macOS', 'Linux', etc. $device = $geo->getDeviceType(); // 'desktop', 'mobile', 'tablet' $resolution = $geo->getResolution(); // ['width' => 1920, 'height' => 1080] // Get all information at once $info = $geo->getGeoInfo(); // Returns: [ // 'country_code' => 'US', // 'ip' => '192.168.1.1', // 'preferred_language' => 'en-US', // 'all_languages' => ['en-US', 'en', 'fr'], // 'user_agent' => 'Mozilla/5.0...', // 'browser' => ['name' => 'Chrome', 'version' => '91.0'], // 'os' => 'Windows 10', // 'device_type' => 'desktop', // 'resolution' => ['width' => 1920, 'height' => 1080] // ] // Get only specific fields $specificInfo = $geo->getGeoInfo(['country_code', 'ip', 'browser']);
Framework Integration Examples
Laravel
// In a controller class HomeController extends Controller { public function index(Request $request) { $geo = new Geolocation( $request->server->all(), config('app.country_to_language', []) ); $country = $geo->getCountryCode(); $lang = $geo->getLanguageForCountry(null, ['en', 'fr', 'de']); if ($geo->shouldSetLanguage() && $lang) { app()->setLocale($lang); } return view('home', [ 'geo' => $geo->getGeoInfo(['country_code', 'ip']), 'language' => $lang ]); } } // In a middleware (optional) class GeolocationMiddleware { public function handle($request, Closure $next) { $geo = new Geolocation($request->server->all()); $lang = $geo->getLanguageForCountry(); if ($lang && $geo->shouldSetLanguage()) { app()->setLocale($lang); } return $next($request); } }
Symfony
// In a controller class HomeController extends AbstractController { public function index(Request $request): Response { $geo = new Geolocation( $request->server->all(), $this->getParameter('country_to_language') ); $country = $geo->getCountryCode(); $lang = $geo->getLanguageForCountry(null, ['en', 'fr', 'de']); if ($geo->shouldSetLanguage() && $lang) { $request->setLocale($lang); } return $this->render('home.html.twig', [ 'geo' => $geo->getGeoInfo(), 'language' => $lang ]); } } // In an event listener (optional) class GeolocationListener { public function onKernelRequest(RequestEvent $event): void { $request = $event->getRequest(); $geo = new Geolocation($request->server->all()); $lang = $geo->getLanguageForCountry(); if ($lang && $geo->shouldSetLanguage()) { $request->setLocale($lang); } } }
Plain PHP
// In any PHP application session_start(); $geo = new Geolocation($_SERVER, [ 'US' => ['en'], 'CA' => ['en', 'fr'], 'DE' => ['de'], 'FR' => ['fr'] ]); $country = $geo->getCountryCode(); $lang = $geo->getLanguageForCountry(null, ['en', 'fr', 'de']); // Set language preference if ($geo->shouldSetLanguage() && $lang) { $_SESSION['language'] = $lang; setcookie('lang', $lang, time() + (86400 * 30)); // 30 days } // Use the information echo "Welcome visitor from: " . ($country ?? 'Unknown'); echo "Preferred language: " . ($lang ?? 'Default');
Configuration
The package is simple and requires minimal configuration. All settings are passed directly to the constructor:
Constructor Parameters
$geo = new Geolocation($server, $countryToLanguage, $languageCookieName);
$server(array, optional): HTTP server array, defaults to$_SERVER$countryToLanguage(array, optional): Country code to language mapping$languageCookieName(string, optional): Language cookie name, defaults to'lang'
Country-to-Language Mapping
Map country codes (ISO 3166-1 alpha-2) to language codes or arrays. The first language is the default for the country:
$countryToLanguage = [ 'US' => ['en'], // United States: English only 'CA' => ['en', 'fr'], // Canada: English (default), French 'CH' => ['de', 'fr', 'it', 'rm'], // Switzerland: German (default), French, Italian, Romansh 'BE' => ['nl', 'fr', 'de'], // Belgium: Dutch (default), French, German 'IN' => ['hi', 'en'], // India: Hindi (default), English 'ZA' => ['en', 'af', 'zu'], // South Africa: English (default), Afrikaans, Zulu // Add more countries as needed... ];
Example Configurations
Minimal Setup
// Use defaults for everything $geo = new Geolocation();
Basic Country Mapping
$geo = new Geolocation($_SERVER, [ 'DE' => ['de'], 'FR' => ['fr'], 'ES' => ['es'] ]);
Custom Cookie Name
$geo = new Geolocation($_SERVER, [], 'user_language');
Full Configuration
$geo = new Geolocation( $_SERVER, // or $request->server->all() in frameworks [ 'US' => ['en'], 'CA' => ['en', 'fr'], 'MX' => ['es'], 'DE' => ['de'], 'AT' => ['de'], 'CH' => ['de', 'fr', 'it'], 'FR' => ['fr'], 'BE' => ['nl', 'fr'], 'IT' => ['it'], 'ES' => ['es'], 'BR' => ['pt'], 'PT' => ['pt'], 'RU' => ['ru'], 'CN' => ['zh'], 'JP' => ['ja'], 'KR' => ['ko'] ], 'preferred_language' );
No configuration files, service providers, or complex setup needed!
Examples
The examples/ directory contains practical demonstrations of the package capabilities:
???? Basic Usage
demo.php- Interactive demo showing simulation in local development with multiple countries
⚡ Framework Integration
LaravelDevelopmentMiddleware.php- Laravel middleware for automatic header injection in developmentSymfonyDevelopmentListener.php- Symfony event listener for request-level simulation
???? Real-World Applications
content-localization.php- Redirect visitors to country-specific domainsapi-endpoint.php- REST API with geolocation-based responses (currency, features, etc.)multi-language.php- Automatic language detection with fallbacks for multi-language sites
Running Examples
# Basic simulation demo php examples/demo.php # Content localization php examples/content-localization.php # API endpoint simulation php examples/api-endpoint.php # Multi-language detection php examples/multi-language.php
All examples automatically detect local development and use simulation, so they work perfectly without Cloudflare setup! ????
Contributing
We welcome contributions! Please see our Contributing Guide for details on how to contribute to this project.
Code of Conduct
This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers.
Development
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
composer test - Run static analysis:
composer analyze - Check code style:
composer style - Submit a pull request
Related Projects
???? Go Version
- go-geolocation - Go adaptation of this package with similar functionality for the Go ecosystem
???? Future Versions (Planned)
- Python version - Python adaptation planned for future release
- WordPress plugin - WordPress integration plugin planned
- Drupal module - Drupal integration module planned
Security
If you discover a security vulnerability, please see our Security Policy for information on how to report it responsibly.
Changelog
All notable changes to this project are documented in the Changelog.
Support
- ???? Documentation
- ???? Issue Tracker
- ???? Discussions
- ???? Sponsor this project
License
统计信息
- 总下载量: 1.03k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 4
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-04