# geocoder-php/Geocoder: a PHP abstraction layer for geocoding providers

> The library splits geocoding into a provider you install separately and a PSR-18 HTTP client you already trust. That decoupling is the whole design, and it decides when the library fits.

**geocoder-php/Geocoder** — The most featured Geocoder library written in PHP.

- Repository: https://github.com/geocoder-php/Geocoder
- Website: https://geocoder-php.org
- Stars: 3,973 · Forks: 525
- Language: PHP
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/geocoder-php-geocoder

## What geocoder-php/Geocoder actually abstracts

The library does not geocode anything by itself. It defines an interface and a set of query and result objects, then delegates every network call to a provider package that you install alongside it. The README describes it as "a powerful abstraction layer for geocoding manipulations", and the important word there is abstraction. If you are writing an application that resolves street addresses to coordinates, or coordinates back to addresses, and you do not want the rest of your code to know whether the answer came from Google Maps, ArcGIS Online or Azure Maps, this is the layer that makes the swap a constructor change rather than a rewrite.

The audience is PHP developers working inside an existing application, usually a web backend or a queue worker that processes addresses in bulk. It is not a command line tool, not a hosted service and not a data source. You bring the API key and the HTTP client; the library brings the shape of the calls and the shape of the responses.

## The provider and HTTP client split introduced in 4.0

Before 4.0 the HTTP adapters shipped inside the library. The README states plainly that since 4.0 providers are not included by default, and that 4.x relies on PSR-18 for sending and receiving HTTP messages. That means two independent choices: a package implementing geocoder-php/provider-implementation, and a package implementing psr/http-client-implementation. Packagist maintains a list of both, and the README links to each.

The payoff is that you are not forced onto a particular HTTP stack. The cost is that a bare `composer require geocoder-php/geocoder` gets you interfaces and query objects and nothing that can reach a network. New users hit this immediately, and the README handles it by jumping straight to a concrete pair of commands rather than a conceptual explanation.

The Provider interface exposes three methods: `geocodeQuery(GeocodeQuery $query):AddressCollection`, `reverseQuery(ReverseQuery $query):AddressCollection` and `getName():string`. The Geocoder interface extends Provider and adds `geocode($streetOrIpAddress)` and `reverse($latitude, $longitude)`, which the README describes as easing migration from 3.x. So the query-object style is the current surface and the string-and-float style is a compatibility convenience.

## Installing geocoder-php/Geocoder with Google Maps and Guzzle

There is nothing to download from a website. Installation is Composer, and you pick the provider and the client in the same command. For Google Maps with Guzzle 7 the README gives this:

```bash
composer require geocoder-php/google-maps-provider guzzlehttp/guzzle
```

If you prefer a curl-based client you need a PSR-7 implementation as well, because the curl client does not supply one. The README's version uses nyholm/psr7:

```bash
composer require geocoder-php/google-maps-provider php-http/curl-client nyholm/psr7
```

With those installed, the README's usage snippet wires the client into the provider, wraps the provider in a StatefulGeocoder with a locale, and issues a query:

```php
use Geocoder\Query\GeocodeQuery;
use Geocoder\Query\ReverseQuery;

$httpClient = new \GuzzleHttp\Client();
$provider = new \Geocoder\Provider\GoogleMaps\GoogleMaps($httpClient, null, 'your-api-key');
$geocoder = new \Geocoder\StatefulGeocoder($provider, 'en');

$result = $geocoder->geocodeQuery(GeocodeQuery::create('Buckingham Palace, London'));
$result = $geocoder->reverseQuery(ReverseQuery::fromCoordinates(...));
```

The second constructor argument is null in the README example and the third is the API key string. Both calls return an AddressCollection, so iteration and result handling are the same regardless of which provider produced the data. If you already run Laravel or Symfony, the README points at `geocoder-php/GeocoderLaravel` and `geocoder-php/BazingaGeocoderBundle` respectively instead of manual wiring.

## Where the abstraction leaks: coverage, keys and rate limits

A uniform interface does not make providers interchangeable in practice. The README's provider tables carry a Features column, and entries differ: Algolia Places is listed as address, while ArcGIS Online is listed as address and reverse. If your application needs reverse geocoding and you pick a provider that only does forward geocoding, the interface will not save you. Check that column before you commit to a provider, not after.

The second leak is credentials and quota. Every real provider here is an HTTP API belonging to someone else, so the API key, the billing relationship and the request ceiling are all upstream concerns. The library does not manage any of that. The README addresses it indirectly through the cookbook, which links to pages on caching responses and on rate limiting API requests. Those are the two problems you will actually hit in production, and they are documented as separate recipes rather than as features of the core.

Third, the provider list is long and unevenly maintained, because each provider is its own repository under the geocoder-php organisation. The core library being current says nothing about the state of an individual provider package. Verify the one you need.

## Composing providers: cache and chain wrappers

