dseguy / php-gremlin
PHP client for Apache TinkerPop Gremlin Server 4.0 over its HTTP protocol
Package info
Language:Gherkin
pkg:composer/dseguy/php-gremlin
Requires
- php: >=8.2
- ext-curl: *
- ext-json: *
Requires (Dev)
- behat/behat: ^3.33
- phpstan/phpstan: ^1.11
- phpunit/phpunit: ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-09-25 05:29:25 UTC
README
A PHP client for Apache TinkerPop Gremlin Server 4.0, talking to its HTTP endpoint directly (TinkerPop 4 dropped the old WebSocket sub-protocol, so there is no session/handshake layer to manage).
- Query & fetch — send Gremlin queries, get back plain PHP values, real
Vertex/Edge/Path/Propertyobjects, or your own hydrated PHP classes. - A fluent Gremlin DSL —
$g->V()->out('knows')->filter(...)->order()->by(...)reads like real Gremlin because it renders to real Gremlin-lang text; the server parses and executes it exactly as it would any other client's query. - Two wire formats — GraphBinary V4 by default (compact, fast), GraphSON V4 as an explicit opt-in for human-readable debugging.
- A mass loader — stream GraphML or GraphSON exports into a running server in batches, without loading the whole file into memory.
Everything here was built and verified against a real Gremlin Server
4.0.0-beta.3, including the entire Apache TinkerPop Gherkin conformance
suite (437 scenarios, run via
Behat — see Testing) — not just unit tests
against assumptions about the protocol.
Requirements
- PHP >= 8.2
ext-curl,ext-json- A Gremlin Server 4.0 instance to connect to
Installation
composer require dseguy/php-gremlin
Quick start
use Gremlin\Driver\GremlinClient; use Gremlin\Driver\RemoteConnection; use Gremlin\Process\Traversal\GraphTraversalSource; use Gremlin\Process\Traversal\P; use Gremlin\Process\Traversal\__; use Gremlin\Structure\Order; $client = new GremlinClient('localhost', 8182); $g = new GraphTraversalSource(new RemoteConnection($client)); // Plain values back for plain queries. $names = $g->V()->hasLabel('person')->values('name')->toList(); // Real Vertex/Edge objects for element-shaped results. $marko = $g->V()->has('name', 'marko')->next(); // Gremlin\Structure\Vertex echo $marko->value('age'); // The fluent DSL renders straight to Gremlin-lang text - server-side semantics, // not a local reimplementation of them. $adults = $g->V()->out('knows') ->filter(__::has('age', P::gt(28))) ->order()->by('name', Order::Asc) ->values('name') ->toList(); // addV()/addE() mutate the graph the same way. $vertex = $g->addV('person')->property('name', 'alice')->next();
Hydrating into your own classes
Vertex/Edge results can be mapped onto a plain PHP class instead, by property
name (id/label are special-cased):
final class Person { public int|string $id; public string $name; public int $age; } $people = $g->V()->hasLabel('person')->hydrateAs(Person::class)->toList(); // list<Person>
Serializers
GraphBinary V4 is the default (Gremlin\Driver\Serializer\GraphBinarySerializerV4).
Pass GraphSON explicitly when you want to inspect requests/responses as JSON, e.g.
while debugging against curl:
use Gremlin\Driver\Serializer\GraphSONSerializerV4; $client = new GremlinClient('localhost', 8182, new GraphSONSerializerV4());
Both serializers decode into the exact same PHP shapes - switching between them never changes what your code gets back.
Mass loading GraphML / GraphSON
use Gremlin\IO\BulkLoader; use Gremlin\IO\GraphMLReader; // or GraphSONReader for TinkerPop's line-delimited export format $reader = new GraphMLReader('/path/to/export.xml'); $loader = new BulkLoader($g, batchSize: 500); $result = $loader->load($reader, function (int $vertices, int $edges): void { echo "loaded {$vertices} vertices, {$edges} edges so far\n"; }); echo "done: {$result->vertexCount} vertices, {$result->edgeCount} edges\n";
Both readers stream the source file (XMLReader for GraphML, line-by-line for
GraphSON) rather than loading it whole, and BulkLoader batches multiple
vertices/edges into a single request per batch instead of one round trip per
element.
Testing
composer install vendor/bin/phpunit tests/Unit # no server needed vendor/bin/phpunit tests/Integration # needs a live Gremlin Server 4.0 (see below) vendor/bin/behat # the TinkerPop conformance suite - same requirement vendor/bin/phpstan analyse
The integration and Behat suites expect a Gremlin Server 4.0 running locally
(localhost:8182 for tests/Integration, localhost:8184 with three named
toy-graph traversal sources - gmodern/gclassic/gempty - for
vendor/bin/behat; see tests/gremlin-test/bootstrap/FeatureContext.php and
tests/Integration/LiveServerTest.php for the exact configuration expected).
They are not part of CI for that reason - only tests/Unit and PHPStan run
there.
tests/gremlin-test/ vendors a curated subset of Apache TinkerPop's own
language-agnostic Gherkin feature files under their original Apache-2.0 license;
see tests/gremlin-test/VENDORED_FROM.md for provenance and the curation
rationale.
License
Apache-2.0. See LICENSE. Files under tests/gremlin-test/features/
originate from the apache/tinkerpop
project and retain their original license headers.