Geocoder for Laravel

repository·master·Indexed 20 days ago

https://github.com/geocoder-php/geocoderlaravel

An integration package for using the Geocoder PHP library within Laravel applications for geocoding, reverse geocoding, and IP geocoding. It features a Laravel-native HTTP client, support for Chain providers, and specialized cache management including automatic registration of serializable classes for Laravel 13 security hardening. Requires PHP >= 8.2 and Laravel >= 11.0.

Tokens
4.3K
Snippets
19
Records
20
Agent score
73%

What's inside geocoder-php/geocoderlaravel

  1. Handle Laravel 13 `cache.serializable_classes` security hardening

    master

    Laravel 13 introduced cache.serializable_classes to block deserialization of arbitrary objects. Because Geocoder stores Collections of Address objects, caching may break if not configured correctly.

    Default Behavior: This package automatically scans vendor/geocoder-php/* and merges those model classes into your application's cache.serializable_classes allow-list at boot.

    Opting Out: If you want to manage the allow-list manually or disable this automatic behavior, set auto_register_serializable_classes to false in config/geocoder.php.

    If you opt out, you must either:

    1. Manually add Geocoder model classes to config/cache.php's serializable_classes array.
    2. Disable caching entirely by calling app('geocoder')->doNotCache() or setting cache.duration to 0 in config/geocoder.php.
    // config/geocoder.php
    'cache' => [
        'auto_register_serializable_classes' => false,
    ],
  2. Upgrade Geocoder Laravel from 0.x to 1.x

    master

    If upgrading from a pre-1.x version, perform these steps:

    1. Update Dependencies: Set "toin0u/geocoder-laravel": "^1.0" in composer.json.
    2. Cleanup Config: Remove config/geocoder.php and remove any Geocoder aliases from config/app.php (the package now auto-registers aliases).
    3. Update Service Provider: Ensure Geocoder\Laravel\Providers\GeocoderService::class is in your config/app.php providers array.
    4. Update Facades: If using the facade, either replace Geocoder:: with app('geocoder')-> or update your use statements to use Geocoder\Laravel\Facades\Geocoder;.
    5. Update Queries: Use ->get() to retrieve a collection of GeoCoder objects or ->all() to retrieve an array of arrays.
    "toin0u/geocoder-laravel": "^1.0"
  3. Prevent stale caches during updates

    master

    To prevent stale caches when upgrading or updating the package in both live and development environments, add the following artisan commands to your composer.json file under the scripts section:

    "post-update-cmd": [
        "@php artisan cache:clear",
    ],
    "post-install-cmd": [
        "@php artisan cache:clear",
    ]
  4. Install Geocoder for Laravel

    master

    Install the package using Composer.

    Requirements:

    • PHP >= 8.2
    • Laravel >= 11.0

    Note on Versioning: Starting with version 13.0.0, the major version tracks the highest supported Laravel version (e.g., 13.x supports Laravel 11, 12, and 13).

    composer require toin0u/geocoder-laravel
  5. Upgrade Geocoder Laravel to version 13.x

    master

    When upgrading to version 13.x, follow these steps to ensure compatibility:

    1. Update Dependencies: Update your composer.json to use "toin0u/geocoder-laravel": "^13.0".
    2. Clear Cache: Always run php artisan cache:clear after an upgrade to prevent incompatible cached responses.
    3. Handle the Default HTTP Adapter Change: The default adapter has changed from Http\Client\Curl\Client to Geocoder\Laravel\Http\LaravelHttpClient. This new adapter is a PSR-18 client that integrates with Laravel's Http facade, allowing you to use Http::fake(), retries, timeouts, and middleware.

    If you have a published config/geocoder.php file, you must take one of these actions to avoid runtime errors:

    • Recommended: Delete or rename your existing config/geocoder.php and re-publish it, then re-apply your customizations.
    • Manual Edit: Change the adapter class from Http\Client\Curl\Client to Geocoder\Laravel\Http\LaravelHttpClient and update the 'adapter' key accordingly.
    • Keep Curl: If you prefer the old behavior, install the curl client explicitly via composer require php-http/curl-client.

    Other 13.x Requirements & Changes:

    • Minimum PHP: 8.2
    • Minimum Laravel: 11.x
    • MaxMind Support: MaxMindBinary provider support has been removed. Use geocoder-php/geoip2-provider for MaxMind data instead.
    "toin0u/geocoder-laravel": "^13.0"
  6. Publish the Geocoder configuration file

    master

    To customize the default settings, publish the configuration file to your application's config/ directory using the following Artisan command:

    php artisan vendor:publish --provider="Geocoder\Laravel\Providers\GeocoderService" --tag="config"
  7. Configure a dedicated cache store for Geocoder

    master

    To optimize performance and prevent cache pollution, it is recommended to use a dedicated cache store (e.g., a separate Redis database).

    1. Add a new Redis connection in config/database.php.
    2. Create a new cache store in config/cache.php pointing to that connection.
    3. Update config/geocoder.php to use the new cache store name.
    // 1. config/database.php
    "redis" => [
        "geocode-cache" => [
            'host' => env('REDIS_HOST', '192.168.10.10'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 1, // Use a unique database index
        ],
    ]
    
    // 2. config/cache.php
    "stores" => [
        "geocode" => [
            'driver' => 'redis',
            'connection' => 'geocode-cache',
        ],
    ],
    
    // 3. config/geocoder.php
    "cache" => [
        "store" => "geocode",
    ],
  8. Upgrade Geocoder Laravel from 4.x to 5.x

    master

    When upgrading from 4.x to 5.x, note the following changes:

    1. Update Dependencies: Update your composer.json to use "toin0u/geocoder-laravel": "^5.0".
    2. Collection Migration: Results returned by the geocoder now use Laravel's native Collection class instead of AddressCollection. Most methods like count(), first(), isEmpty(), slice(), has(), get(), and all() map directly, but verify your implementation.
    3. Provider Migration: getProviders() now returns a Laravel Collection instead of an array.
    4. Iteration: The getIterator() method is no longer needed; iterate over results directly as a standard Laravel collection.

    Deprecations (to be removed in 5.0.0):

    • Use get() instead of all() on the geocoder to retrieve a Collection. You can then call all() on the resulting collection.
    • Use getProviders() instead of getProvider(). You can then call first() on the resulting collection to get a single provider.
    "toin0u/geocoder-laravel": "^5.0"
  9. Register the Geocoder Service Provider

    master

    If you are using a version of Laravel older than 5.5 (though the current requirements specify Laravel >= 11.0), you must manually register the service provider in config/app.php within the providers array.

    Note: For Laravel 5.5 and above, the package is auto-discovered and this step is unnecessary.

    // 'providers' => [
        Geocoder\Laravel\Providers\GeocoderService::class,
    // ];
  10. Configure HTTP Adapters and options

    master

    The adapter defines the PSR-18 client used for requests.

    • Default: LaravelHttpClient, which uses Laravel's Http facade. This allows you to use Http::fake() in tests and provides native retry/timeout support.
    • Customizing Options: You can pass constructor arguments to the adapter via an array in config/geocoder.php. For the LaravelHttpClient, you can pass timeout, connectTimeout, retry, and options (Guzzle transport options).
    • Swapping Adapters: To use a different client (like php-http/curl-client), provide the class name. If the constructor requires arguments, use the [Class => [args]] format.
    // Using LaravelHttpClient with custom options
    'adapter' => [\Geocoder\Laravel\Http\LaravelHttpClient::class => [
        'timeout' => 10,
        'connectTimeout' => 3,
        'retry' => [3, 100],             // [times, sleepMilliseconds]
        'options' => ['verify' => false], // Guzzle transport options
    ]],
    
    // Using a different transport (e.g., CURL)
    'adapter' => [\Http\Client\Curl\Client::class => [
        null,
        null,
        [CURLOPT_PROXY => env('CURL_PROXY'), CURLOPT_PROXYUSERPWD => env('CURL_PROXYUSERPWD')],
    ]],
  11. How the Geocoder service provider works

    master

    The GeocoderService is the core Laravel Service Provider that integrates the Geocoder library into your application. It performs the following tasks during the Laravel boot process:

    1. Configuration Publishing: It allows you to publish the geocoder.php configuration file to your application's config/ directory using php artisan vendor:publish.
    2. Dependency Injection: It registers the ProviderAndDumperAggregator as a singleton, which is responsible for instantiating the geocoding providers defined in your geocoder.providers configuration.
    3. Aliasing: It aliases the Geocoder facade to the Geocoder class for easy access.
    4. Cache Safety: It automatically discovers and registers Geocoder model classes into Laravel's cache.serializable_classes to prevent unserialization errors when using cache stores.
  12. Configure Geocoder providers and the Chain provider

    master

    The providers configuration defines which services are used for geocoding.

    • Chain Provider: A special provider that runs multiple providers in sequence. If the first provider fails, the next one in the list is executed.
    • Default Setup: By default, the package uses a Chain containing GoogleMaps (for addresses and reverse lookups) and GeoPlugin (for IP addresses).
    • Manual Selection: You can explicitly use a specific provider by its alias using app('geocoder')->using('alias').
    // config/geocoder.php
    'providers' => [
        \Geocoder\Provider\Chain\Chain::class => [
            \Geocoder\Provider\GoogleMaps\GoogleMaps::class => [
                env('GOOGLE_MAPS_LOCALE', 'us'),
                env('GOOGLE_MAPS_API_KEY'),
            ],
            \Geocoder\Provider\GeoPlugin\GeoPlugin::class => [],
        ],
    ],