PHP has been lacking a fully-featured and actively maintained client for a few years. As the maintainer of the new library, I am happy to announce the
🎉 Neo4j PHP client!🎉
The client features:
- Multiple, easily configurable drivers
- An intuitive API
- Extensible architecture
- Designed, built, and tested under close supervision with the official Neo4j driver team
- Validated with testkit
- Fully typed with psalm
Set up your drivers/client
First off: Let’s install it with composer!
A standard Neo4j deployment understands two protocols: HTTP and Bolt. All drivers have the same API and are determined by the scheme of the URI. The HTTP and Bolt schemes each act on these protocols. The Neo4j scheme enables auto-routing of queries when connecting to a cluster of Neo4j nodes over Bolt.
This library goes one step further and consolidates all drivers in a single object: a client. A client simply contains a set of drivers with an alias and routes all queries to the default alias if you don’t provide one as a parameter.
There are three ways of running queries using the library:
- Transaction functions
- Auto committed queries
- Unmanaged transactions
Using transaction functions
When working with high availability solutions such as a cluster or Neo4j Aura, transaction functions are preferred. Transient errors are likely to occur in this environment. The driver will automatically retry the transaction function in these cases.
Transaction functions also allow specifying intent. Read or write transaction functions will automatically be routed to a correct node in the cluster when using the Neo4j scheme.
A word of caution: The driver automatically reruns the transaction functions. Therefore, they should always produce the same result on reruns (idempotency). This is because if a function produces a side effect and a transient error occurs afterwards, the side effect will occur twice.
Using auto committed queries
Auto committed queries are the most intuitive and straightforward way to send queries. There really isn’t much to talk about here. You send a query, and it gets executed within its own self-managed transaction. You, the user, are responsible for handling all errors.
Note: Transactions, clients, and sessions allow sending multiple statements at once. This feature is vital when using the HTTP protocol, as it drastically reduces network traffic.
Using unmanaged transactions
An unmanaged transaction allows for the most significant degree of control. It is also the most error-prone because you are still responsible for handling all errors. On top of that, you decide when to commit or roll back all your queries.
Client, driver, sessions, and transactions
In the above examples, we have always used a client. A client manages drivers. A driver creates a session, which is a lightweight container for chaining transactions, the atomic units of work. This structure is publicly available in the code:
Note: A driver does not support immediate access to run or transaction methods. These are only accessible through a session. The client does these method calls for you.
Result formats are fully configurable. Our next blog post will be all about that. The default result structure is that of rows and columns represented by CypherList and CypherMap, respectively. On top of that, objects in the Cypher protocol map to a PHP class counterpart. For example, a node in cypher maps to a \Laudis\Neo4j\Types\Node. You can find a complete list here.
Real world example
We’ve created a real-world example of the Neo4j movies project on GitHub. You can find it here.
The example is as minimalistic as possible. It works on top of the super simple framework slim. The routing and code are straightforward and it’s all in one file: index.php.
This blog post was a birds-eye view of the drivers and clients. If you find any issues, please feel free to open one at GitHub. We love to collaborate with people all over the world.
These are the core takeaways:
- You can either construct a client or driver to connect to Neo4j
- Results are in rows and columns format
- There are HTTP, Bolt, and Neo4j drivers available
- There are transaction functions, auto committed queries, and unmanaged transactions at your disposal
Now, please go forth and leverage the power of Neo4j in your PHP applications!
🙏 Special thanks to: 🙏
- Michal Štefaňák for its excellent Bolt library we use under the hood
- Davide from Larus for setting up GitHub actions
- Abed for developing the OGM with me