gino-pane / neo4j-php-client
Neo4j-PHP-Client is the most advanced PHP Client for Neo4j
Installs: 13
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 136
pkg:composer/gino-pane/neo4j-php-client
Requires
- php: ^7.1.3|^8.0
- ext-bcmath: *
- ext-mbstring: *
- autoprotect-group/neo4j-bolt: ^1.12.4
- autoprotect-group/neo4j-common: ^3.6.2
- myclabs/php-enum: ^1.4
- php-http/client-common: ^2.3
- php-http/discovery: ^1.10
- php-http/guzzle6-adapter: ^2.0.2
- php-http/httplug: ^2.2
- php-http/message: ^1.0
- php-http/message-factory: ^1.0
- symfony/event-dispatcher: ^4.0 || ^5.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.0
- phpunit/phpunit: ^4.0
- symfony/stopwatch: ^3.0
- dev-master
- 5.4.4
- 5.3.4
- 5.3.3
- 5.3.2
- 5.3.1
- 5.3.0
- 5.2.0
- 5.1.1
- 5.1.0
- 5.0.0
- 4.8.5
- 4.8.4
- 4.8.3
- 4.8.2
- 4.8.1
- 4.8.0
- 4.7.0
- 4.6.4
- 4.6.3
- 4.6.2
- 4.6.1
- 4.6.0
- 4.5.5
- 4.5.4
- 4.5.3
- 4.5.2
- 4.5.1
- 4.5.0
- 4.4.7
- 4.4.6
- 4.4.5
- 4.4.4
- 4.4.3
- 4.4.2
- 4.4.1
- 4.4.0
- 4.3.1
- 4.3.0
- 4.2.1
- 4.2.0
- 4.1.1
- 4.1.0
- 4.0.x-dev
- 4.0.2
- 4.0.1
- 4.0.0
- 4.0.0-alpha15
- 4.0.0-alpha14
- 4.0.0-alpha13
- 4.0.0-alpha12
- 4.0.0-alpha11
- 4.0.0-alpha10
- 4.0.0-alpha9
- 4.0.0-alpha8
- 4.0.0-alpha7
- 4.0.0-alpha6
- 4.0.0-alpha5
- 4.0.0-alpha4
- 4.0.0-alpha3
- 4.0.0-alpha2
- 4.0.0-alpha1
- 3.4.x-dev
- 3.4.2
- 3.4.1
- 3.3.20
- 3.3.19
- 3.3.18
- 3.3.17
- 3.3.16
- 3.3.15
- 3.3.14
- 3.3.13
- 3.3.12
- 3.3.11
- 3.3.10
- 3.3.9
- 3.3.8
- 3.3.7
- 3.3.6
- 3.3.5
- 3.3.4
- 3.3.3
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.1
- 3.2.0
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.x-dev
- 3.0.2
- 3.0.1
- 3.0.0
- 2.2.10
- 2.2.9
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2
- 2.1.20
- 2.1.19
- 2.1.18
- 2.1.17
- 2.1.16
- 2.1.15
- 2.1.14
- 2.1.13
- 2.1.12
- 2.1.11
- 2.1.10
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1.x-dev
- 2.1.1
- 2.1.0
- 2.0.x-dev
- 2.0.11
- 2.0.10
- 2.0.9
- 2.0.8
- 2.0.7
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.7.x-dev
- 1.6.x-dev
- 1.6.9
- 1.6.8
- 1.6.7
- 1.6.6
- 1.6.5
- 1.6.4
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.0
- 1.4.6
- 1.4.5
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4
- 1.3.0
- 1.2.0
- 1.1.0
- 1.0.1
- 1.0.0
- dev-ClaasBrueggemann-feature/v4-support
- dev-issue105-bis
- dev-issue-105
- dev-fix/empty-array
- dev-tx-events
- dev-issue40
- dev-ikwattro-patch-12
- dev-ikwattro-patch-11
- dev-ikwattro-patch-10
- dev-ikwattro-patch-9
- dev-ikwattro-patch-8
- dev-ikwattro-patch-7
- dev-ikwattro-patch-6
- dev-ikwattro-patch-5
- dev-ikwattro-patch-4
- dev-ikwattro-patch-3
- dev-ikwattro-patch-2
- dev-ikwattro-patch-1
- dev-log
- dev-preview
- dev-livetx-fix
- dev-schema
- dev-issue-stefan
- dev-ha-no-yaml
- dev-connected-nodes
- dev-data-table
- dev-rows
- dev-custom-headers
- dev-travis
- dev-changePassword
- dev-3.0-dev
- dev-prepared-transaction
- dev-relProp
- dev-auth2
- dev-restformat
- dev-rest
- dev-client-changes
- dev-path
- dev-txmanager
- dev-1.6-dev
- dev-1.5-dev
- dev-1.4-dev
This package is auto-updated.
Last update: 2025-10-20 15:24:00 UTC
README
THIS REPOSITORY IS ARCHIVED. This is no longer supported or used by Navigate/APG
GraphAware Neo4j PHP Client
An Enterprise Grade Client for Neo4j
Introduction
Neo4j-PHP-Client is the most advanced and flexible Neo4j Client for PHP.
What is Neo4j?
Neo4j is a transactional, open-source graph database. A graph database manages data in a connected data structure, capable of representing any kind of data in a very accessible way. Information is stored in nodes and relationships connecting them, both of which can have arbitrary properties. To learn more visit What is a Graph Database?
Key features
- Supports multiple connections
- Support for Bolt binary protocol
- Built-in and automatic support for Neo4j Enterprise HA Master-Slave Mode with auto slaves fallback
Neo4j Version Support
| Version | Tested |
|---|---|
| <= 2.2.6 | No |
| >= 2.2.6 | Yes |
| 2.2 | Yes |
| 2.3 | Yes |
| 3.0 + | Yes |
Neo4j Feature Support
| Feature | Supported? |
|---|---|
| Auth | Yes |
| Remote Cypher | Yes |
| Transactions | Yes |
| High Availability | Yes |
| Embedded JVM support | No |
| Binary Protocol | Yes |
Requirements
- PHP >= 5.6
- ext-bcmath
- ext-mbstring
- A Neo4j database (minimum version 2.2.6)
Getting Help
You can:
- Ask a question on StackOverflow
- For bugs, please feel free to create a new issue on GitHub
Implementations
Installation and basic usage
Installation
Add the library to your composer dependencies :
composer require "autoprotect-group/neo4j-php-client:^5.0"
Require the composer autoloader, configure your connection by providing a connection alias and your connection settings :
<?php require_once 'vendor/autoload.php'; use GraphAware\Neo4j\Client\ClientBuilder; $client = ClientBuilder::create() ->addConnection('default', 'http://neo4j:password@localhost:7474') // Example for HTTP connection configuration (port is optional) ->addConnection('bolt', 'bolt://neo4j:password@localhost:7687') // Example for BOLT connection configuration (port is optional) ->build();
You're now ready to connect to your database.
NB: The build method will process configuration settings and return you a Client instance.
Basic Usage
Sending a Cypher Query
$client->run('CREATE (n:Person)');
Sending a Cypher Query with parameters
$client->run('CREATE (n:Person) SET n += {infos}', ['infos' => ['name' => 'Ales', 'age' => 34]]);
Reading a Result
$result = $client->run('MATCH (n:Person) RETURN n'); // a result always contains a collection (array) of Record objects // get all records $records = $result->getRecords(); // get the first or (if expected only one) the only record $record = $result->getRecord();
A Record object contains the values of one record from your Cypher query :
$query = 'MATCH (n:Person)-[:FOLLOWS]->(friend) RETURN n.name, collect(friend) as friends'; $result = $client->run($query); foreach ($result->getRecords() as $record) { echo sprintf('Person name is : %s and has %d number of friends', $record->value('name'), count($record->value('friends'))); }
Cypher statements and Stacks
Ideally, you would stack your statements and issue them all at once in order to improve performance.
You can create Cypher statement stacks that act as a Bag and run this stack with the client, example :
$stack = $client->stack(); $stack->push('CREATE (n:Person {uuid: {uuid} })', ['uuid' => '123-fff']); $stack->push('MATCH (n:Person {uuid: {uuid1} }), (n2:Person {uuid: {uuid2} }) MERGE (n)-[:FOLLOWS]->(n2)', ['uuid1' => '123-fff', 'uuid2' => '456-ddd']); $results = $client->runStack($stack);
Tagging your Cypher statements
Sometimes, you may want to retrieve a specific result from a Stack, an easy way to do this is to tag your Cypher statements.
The tag is passed via the 3rd argument of the run or push methods :
$stack = $client->stack(); $stack->push('CREATE (n:Person {uuid: {uuid} })', ['uuid' => '123-fff'], 'user_create'); $stack->push('MATCH (n:Person {uuid: {uuid1} }), (n2:Person {uuid: {uuid2} }) MERGE (n)-[r:FOLLOWS]->(n2) RETURN id(r) as relId', ['uuid1' => '123-fff', 'uuid2' => '456-ddd'], 'user_follows'); $results = $client->runStack($stack); $followResult = $results->get('user_follows'); $followRelationshipId = $followResult->getRecord()->value('relId');
Working with Result sets
Basics
The run method returns you a single Result object. Other methods where you can expect multiple results returns a ResultCollection object which is Traversable.
The Result object contains the records and the summary of the statement, the following methods are available in the API :
$result->firstRecord(); // Returns the first record of the Statement Result $result->records(); // Returns all records $result->summarize(); // Returns the ResultSummary
Summary
The ResultSummary contains the Statement, the Statistics and the QueryPlan if available :
$summary = $result->summarize(); $query = $summary->statement()->text(); $stats = $summary->updateStatistics(); $nodesUpdated = $stats->nodesUpdated(); $propertiesSet = $stats->propertiesSet(); // Does the statement affected the graph ? $affected = $stats->containsUpdates();
Record Values
Each record contains one row of values returned by the Cypher query :
$query = 'MATCH (n:Person) n, n.name as name, n.age as age';
$result = $client->run($query);
foreach ($result->records() as $record) {
print_r($record->get('n')); // nodes returned are automatically hydrated to Node objects
echo $record->value('name') . PHP_EOL;
echo $record->value('age') . PHP_EOL;
}
The client takes care of the hydration of Graph objects to PHP Objects, so it is for Node, Relationship and Path :
Node
labels(): returns an array of labels (string)identity(): returns the internal ID of the nodevalues(): returns the properties of the node (array)value($key): returns the value for the given property keyhasValue($key): returns whether or not the nodes has a property with the given keykeys(): returns you an array representing the keys of the node propertieshasLabel($label): returns whether or not the node has the given label (boolean)
Relationship
type(): returns the relationship typeidentity(): returns the internal ID of the relationshipvalues(): returns the properties of the relationship (array)value($key): returns the value for the given property keyhasValue($key): returns whether or not the relationship has a property with the given keykeys(): returns you an array representing the keys of the relationship propertiesstartNodeIdentity: returns the start node idendNodeIdentity: returns the end node id
Path
start(): returns the start node of the pathend(): returns the end node of the pathlength(): returns the length of the pathnodes(): returns all the nodes in the pathrelationships: returns all the relationships in the path
Handling Results (from v3 to v4)
There are 3 main concepts around this topic :
- a Result
- a Record
- a RecordValue
Let's take a look at a query we do in the browser containing multiple possibilities of types :
MATCH (n:Address)
RETURN n.address as addr, n, collect(id(n)) as ids
LIMIT 5
Result
A Result is a collection of Record objects, every row you see in the browser is a Record and contains Record Values.
- In blue the Result
- In orange a Record
- In green a RecordValue
Record
In contrary to the previous versions of the client, there is no more automatic merging of all the records into one big record, so you will need to iterate all the records from the Result :
$query = 'MATCH (n:Address) RETURN n.address as addr, n, collect(id(n)) as ids LIMIT 5'; $result = $client->run($query); foreach ($result->records() as $record) { // here we do what we want with one record (one row in the browser result) print_r($record); }
Record Value
Every record contains a collection of Record Values, which are identified by a key, the key is the identifier you give in the RETURN clause of the Cypher query. In our example, a Record will contain the following keys :
- addr
- n
- ids
In order to access the value, you make use of the get() method on the Record object :
$address = $record->get('addr');
The type of the value is depending of what you return from Neo4j, in our case the following values will be returned :
- a
stringfor theaddrvalue - a
Nodefor thenvalue - an
arrayofintegersfor theidsvalue
Meaning that :
$record->get('addr'); // returns a string $record->get('n'); // returns a Node object $record->get('ids'); // returns an array
Node, Relationship and Path objects have then further methods, so if you know that the node returned by the identifier n has a countries property on it, you can access it like this :
$addressNode = $record->get('n'); $countries = $addressNode->value('countries');
The Record object contains three methods for IDE friendlyness, namely :
$record->nodeValue('n'); $record->relationshipValue('r'); $record->pathValue('p');
This does not offer something extra, just that the docblocks hint the IDE for autocompletion.
Extra: ResultCollection
When you use Stack objects for sending multiple statements at once, it will return you a ResultCollection object containing a collection of Results. So you need to iterate the results before accessing the records.
Working with Transactions
The Client provides a Transaction object that ease how you would work with transactions.
Creating a Transaction
$tx = $client->transaction();
At this stage, nothing has been sent to the server yet (the statement BEGIN has not been sent), this permits to stack queries or Stack objects before commiting them.
Stack a query
$tx->push('CREATE (n:Person) RETURN id(n)');
Again, until now nothing has been sent.
Run a query in a Transaction
Sometimes you want to get an immediate result of a statement inside the transaction, this can be done with the run method :
$result = $tx->run('CREATE (n:Person) SET n.name = {name} RETURN id(n)', ['name' => 'Michal']); echo $result->getRecord()->value("id(n)");
If the transaction has not yet begun, the BEGIN of the transaction will be done automatically.
You can also push or run Stacks
$stack = $client->stack(); $stack->push('CREATE (n:Person {uuid: {uuid} })', ['uuid' => '123-fff']); $stack->push('MATCH (n:Person {uuid: {uuid1} }), (n2:Person {uuid: {uuid2} }) MERGE (n)-[:FOLLOWS]->(n2)', ['uuid1' => '123-fff', 'uuid2' => '456-ddd']); $tx->pushStack($stack); // or $results = $tx->runStack($stack);
Commit and Rollback
if you have queued statements in your transaction (those added with the push methods) and you have finish your job, you can commit the transaction and receive
the results :
$stack = $client->stack(); $stack->push('CREATE (n:Person {uuid: {uuid} })', ['uuid' => '123-fff']); $stack->push('MATCH (n:Person {uuid: {uuid1} }), (n2:Person {uuid: {uuid2} }) MERGE (n)-[:FOLLOWS]->(n2)', ['uuid1' => '123-fff', 'uuid2' => '456-ddd']); $tx->pushStack($stack); $tx->pushQuery('MATCH (n) RETURN count(n)'); $results = $tx->commit();
After a commit, you will not be able to push or run statements in this transaction.
Working with multiple connections
Generally speaking, you would better use HAProxy for running Neo4j in a cluster environment. However sometimes it makes sense to have full control to which instance you send your statements.
Let's assume a environment with 3 neo4j nodes :
$client = ClientBuilder::create() ->addConnection('node1', 'bolt://10.0.0.1') ->addConnection('node2', 'bolt://10.0.0.2') ->addConnection('node3', 'bolt://10.0.0.3') ->setMaster('node1') ->build();
By default, the $client->run() command will send your Cypher statements to the first registered connection in the list.
You can specify to which connection to send the statement by specifying its alias as 4th argument to the run parameter :
$result = $client->run('CREATE (n) RETURN n', null, null, 'node1');
The client is also aware of the manually configured master connection, so sending your writes can be easier with :
$client->runWrite('CREATE (n:User {login: 123})');
Helper Methods
$client->getLabels();
Returns an array of Label objects.
Event Dispatching
3 types of events are dispatched during the run methods :
PreRunEvent: before the statement or stack is run.PostRunEvent: after the statement or stack is run.FailureEvent: in case of failure, you can disable the client to throw an exception with this event.
Registering listeners
Example :
$client = ClientBuilder::create() ->addConnection('default', 'bolt://localhost') ->registerEventListener(Neo4jClientEvents::NEO4J_PRE_RUN, array($listener, 'onPreRun') ->build();
The event dispatcher is available via the client with the $client->getEventDispatcher methods.
Settings
Timeout (deprecated)
You can configure a global timeout for the connections :
$client = ClientBuilder::create() ->addConnection('default', 'http://localhost:7474') ->setDefaultTimeout(3) ->build();
The timeout by default is 5 seconds.
This feature is deprecated and will be removed in version 5. See Http client settings below.
TLS
You can enable TLS encryption for the Bolt Protocol by passing a Configuration instance when building the connection, here
is a simple example :
$config = \GraphAware\Bolt\Configuration::newInstance()
->withCredentials('bolttest', 'L7n7SfTSj')
->withTLSMode(\GraphAware\Bolt\Configuration::TLSMODE_REQUIRED);
$client = ClientBuilder::create()
->addConnection('default', 'bolt://hodccomjfkgdenl.dbs.gdb.com:24786', config)
->build();
HTTP client settings
We use HTTPlug to give you full control of the HTTP client. Version 4 of the Neo4jClient comes with Guzzle6 by default to preserve backward compatibility. Version 5 will give you the option to choose whatever client you want. Read more about HTTPlug in their documentation.
To configure your client you may add it to Configuration. Below is an example using php-http/curl-client.
use Http\Client\Curl\Client; $options = [ CURLOPT_CONNECTTIMEOUT => 3, // The number of seconds to wait while trying to connect. CURLOPT_SSL_VERIFYPEER => false // Stop cURL from verifying the peer's certificate ]; $httpClient = new Client(null, null, $options); $config = \GraphAware\Neo4j\Client\HttpDriver\Configuration::create($httpClient); $client = ClientBuilder::create() ->addConnection('default', 'http://neo4j:password@localhost:7474', $config) ->build();
License
The library is released under the MIT License, refer to the LICENSE file bundled with this package.
