Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Neo4J Php Client Laravel Package

laudis/neo4j-php-client

Typed Neo4j PHP client/driver with Bolt and Neo4j (auto-routed) support. Intuitive, extensible API with easy configuration, built with input from the official driver team and validated via Neo4j Testkit for reliability.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require laudis/neo4j-php-client
    

    Ensure your project meets the requirements: PHP ≥7.4, Neo4j ≥3.5, and extensions bcmath, json, and sockets.

  2. Basic Client Setup: Configure the client with a Bolt driver (recommended for production):

    use Laudis\Neo4j\ClientBuilder;
    
    $client = ClientBuilder::create()
        ->withDriver('bolt', 'bolt+s://neo4j:password@localhost:7687')
        ->withDefaultDriver('bolt')
        ->build();
    
  3. First Query: Execute a simple Cypher query to verify connectivity:

    $result = $client->run('RETURN 1 AS one');
    echo $result->first()->get('one'); // Output: 1
    
  4. First Use Case: Create a node and return its properties:

    $result = $client->writeTransaction(function ($tx) {
        return $tx->run('CREATE (n:User {name: $name}) RETURN n', ['name' => 'John Doe'])
            ->first()
            ->get('n');
    });
    

Implementation Patterns

1. Transaction Workflows

Use transaction functions for idempotent operations (recommended for most use cases):

// Idempotent write transaction
$userId = Uuid::v4();
$client->writeTransaction(function ($tx) use ($userId) {
    $tx->run('MERGE (u:User {id: $id}) SET u.name = $name', [
        'id' => $userId,
        'name' => 'Alice'
    ]);
});

2. Query Parameterization

Always use parameters to avoid injection and improve readability:

$email = 'user@example.com';
$client->run('MATCH (u:User {email: $email}) RETURN u', ['email' => $email]);

3. Result Handling

Iterate over results or fetch specific columns:

// Fetch all users
$users = $client->run('MATCH (u:User) RETURN u');
foreach ($users as $user) {
    $node = $user->get('u');
    echo $node->getProperty('name');
}

// Fetch a single value
$count = $client->run('MATCH (u:User) RETURN count(u) AS total')->first()->get('total');

4. Unmanaged Transactions

For advanced control (e.g., custom rollback logic):

$tx = $client->beginTransaction();
try {
    $tx->run('CREATE (n:Test)');
    $tx->commit();
} catch (\Exception $e) {
    $tx->rollback();
    throw $e;
}

5. Bulk Operations

Use runStatements for batch operations:

$statements = [
    Statement::create('CREATE (n:User {id: $id})', ['id' => 1]),
    Statement::create('CREATE (n:User {id: $id})', ['id' => 2]),
];
$client->runStatements($statements);

6. Integration with Laravel

Store the client in a service provider or singleton:

// app/Providers/Neo4jServiceProvider.php
public function register()
{
    $this->app->singleton('neo4j', function () {
        return ClientBuilder::create()
            ->withDriver('bolt', config('neo4j.uri'))
            ->withDefaultDriver('bolt')
            ->build();
    });
}

Use dependency injection in controllers:

public function __construct(private ClientInterface $neo4j) {}

public function index()
{
    $users = $this->neo4j->run('MATCH (u:User) RETURN u');
    return view('users.index', compact('users'));
}

Gotchas and Tips

Pitfalls

  1. Non-Idempotent Transactions: Avoid side effects outside the transaction (e.g., incrementing counters). Retries will fail if the operation isn’t repeatable.

    // ❌ Bad: Non-idempotent
    $client->writeTransaction(function ($tx) use (&$counter) {
        $counter++; // Side effect!
        $tx->run('CREATE (n:Test)');
    });
    
    // ✅ Good: Idempotent
    $client->writeTransaction(function ($tx) {
        $tx->run('CREATE (n:Test)');
    });
    
  2. Parameter Type Ambiguity: Empty arrays default to CypherList. Use ParameterHelper for clarity:

    $client->run('UNWIND $list RETURN count(*)', [
        'list' => ParameterHelper::asList([]) // Explicitly a list
    ]);
    
  3. Connection Timeouts: Bolt connections may hang. Use neo4j:// for auto-routing in clusters:

    $client = ClientBuilder::create()
        ->withDriver('neo4j', 'neo4j://cluster.example.com')
        ->build();
    
  4. Result Caching: The driver doesn’t cache results. For frequent queries, consider:

    • Application-level caching (e.g., Redis).
    • Neo4j’s CALL db.cache.clear() for full cache invalidation.
  5. Large Result Sets: Avoid RETURN * or unbounded LIMIT. Use pagination:

    $offset = 0;
    $limit = 100;
    $users = $client->run(
        'MATCH (u:User) RETURN u SKIP $offset LIMIT $limit',
        ['offset' => $offset, 'limit' => $limit]
    );
    

Debugging Tips

  1. Enable Logging: Configure the driver to log queries and responses:

    $client = ClientBuilder::create()
        ->withDriver('bolt', 'bolt://localhost', null, [
            'logging' => [
                'level' => Logger::DEBUG,
                'handler' => new StreamHandler('php://stdout'),
            ],
        ])
        ->build();
    
  2. Query Profiling: Use PROFILE to analyze slow queries:

    $result = $client->run('PROFILE MATCH (u:User) RETURN u');
    $summary = $result->getSummary();
    echo $summary->getPlanDescription();
    
  3. Error Handling: Catch Neo4jException for driver-specific errors:

    try {
        $client->run('INVALID CYPHER');
    } catch (Neo4jException $e) {
        echo $e->getCode(); // Neo4j status code (e.g., 400 for syntax errors)
    }
    

Extension Points

  1. Custom Formatters: Override result formatting (e.g., for JSON APIs):

    $client = ClientBuilder::create()
        ->withFormatter(new class implements ResultFormatterInterface {
            public function formatResult(ResultInterface $result): ResultInterface {
                // Custom logic (e.g., convert nodes to arrays)
                return $result;
            }
        })
        ->build();
    
  2. Middleware: Intercept queries for logging/auditing:

    $client = ClientBuilder::create()
        ->withMiddleware(function ($session) {
            return new class($session) implements SessionInterface {
                public function run(string $query, array $params = []): ResultInterface {
                    // Log query before execution
                    logger()->debug("Executing: $query", ['params' => $params]);
                    return $this->session->run($query, $params);
                }
            };
        })
        ->build();
    
  3. Custom Types: Extend CypherType for domain-specific types:

    class UserType extends CypherType {
        public function serialize($value): string {
            return json_encode($value);
        }
    
        public function deserialize(string $value): array {
            return json_decode($value, true);
        }
    }
    

Configuration Quirks

  1. Driver Aliases: Use aliases to switch between environments (e.g., dev, prod):

    $client = ClientBuilder::create()
        ->withDriver('bolt:dev', 'bolt://dev.example.com')
        ->withDriver('bolt:prod', 'bolt://prod.example.com')
        ->withDefaultDriver('bolt:dev')
        ->build();
    
  2. Bookmarks: Resume transactions from a specific point (useful for retries):

    $client = ClientBuilder::create()
        ->withDriver('bolt', 'bolt://localhost', null, [
            'bookmarks' => ['bookmark1', 'bookmark2'],
        ])
        ->build();
    
  3. Max Connection Pool Size: Limit connections to avoid overload:

    $client = ClientBuilder::create()
        ->withDriver('bolt', 'bolt://localhost', null, [
            'max_connection_pool_size' =>
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle