定制 gryfoss/http-cf-geolocation-service 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

gryfoss/http-cf-geolocation-service

Composer 安装命令:

composer require gryfoss/http-cf-geolocation-service

包简介

Wrapper around GeoIP service and CloudFlare functionality which grants ISO code of the detected country during masking of IPs.

README 文档

README

CI Tests Quick Tests PHP Version License: MIT

A high-performance PHP service for detecting user geolocation using Cloudflare headers with MaxMind GeoIP database fallback.

🎯 Purpose

CFGeolocationService is designed to provide fast and accurate geolocation detection by leveraging Cloudflare's edge network capabilities while maintaining reliability through GeoIP database fallbacks. This dual-strategy approach ensures optimal performance and accuracy for web applications behind Cloudflare's proxy network.

Key Benefits

  • 🚀 Performance: Prioritizes Cloudflare headers for instant geolocation (no database lookup required)
  • 🛡️ Reliability: Falls back to MaxMind GeoIP2 database when Cloudflare headers are unavailable
  • 🌐 Accuracy: Uses Cloudflare's global edge network data combined with MaxMind's proven database
  • ⚡ Speed: Minimal overhead with intelligent caching strategy
  • 🔒 Security: Validates all inputs and handles edge cases gracefully

🏗️ How It Works

1. Check CF-IPCountry header → Valid ISO country code? → Return country
                                      ↓
2. Check CF-Connecting-IP header → Valid IP address? → Use for GeoIP lookup
                                      ↓
3. Fall back to Symfony getClientIp() → Perform GeoIP database lookup → Return country

Dual Detection Strategy

  1. Primary: Cloudflare Headers (instant results)

    • CF-IPCountry: ISO 3166-1 alpha-2 country code
    • CF-Connecting-IP: Real client IP address
  2. Fallback: GeoIP Database Lookup

    • MaxMind GeoLite2/GeoIP2 Country database
    • Handles cases where CF headers are missing or invalid

🚀 Installation

Via Composer

composer require gryfoss/http-cf-geolocation-service

Requirements

  • PHP: 8.1 or higher
  • Extensions: mbstring, filter
  • Dependencies:
    • symfony/http-foundation ^7.3
    • geoip2/geoip2 ^3.2

📖 Usage

Basic Usage

<?php

use GryfOSS\Geolocation\CFGeolocationService;
use Symfony\Component\HttpFoundation\Request;

// Initialize with GeoIP database path
$service = new CFGeolocationService('/path/to/GeoLite2-Country.mmdb');

// Get current request
$request = Request::createFromGlobals();

// Detect client IP address
$clientIp = $service->getIp($request);
echo "Client IP: " . $clientIp; // e.g., "203.0.113.1"

// Detect country code
$countryCode = $service->getCountryCode($request);
echo "Country: " . $countryCode; // e.g., "US"

With Cloudflare Headers

When your application is behind Cloudflare, the service automatically uses CF headers:

// Cloudflare provides these headers:
// CF-Connecting-IP: 203.0.113.1
// CF-IPCountry: US

$countryCode = $service->getCountryCode($request);
// Returns "US" instantly (no database lookup needed)

$clientIp = $service->getIp($request);
// Returns "203.0.113.1" (real client IP, not Cloudflare's)

Without Cloudflare Headers

The service gracefully falls back to GeoIP database lookup:

// No CF headers available
$countryCode = $service->getCountryCode($request);
// Performs GeoIP database lookup on client IP
// Returns country code based on IP geolocation

Debug Mode for Local Development

When developing on localhost or behind corporate VPNs, Cloudflare headers might be unavailable. Enable debug mode to short-circuit lookups and return deterministic values without changing your stack:

$service->setDebugMode(true, '203.0.113.77', 'PL'); // Use fake IP + ISO code

$clientIp = $service->getIp($request);      // "203.0.113.77"
$countryCode = $service->getCountryCode($request); // "PL"

$service->setDebugMode(false); // Revert to normal detection

Use isDebugModeEnabled(), getDebugModeIp(), and getDebugModeCountryCode() to inspect the current state. Debug mode strictly validates both the IP address and ISO 3166-1 alpha-2 country code to avoid accidental misuse.

Error Handling

use GryfOSS\Geolocation\CFGeolocationService;

try {
    $service = new CFGeolocationService('/invalid/path/database.mmdb');
} catch (\InvalidArgumentException $e) {
    echo "Database not found: " . $e->getMessage();
}

try {
    $countryCode = $service->getCountryCode($request);
} catch (\Exception $e) {
    echo "Geolocation failed: " . $e->getMessage();
}

Complete Examples

See examples.php for comprehensive usage examples including:

  • Basic geolocation detection
  • Cloudflare header simulation
  • GeoIP database fallback scenarios
  • Error handling demonstrations
  • Testing with various IP addresses
# Run examples (requires database download first)
./pull-free-db.sh
php examples.php

🧪 Testing

Download GeoIP Database

⚠️ Important: Due to MaxMind's licensing restrictions, the GeoIP database cannot be bundled with this package. You must download it separately.

# Download free GeoLite2 database
./pull-free-db.sh

# Or manually download from:
# https://dev.maxmind.com/geoip/geoip2/geolite2/

Run Tests

# Install development dependencies
composer install

