hivellm / nexus-php
Official PHP client library for Nexus, a high-performance Neo4j-compatible graph database
Requires
- php: >=8.1
- guzzlehttp/guzzle: ^7.8
- psr/http-client: ^1.0
- rybakit/msgpack: ^0.9
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.5
- squizlabs/php_codesniffer: ^3.8
This package is auto-updated.
Last update: 2026-07-21 12:28:53 UTC
README
Official PHP client library for Nexus, a high-performance Neo4j-compatible graph database.
Compatibility: SDK 2.5.0 ↔
nexus-server2.5.0. SDK and server move in lockstep on the same X.Y.Z train. Seedocs/COMPATIBILITY_MATRIX.md.
Features
- Binary RPC by default — connects over
nexus://127.0.0.1:15475using length-prefixed MessagePack; 3–10× lower latency and 40–60% smaller payloads than the legacy HTTP path. - HTTP fallback in one line — pass an
http://…URL or setConfig::$transport = TransportMode::Httpto use the REST transport. - Complete Cypher Support - Execute any Cypher query with parameters
- CRUD Operations - Simplified methods for nodes and relationships
- Batch Operations - Create multiple nodes/relationships efficiently
- Transaction Support - Full ACID transaction management
- Schema Management - Indexes, labels, and relationship types
- Authentication - API keys and bearer tokens
- Modern PHP - PHP 8.1+ with strict types and readonly properties
- PSR Compliant - Follows PSR-4, PSR-12, and uses PSR-18 HTTP client
- Type Safe - Full type hints and return types
Requirements
- PHP 8.1 or higher
- Composer
- Nexus server 1.0.0 or higher
Installation
composer require hivellm/nexus-php
Quick Start (RPC — default)
<?php require 'vendor/autoload.php'; use Nexus\SDK\Config; use Nexus\SDK\NexusClient; // Defaults to nexus://127.0.0.1:15475 (binary RPC). $config = new Config( baseUrl: 'nexus://127.0.0.1:15475', apiKey: 'your-api-key', // Optional timeout: 30 ); $client = new NexusClient($config); // Check connection $client->ping(); // Execute Cypher query $result = $client->executeCypher( 'MATCH (n:Person) WHERE n.age > $minAge RETURN n.name, n.age ORDER BY n.age DESC', ['minAge' => 25] ); // Process results foreach ($result->rows as $row) { echo "Name: {$row['n.name']}, Age: {$row['n.age']}\n"; } echo "Query took {$result->stats?->executionTimeMs}ms\n";
Usage Examples
Creating Nodes
// Create a single node $node = $client->createNode( labels: ['Person'], properties: [ 'name' => 'John Doe', 'age' => 30, 'email' => 'john@example.com' ] ); echo "Created node with ID: {$node->id}\n"; // Batch create multiple nodes $nodes = $client->batchCreateNodes([ [ 'labels' => ['Person'], 'properties' => ['name' => 'Alice', 'age' => 28] ], [ 'labels' => ['Person'], 'properties' => ['name' => 'Bob', 'age' => 32] ] ]); echo "Created " . count($nodes) . " nodes\n";
External IDs
Nodes can carry a caller-supplied external id in prefixed string form.
Supported variants: sha256:<64-hex>, blake3:<64-hex>, sha512:<128-hex>,
uuid:<canonical>, str:<utf8 ≤256 B>, bytes:<hex ≤128 chars>.
$client = new NexusClient(new Config(baseUrl: 'http://localhost:15474')); // Create via Cypher with an external id $result = $client->executeCypher( "CREATE (n:Document {_id: 'str:doc-phase10', title: 'Phase 10 spec'}) RETURN n._id" ); echo $result->rows[0][0] . "\n"; // str:doc-phase10 // Retrieve by external id $resp = $client->getNodeByExternalId('str:doc-phase10'); if ($resp['node'] !== null) { echo "Node id: " . $resp['node']['id'] . "\n"; } // Conflict policies via Cypher ON CONFLICT $client->executeCypher( "CREATE (n:Document {_id: 'str:doc-phase10', title: 'Updated'}) ON CONFLICT REPLACE RETURN n._id" );
Run the live test suite (requires a running server):
NEXUS_LIVE_HOST=http://localhost:15474 vendor/bin/phpunit --group live
Creating Relationships
// Create a relationship $rel = $client->createRelationship( startNode: $node1->id, endNode: $node2->id, type: 'KNOWS', properties: [ 'since' => '2020', 'strength' => 0.8 ] ); echo "Created relationship: {$rel->type}\n"; // Batch create relationships $rels = $client->batchCreateRelationships([ [ 'start_node' => '1', 'end_node' => '2', 'type' => 'KNOWS', 'properties' => ['since' => '2020'] ], [ 'start_node' => '2', 'end_node' => '3', 'type' => 'WORKS_WITH', 'properties' => ['project' => 'GraphDB'] ] ]);
Reading and Updating Data
// Get node by ID $node = $client->getNode('1'); echo "Node: {$node->properties['name']}\n"; // Update node properties $updated = $client->updateNode('1', [ 'age' => 31, 'updated_at' => time() ]); // Get relationship $rel = $client->getRelationship('r1'); // Delete node $client->deleteNode('1'); // Delete relationship $client->deleteRelationship('r1');
Transactions
// Begin transaction $tx = $client->beginTransaction(); try { // Execute queries in transaction $tx->executeCypher("CREATE (n:Person {name: \$name})", ['name' => 'Transaction User']); $tx->executeCypher("CREATE (n:Person {name: \$name})", ['name' => 'Another User']); // Commit transaction $tx->commit(); echo "Transaction committed successfully\n"; } catch (Exception $e) { // Rollback on error $tx->rollback(); echo "Transaction rolled back: {$e->getMessage()}\n"; }
Schema Management
// List all labels. Each entry is ['name' => '...', 'id' => N] — // `id` is the catalog id allocated by the engine, not a count. // (Renamed from a JSON tuple ['Person', 0] in nexus-server 1.15+, // see https://github.com/hivellm/nexus/issues/2.) $labels = $client->listLabels(); foreach ($labels as $label) { echo " {$label['name']} (id={$label['id']})\n"; } // List all relationship types — same shape as labels. $types = $client->listRelationshipTypes(); foreach ($types as $relType) { echo " {$relType['name']} (id={$relType['id']})\n"; } // Create index $client->createIndex('person_name_idx', 'Person', ['name']); // List indexes $indexes = $client->listIndexes(); foreach ($indexes as $idx) { echo "Index: {$idx->name} on {$idx->label}(" . implode(', ', $idx->properties) . ")\n"; } // Delete index $client->deleteIndex('person_name_idx');
Error Handling
use Nexus\SDK\NexusApiException; use Nexus\SDK\NexusException; try { $result = $client->executeCypher('INVALID QUERY'); } catch (NexusApiException $e) { echo "HTTP {$e->statusCode}: {$e->responseBody}\n"; match ($e->statusCode) { 400 => echo "Bad request - check your query syntax\n", 401 => echo "Unauthorized - check your API key\n", 404 => echo "Not found\n", 500 => echo "Server error\n", default => echo "Unknown error\n" }; } catch (NexusException $e) { echo "Nexus SDK error: {$e->getMessage()}\n"; } catch (Exception $e) { echo "Unexpected error: {$e->getMessage()}\n"; }
Authentication
API Key
$config = new Config( baseUrl: 'nexus://127.0.0.1:15475', apiKey: 'your-api-key' ); $client = new NexusClient($config);
Username/Password
$config = new Config( baseUrl: 'nexus://127.0.0.1:15475', username: 'admin', password: 'password' ); $client = new NexusClient($config);
Bearer Token
$config = new Config(baseUrl: 'nexus://127.0.0.1:15475'); $client = new NexusClient($config); // Set token manually after authentication $client->setToken('your-jwt-token');
Configuration
class Config { public function __construct( public string $baseUrl = 'nexus://127.0.0.1:15475', public ?string $apiKey = null, public ?string $username = null, public ?string $password = null, public int $timeout = 30, public ?\Nexus\SDK\Transport\TransportMode $transport = null, public ?int $rpcPort = null, public ?int $resp3Port = null, ) {} }
Models
Node
class Node { public string $id; // Unique identifier public array $labels; // Node labels public array $properties; // Node properties }
Relationship
class Relationship { public string $id; // Unique identifier public string $type; // Relationship type public string $startNode; // Start node ID public string $endNode; // End node ID public array $properties; // Relationship properties }
QueryResult
class QueryResult { public array $columns; // Column names public array $rows; // Result rows public ?QueryStats $stats; // Execution statistics } class QueryStats { public int $nodesCreated; public int $nodesDeleted; public int $relationshipsCreated; public int $relationshipsDeleted; public int $propertiesSet; public float $executionTimeMs; }
Testing
Run tests with PHPUnit:
composer test
Run static analysis:
composer phpstan
Check code style:
composer cs-check
Fix code style:
composer cs-fix
Examples
See the examples directory for complete working examples:
basic_usage.php- Basic CRUD operationstransactions.php- Transaction managementbatch_operations.php- Batch node/relationship creationschema_management.php- Working with indexes and schema
Performance Tips
- Use Batch Operations - For creating multiple nodes/relationships
- Reuse Client - Create one client instance and reuse it
- Parameterized Queries - Always use parameters instead of string concatenation
- Transactions - Group related operations for consistency and performance
- Connection Timeout - Set appropriate timeout for your use case
License
Apache License 2.0 - see LICENSE file for details
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Support
- Documentation: https://github.com/hivellm/nexus
- Issues: https://github.com/hivellm/nexus/issues
- Discussions: https://github.com/hivellm/nexus/discussions