PHPackages                             richardwooding/arcgis - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. richardwooding/arcgis

ActiveLibrary[HTTP &amp; Networking](/categories/http)

richardwooding/arcgis
=====================

A small, dependency-free PHP client for querying ArcGIS Feature Services over their REST API.

v0.1.0(today)00MITPHPPHP &gt;=8.2CI passing

Since Jun 20Pushed todayCompare

[ Source](https://github.com/richardwooding/php-arcgis)[ Packagist](https://packagist.org/packages/richardwooding/arcgis)[ RSS](/packages/richardwooding-arcgis/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (3)Versions (2)Used By (0)

php-arcgis
==========

[](#php-arcgis)

[![CI](https://github.com/richardwooding/php-arcgis/actions/workflows/ci.yml/badge.svg)](https://github.com/richardwooding/php-arcgis/actions/workflows/ci.yml)[![Latest Stable Version](https://camo.githubusercontent.com/1ed09c2c4ae7306c24fbd78928af93044a6c9b574d035ae719f7b9044f01b7cb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f72696368617264776f6f64696e672f6172636769732e737667)](https://packagist.org/packages/richardwooding/arcgis)[![Total Downloads](https://camo.githubusercontent.com/c2cef6544d30e1691dbc96acb0bfd85e312bf29713d7b55a9c7da5068a3f831d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f72696368617264776f6f64696e672f6172636769732e737667)](https://packagist.org/packages/richardwooding/arcgis)[![PHP Version Require](https://camo.githubusercontent.com/de0325111103c7a7347ac335c22223ac1d4bbaca83844ce1f6e70e857230f227/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f72696368617264776f6f64696e672f6172636769732f7068702e737667)](https://packagist.org/packages/richardwooding/arcgis)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)

A small, dependency-free PHP client for querying **ArcGIS Feature Services**over their REST API. It handles pagination, counts, and object-ID-only queries, and offers two interchangeable styles: a plain value-object API and a fluent builder.

This is a PHP port of [`go-arcgis`](https://github.com/richardwooding/go-arcgis)and tracks its design closely.

```
use RichardWooding\ArcGis\Client;

$client = new Client($baseUrl);

$features = $client->layer(7)->query()
    ->where('STAGE = 4')
    ->fields('BLOCK_NAME', 'STAGE')
    ->all(); // paginates automatically
```

Install
-------

[](#install)

```
composer require richardwooding/arcgis
```

Requires PHP 8.2+ and the `curl` and `json` extensions. No third-party Composer dependencies.

Two styles, one engine
----------------------

[](#two-styles-one-engine)

The fluent builder and the value-object API produce the same `QueryParams` and hit the same code path — pick whichever reads better at the call site.

### Value-object style — explicit and serializable

[](#value-object-style--explicit-and-serializable)

```
use RichardWooding\ArcGis\QueryParams;

$fs = $client->query(new QueryParams(
    layerId: 7,
    where: 'STAGE = 4',
    fields: ['BLOCK_NAME', 'STAGE'],
    pageSize: 100,
));
```

### Fluent style — readable and chainable

[](#fluent-style--readable-and-chainable)

```
$features = $client->layer(7)->query()
    ->where('STAGE = 4')
    ->fields('BLOCK_NAME', 'STAGE')
    ->withinEnvelope(18.4, -34.0, 18.6, -33.8)
    ->all();
```

Querying
--------

[](#querying)

CallReturnsNotes`query` / `->first``FeatureSet`a single page`queryAll` / `->all``list`follows `exceededTransferLimit` until exhausted`queryCount` / `->count``int`no feature data transferred`queryIds` / `->ids``list`object IDs onlyPagination is automatic: `queryAll` keeps advancing `resultOffset` while the service reports `exceededTransferLimit`.

Attributes are exposed uniformly regardless of the response format — `Feature::attrs()` returns the Esri-JSON `attributes` map, falling back to the GeoJSON `properties` map:

```
foreach ($features as $f) {
    echo $f->attrs()['BLOCK_NAME'], "\n";
}
```

Spatial filters
---------------

[](#spatial-filters)

```
// Bounding box (lon/lat)
$client->layer(7)->query()->withinEnvelope(18.4, -34.0, 18.6, -33.8);

// Point with an explicit relationship
use RichardWooding\ArcGis\SpatialRel;

$client->layer(7)->query()
    ->intersectsPoint(18.42, -33.92)
    ->spatialRel(SpatialRel::Within);

// Polygon (one or more [x, y] rings)
$client->layer(7)->query()->withinPolygon([
    [[18.0, -34.0], [18.1, -34.0], [18.1, -34.1], [18.0, -34.0]],
]);
```

Geometry filters default to the WGS84 (`inSR` 4326) spatial reference and the `intersects` relationship. Override `inSR` when your coordinates are in another spatial reference, or a WGS84 box will silently match nothing against a layer stored in, say, Web Mercator.

Output format
-------------

[](#output-format)

GeoJSON is the default. Switch to Esri JSON when you need its richer metadata (`objectIdFieldName`, field definitions):

```
use RichardWooding\ArcGis\OutputFormat;

$client->layer(7)->query()->format(OutputFormat::Json)->first();
```

`count` and `ids` always use Esri JSON internally, since that is the only format ArcGIS returns those responses in.

Options
-------

[](#options)

```
use RichardWooding\ArcGis\Client;

$client = new Client(
    $baseUrl,
    token: '…',      // authenticated services; appended to every request
    timeout: 10.0,   // seconds, for the default curl transport
);

// Or bring your own transport (e.g. a Guzzle/PSR-18 wrapper):
$client = new Client($baseUrl, httpClient: $myHttpClient);
```

A token, when set, is appended to every request — queries, counts, service and layer metadata.

Errors
------

[](#errors)

ArcGIS frequently reports failures with an HTTP 200 status and an error envelope in the body. `php-arcgis` surfaces these as `ApiException`:

```
use RichardWooding\ArcGis\Exception\ApiException;

try {
    $client->query($params);
} catch (ApiException $e) {
    echo $e->getCode(), ': ', $e->getArcGisMessage(), "\n";
    print_r($e->getDetails());
}
```

Transport failures, non-200 statuses, and undecodable bodies are raised as `TransportException`. Both extend `ArcGisException`.

Large queries
-------------

[](#large-queries)

A query carrying a detailed geometry (e.g. a ward or suburb polygon with hundreds of vertices) can exceed typical server URL-length limits, which ArcGIS manifests as an HTTP 404. The client transparently falls back from a GET to a form-encoded POST when the encoded query string grows large; ArcGIS REST endpoints accept the same parameters either way.

Named services
--------------

[](#named-services)

Build named layer IDs and pre-built `QueryParams` for a specific service, then extend them at the call site with `->from(...)`:

```
function loadSheddingForStage(int $stage): QueryParams
{
    return new QueryParams(
        layerId: 111,
        where: "STAGE = {$stage}",
        fields: ['BLOCK_NAME', 'STAGE'],
    );
}

$features = $client->layer(111)->query()
    ->from(loadSheddingForStage(4))
    ->withinEnvelope(18.4, -34.0, 18.6, -33.8)
    ->all();
```

Development
-----------

[](#development)

```
composer install
composer test    # PHPUnit (no live network — uses a mock transport)
composer stan    # PHPStan (max level)
composer lint    # PHP-CS-Fixer dry run
composer fix     # PHP-CS-Fixer apply
```

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md).

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

36

—

LowBetter than 80% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/373901?v=4)[Richard Wooding](/maintainers/richardwooding)[@richardwooding](https://github.com/richardwooding)

---

Top Contributors

[![richardwooding](https://avatars.githubusercontent.com/u/373901?v=4)](https://github.com/richardwooding "richardwooding (3 commits)")

---

Tags

arcgisesrifeature-servicegeojsongisphpphp-libraryrestrest-apirestgisgeojsonESRIArcGISfeature-service

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/richardwooding-arcgis/health.svg)

```
[![Health](https://phpackages.com/badges/richardwooding-arcgis/health.svg)](https://phpackages.com/packages/richardwooding-arcgis)
```

###  Alternatives

[zircote/swagger-php

Generate interactive documentation for your RESTful API using PHP attributes (preferred) or PHPDoc annotations

5.3k140.4M554](/packages/zircote-swagger-php)[psr/link

Common interfaces for HTTP links

2.5k149.8M81](/packages/psr-link)[league/fractal

Handle the output of complex data structures ready for API output.

3.5k66.1M529](/packages/league-fractal)[friendsofsymfony/rest-bundle

This Bundle provides various tools to rapidly develop RESTful API's with Symfony

2.8k75.0M336](/packages/friendsofsymfony-rest-bundle)[lexik/jwt-authentication-bundle

This bundle provides JWT authentication for your Symfony REST API

2.6k61.3M242](/packages/lexik-jwt-authentication-bundle)[nelmio/api-doc-bundle

Generates documentation for your REST API from attributes

2.3k66.1M253](/packages/nelmio-api-doc-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