The special providers are the most interesting part of the design. `geocoder-php/cache-provider` wraps another provider and caches its results; `geocoder-php/chain-provider` iterates over multiple providers. Both implement the same Provider interface, so they nest. A cache wrapper around a chain of two providers is a valid construction, and the calling code still sees one geocodeQuery method.

The chain provider is the practical answer to vendor risk: if the first provider returns nothing for an address, the next one is tried. That is a different approach from picking the best single vendor, and it costs you a second API relationship and second set of terms to respect. The cache provider is the answer to repeated lookups of the same address, which is common when addresses arrive from user input or from a table you reprocess.

Neither wrapper is described in the README beyond a one-line feature summary and a link. If you need to know the cache key strategy or the exact fallback semantics of the chain, you are reading the separate repositories, not this one.

## When geocoder-php/Geocoder is the wrong tool

If you need geocoding without any external API call, this library is not it. It has no bundled dataset and no offline mode; every provider listed talks to a remote service. The same applies if you want to geocode addresses you already store in a database with your own matching logic. That is a different problem, usually solved with a spatial index in the database rather than a provider abstraction.

Language is the harder boundary. The search data around the word geocoder is full of Python and Android questions, and this package answers none of them. It is a PHP library and its framework integrations are Laravel and Symfony. A Python team looking at this repository is looking at the wrong ecosystem, however similar the naming.

There is also a version trap. The README you land on warns that it documents Geocoder 4.x and links to separate 3.x and 2.x READMEs. The most recent release listed is 5.0.0 from 2025-01-01, while the README still carries the 4.x notice at the top. If you are following a tutorial written against 3.x, the query-object API and the PSR-18 requirement will not match what you find.

## Alternatives and the difference in approach

The nearest alternative in the same ecosystem is to skip the abstraction and call the vendor SDK directly. If you use only Google Maps and expect to keep using only Google Maps, the official PHP client gives you the vendor's full surface, including features the abstraction does not model, at the cost of coupling your call sites to that vendor. geocoder-php/Geocoder deliberately trades that surface away for uniformity, and the trade only pays off if you have, or expect to have, more than one provider.

For PHP teams already on Symfony, the bundle `geocoder-php/BazingaGeocoderBundle` is not really an alternative but a different integration path: it wires the same library into the container. Choosing it is a decision about configuration style, not about geocoding behaviour.

Outside PHP, the equivalent role is played by language-specific clients, and the search data reflects that with Python and Android questions. The architectural difference is the same everywhere: a thin client for one vendor versus an interface over several. This library sits firmly on the interface side, and it charges you the configuration overhead of the provider-plus-client pair for the privilege.

## Conclusion

Adopt geocoder-php/Geocoder if you are building a PHP application that must talk to one or more geocoding HTTP APIs and you want to swap vendors without rewriting call sites. Skip it if you need an offline gazetteer, a database of your own addresses, or a Python or JavaScript tool; the README points Python users elsewhere and this package is PHP only. Before committing, verify the provider package you actually need exists on Packagist, check whether that provider is listed as address only or address and reverse, and confirm the API key and quota terms of the upstream service you pick.

## FAQ

### What does geocoder-php/Geocoder do?

It is a PHP library that provides an abstraction layer for geocoding, defining Provider, Geocoder, GeocodeQuery and ReverseQuery types and delegating the actual network calls to a separately installed provider package. It does not geocode anything on its own.

### How do I install geocoder-php/Geocoder?

Install it with Composer, choosing a provider package and an HTTP client in the same command. The README's example is composer require geocoder-php/google-maps-provider guzzlehttp/guzzle, or the curl client variant with php-http/curl-client and nyholm/psr7.

### How do I use geocoder-php/Geocoder to geocode an address?

Construct an HTTP client, pass it to a provider constructor along with the API key, wrap the provider in a StatefulGeocoder with a locale, then call geocodeQuery(GeocodeQuery::create('...')) and read the returned AddressCollection. The README shows this sequence with GoogleMaps and Guzzle 7.

### Is geocoder-php/Geocoder free?

The library itself is MIT licensed, so the code is free to use. The geocoding APIs it calls are separate services with their own keys and terms, so the cost of using it depends entirely on the provider you install.

### Is Google geocoder free with geocoder-php/Geocoder?

The library does not change the terms of the Google Maps API. You supply an API key to the GoogleMaps provider constructor, and the billing and quota rules of that service apply to the requests the provider makes.

### How do I geocode with Google Maps using geocoder-php/Geocoder?

Install geocoder-php/google-maps-provider with an HTTP client, construct GoogleMaps with the client and your API key, wrap it in a StatefulGeocoder, then call geocodeQuery with a GeocodeQuery built from the address string.

## Sources

- [geocoder-php/Geocoder on GitHub](https://github.com/geocoder-php/Geocoder)
- [License: MIT](https://github.com/geocoder-php/Geocoder/blob/master/LICENSE)
- [Project website](https://geocoder-php.org)
- [README](https://github.com/geocoder-php/Geocoder/blob/master/README.md)
- [Releases](https://github.com/geocoder-php/Geocoder/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/geocoder-php-geocoder