# Download test database
./pull-free-db.sh

# Run complete test suite
./vendor/bin/phpunit

# Run Behat functional specs (debug mode scenarios)
./vendor/bin/behat

# Run tests with coverage
XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text

# Run tests with readable output
./vendor/bin/phpunit --testdox

# Run usage examples
php examples.php

Test Coverage

The project maintains 100% code coverage:

  • Lines: 100%
  • Methods: 100%
  • Classes: 100%
# Verify coverage locally
XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-html coverage-report
# Open coverage-report/index.html in your browser

Testing Strategy

  • Unit Tests: 32 unit tests covering all methods and edge cases
  • Integration Tests: 6 integration tests with real GeoIP database
  • Total: 38 tests with 47 assertions
  • Data Providers: Multiple test scenarios for various input combinations
  • Exception Testing: Error handling and edge case validation
  • Real Database: Tests use actual GeoLite2-Country.mmdb for authenticity

🗃️ GeoIP Database Setup

Database Licensing Notice

⚠️ Important Licensing Information

This package does not include the MaxMind GeoIP database due to licensing restrictions:

  • GeoLite2 databases are available for free but require separate download
  • Commercial GeoIP2 databases require a MaxMind license
  • Distribution restrictions prevent bundling databases with open-source packages

Download Options

Option 1: Free GeoLite2 Database

# Use the included script
./pull-free-db.sh

# Manual download
wget https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb

Option 2: Official MaxMind Account

  1. Create account at MaxMind
  2. Generate license key
  3. Download GeoLite2 or purchase GeoIP2 databases
  4. Follow MaxMind's terms of service

Option 3: Automated Updates

# Set up cron job for monthly updates
0 0 1 * * /path/to/your/project/pull-free-db.sh

Database Paths

// Common database locations
$service = new CFGeolocationService('/usr/local/share/GeoIP/GeoLite2-Country.mmdb');
$service = new CFGeolocationService('/var/lib/GeoIP/GeoLite2-Country.mmdb');
$service = new CFGeolocationService('./data/GeoLite2-Country.mmdb');

🔧 Configuration

Environment Variables

# Set database path via environment
export GEOIP_DATABASE_PATH="/path/to/GeoLite2-Country.mmdb"
// Use in your application
$databasePath = $_ENV['GEOIP_DATABASE_PATH'] ?? '/default/path/GeoLite2-Country.mmdb';
$service = new CFGeolocationService($databasePath);

Framework Integration

Symfony

# config/services.yaml
services:
    GryfOSS\Geolocation\CFGeolocationService:
        arguments:
            $databasePath: '%env(GEOIP_DATABASE_PATH)%'

Laravel

// config/app.php or service provider
$this->app->singleton(CFGeolocationService::class, function ($app) {
    return new CFGeolocationService(env('GEOIP_DATABASE_PATH'));
});

🏆 Quality Assurance

GitHub Actions CI/CD

  • Multi-PHP Testing: 8.2, 8.3, 8.4
  • Automated Database Download: Fresh GeoLite2 database for each test run
  • 100% Coverage Enforcement: Builds fail if coverage drops below 100%
  • Cross-Platform: Ubuntu latest with comprehensive test matrix

Code Quality Standards

  • PSR-4 Autoloading: Namespace compliance
  • PHPDoc Documentation: Comprehensive method and class documentation
  • Type Declarations: Strict typing for all parameters and returns
  • Error Handling: Graceful exception handling for all failure modes
  • Input Validation: Thorough validation of all external inputs

🤝 Contributing

We welcome contributions from the community! Here's how you can help:

Reporting Issues

  • Bug Reports: Use the GitHub Issues to report bugs
  • Feature Requests: Propose new features or improvements
  • Security Issues: Report security vulnerabilities privately

Pull Requests

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes with tests
  4. Ensure 100% test coverage: XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text
  5. Follow coding standards: PSR-12 compliance
  6. Submit a pull request with detailed description

Development Guidelines

  • Write tests first: TDD approach preferred
  • Maintain 100% coverage: All new code must be fully tested
  • Follow existing patterns: Consistent with current codebase
  • Document thoroughly: PHPDoc for all public methods
  • Validate inputs: Handle edge cases gracefully

Code of Conduct

Please follow our code of conduct in all interactions:

  • Be respectful and inclusive
  • Focus on constructive feedback
  • Help others learn and grow
  • Maintain professionalism

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

👥 Authors

  • IDCT Bartosz Pachołek - GitHub - Initial work

🙏 Acknowledgments

  • MaxMind for providing GeoIP2 and GeoLite2 databases
  • Cloudflare for their excellent geolocation headers
  • Symfony for the robust HTTP foundation component
  • P3TERX for maintaining the GeoLite2 mirror repository
  • PHP Community for continuous improvements and feedback

📚 Additional Resources

Made with ❤️ by the GryfOSS team

gryfoss/http-cf-geolocation-service 适用场景与选型建议

gryfoss/http-cf-geolocation-service 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 29 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 11 月 12 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 gryfoss/http-cf-geolocation-service 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 gryfoss/http-cf-geolocation-service 我们能提供哪些服务?
定制开发 / 二次开发

基于 gryfoss/http-cf-geolocation-service 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 29
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 41
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-11-12