VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/3-core-architecture

⇱ Core Architecture | stefanak-michal/php-bolt-driver | DeepWiki


Loading...
Last indexed: 14 February 2026 (a283bd)
Menu

Core Architecture

The Bolt PHP driver implements a layered architecture consisting of four primary layers: the Factory Layer, Protocol Layer, Connection Layer, and Serialization Layer. Each layer has distinct responsibilities and interacts with adjacent layers through well-defined interfaces.

For detailed information about specific subsystems, see:

  • Protocol version negotiation and handshake: page 3.1
  • Protocol implementation details: page 3.2
  • Server state transitions: page 3.3
  • Caching and telemetry: page 3.4

Four-Layer Architecture

The architecture separates concerns into four distinct layers, from top to bottom:

Layered Architecture Diagram


Sources: src/Bolt.php1-262 src/protocol/AProtocol.php1-192 src/connection/IConnection.php src/packstream/IPacker.php src/packstream/IUnpacker.php

Layer Responsibilities

LayerPrimary ClassesResponsibility
FactoryBoltProtocol version negotiation, connection establishment, analytics tracking
ProtocolAProtocol, V1 through V6Bolt message construction, state transitions, pipelining
ConnectionIConnection, Socket, StreamSocket, PStreamSocketTCP/IP communication, SSL/TLS, persistent connections
SerializationIPacker, IUnpacker, v1\Packer, v1\UnpackerPackStream encoding/decoding, structure mapping

Sources: src/Bolt.php21 src/protocol/AProtocol.php21 src/connection/IConnection.php src/packstream/IPacker.php

Factory Layer: The Bolt Class

The Bolt class implements the Factory design pattern and serves as the entry point for the entire driver. It handles protocol version negotiation and instantiates the appropriate protocol version class.

Key Responsibilities

ResponsibilityImplementationLocation
Connection ManagementAccepts IConnection via constructorsrc/Bolt.php28
Version ConfigurationStores up to 4 protocol versionssrc/Bolt.php187-193
Protocol NegotiationPerforms handshake with serversrc/Bolt.php205-220
Protocol InstantiationCreates versioned AProtocol subclasssrc/Bolt.php145-157
Persistent Connection RecoveryReuses cached protocol versionsrc/Bolt.php159-185
PackStream ConfigurationSets serialization versionsrc/Bolt.php195-199
Analytics TrackingSubmits anonymous usage datasrc/Bolt.php40-114

Factory Methods and Properties

MemberTypeDescriptionDefault Value
__construct(IConnection $connection)MethodInitializes factory with connection-
setProtocolVersions(int|float|string ...$v)MethodSets up to 4 protocol versions[6, '5.8.8', '4.4.4']
setPackStreamVersion(int $version)MethodSets PackStream version1
build()MethodExecutes handshake and returns AProtocol-
$debugStatic propertyEnables binary communication outputfalse

Sources: src/Bolt.php21-262 README.md85-93

Factory Workflow Diagram


Sources: src/Bolt.php120-143 src/Bolt.php145-157 src/Bolt.php159-185 src/Bolt.php205-220

Protocol Version Negotiation

The handshake() method src/Bolt.php205-220 implements the Bolt handshake protocol:

  1. Magic Bytes: Sends 0x6060B017 to identify as Bolt protocol client
  2. Version List: Sends up to 4 protocol versions (16 bytes total)
  3. Server Response: Reads 4 bytes containing negotiated version
  4. Version Parsing: Calls unpackProtocolVersion() to decode response

Protocol Version Formats

Input FormatExamplePacked FormatClass Name
Integer40x00000004V4
String'5.4'0x04050000V5_4
Float4.30x03040000V4_3

The packProtocolVersions() method src/Bolt.php243-261 handles conversion:

  • Integers are packed as 32-bit big-endian
  • Strings/floats are split on . and packed as 4 bytes (minor, minor, major, 0)

Default Versions: [6, '5.8.8', '4.4.4'] set in constructor src/Bolt.php37

Sources: src/Bolt.php205-220 src/Bolt.php225-238 src/Bolt.php243-261

Protocol Layer: AProtocol and Version Implementations

The AProtocol abstract class src/protocol/AProtocol.php21 provides the foundation for all protocol versions. Each version (V1 through V6) extends the base class or a previous version, creating an inheritance chain that incrementally adds features.

AProtocol Core Properties and Methods

AProtocol Class Structure Diagram


Sources: src/protocol/AProtocol.php21-61 src/protocol/V1.php src/protocol/V3.php src/protocol/V4_4.php src/protocol/V5_1.php src/protocol/V5_4.php

Protocol Properties

PropertyTypeVisibilityPurposeLocation
$serverStateServerStatePublicCurrent connection statesrc/protocol/AProtocol.php29
$pipelinedMessagesMessage[]ProtectedQueue of sent messages awaiting responsesrc/protocol/AProtocol.php24
$packerIPackerProtectedPackStream encoder instancesrc/protocol/AProtocol.php26
$unpackerIUnpackerProtectedPackStream decoder instancesrc/protocol/AProtocol.php27
$connectionIConnectionProtectedTCP connection instancesrc/protocol/AProtocol.php47
$openStreamsintProtectedCount of unclosed result streamssrc/protocol/AProtocol.php39
$writeCallsintPrivateQuery execution counter for analyticssrc/protocol/AProtocol.php31

Sources: src/protocol/AProtocol.php24-48

Message Pipeline Architecture

The protocol layer implements message pipelining README.md76 allowing multiple Bolt messages to be sent before consuming responses. This reduces network round-trip latency.

Pipeline Flow Diagram


Sources: src/protocol/AProtocol.php67-73 src/protocol/AProtocol.php79-103 src/protocol/AProtocol.php120-168

Pipeline State Management

Writing Messages:

  1. Protocol method called (e.g., run(), pull())
  2. Message serialized via $this->packer->pack() src/protocol/AProtocol.php54
  3. Generator iterated and chunks written via write() src/protocol/AProtocol.php67-73
  4. Message enum added to $pipelinedMessages array
  5. Method returns $this for chaining

Reading Responses:

State Tracking:

Sources: src/protocol/AProtocol.php24-39 src/protocol/AProtocol.php67-103 src/protocol/AProtocol.php120-168

Trait Composition and Inheritance

Protocol versions use an inheritance chain where each version extends the previous, creating cumulative feature sets. Version-specific messages are implemented using PHP traits. See page 3.2 for trait composition details.

Sources: src/protocol/ README.md76-78

Connection Layer

The Connection Layer provides TCP/IP communication abstractions. All connection classes implement the IConnection interface, which defines methods for socket operations.

Connection Class Hierarchy Diagram


Sources: src/connection/IConnection.php src/connection/AConnection.php src/connection/Socket.php src/connection/StreamSocket.php src/connection/PStreamSocket.php

Connection Implementations

ClassExtension RequiredSSL SupportPersistentUse Case
Socketext-socketsNoNoHigh-performance, no encryption
StreamSocketNoneYes (ext-openssl)NoSSL/TLS connections, Neo4j Aura
PStreamSocketNoneYes (ext-openssl)YesPersistent connections with cache

Sources: src/connection/Socket.php src/connection/StreamSocket.php src/connection/PStreamSocket.php README.md212-233

Serialization Layer: PackStream

The Serialization Layer implements the PackStream binary format for encoding and decoding data. The primary interfaces are IPacker and IUnpacker.

Serialization Component Diagram


Sources: src/packstream/IPacker.php src/packstream/IUnpacker.php src/packstream/v1/Packer.php src/packstream/v1/Unpacker.php

PackStream Version 1

The v1\Packer and v1\Unpacker classes src/packstream/v1/ implement PackStream v1 format:

Packer responsibilities:

  • Encode PHP types to binary PackStream format
  • Handle structures via IStructure::__pack() method
  • Support generator-based serialization for memory efficiency
  • Chunk output into 65535-byte segments

Unpacker responsibilities:

  • Decode binary PackStream to PHP types
  • Reconstruct structures from signature bytes
  • Handle variable-length data types
  • Extract message signatures

Type Mappings: See page 7.1 for complete type mapping tables.

Sources: src/packstream/v1/Packer.php src/packstream/v1/Unpacker.php README.md148-160

Supporting Subsystems

PSR-16 Cache System

CacheProvider and FileCache Diagram


Sources: src/helpers/CacheProvider.php src/helpers/FileCache.php1-219

CacheProvider - Static accessor:

  • CacheProvider::get(): Returns singleton cache instance
  • CacheProvider::set(CacheInterface $cache): Inject custom implementation
  • Default: FileCache instance

FileCache - PSR-16 implementation src/helpers/FileCache.php16:

Cache Usage:

  1. Persistent connections: Store protocol version src/Bolt.php139
  2. Analytics data: Aggregate query/session counts src/protocol/AProtocol.php181-186

Sources: src/helpers/FileCache.php1-219 src/Bolt.php138-140 README.md283-286

Anonymous Analytics

The driver tracks anonymous usage statistics to inform development priorities. This system is opt-out via BOLT_ANALYTICS_OPTOUT environment variable.

Analytics Flow:

  1. Collection: AProtocol increments $writeCalls on each message sent src/protocol/AProtocol.php69
  2. Aggregation: On __destruct(), updates daily counts in cache src/protocol/AProtocol.php181-186
  3. Submission: Bolt::track() sends data older than today src/Bolt.php40-114
  4. Endpoint: Mixpanel API at api-eu.mixpanel.com/import src/Bolt.php80

Data Collected:

  • Query count per day
  • Session count per day
  • Anonymous distinct_id hash src/Bolt.php47

Opt-Out: Set BOLT_ANALYTICS_OPTOUT=1 environment variable README.md290

Sources: src/Bolt.php30-114 src/protocol/AProtocol.php170-191 README.md289-292

Complete Interaction Flow

This sequence diagram shows how all four layers interact during connection establishment and query execution:

Cross-Layer Interaction Diagram


Sources: src/Bolt.php120-143 src/protocol/AProtocol.php45-61 src/protocol/AProtocol.php67-73 src/protocol/AProtocol.php79-103 src/protocol/AProtocol.php120-168 src/protocol/AProtocol.php170-191

Initialization and Lifecycle

Standard Connection Lifecycle

  1. Instantiation: Create Bolt with IConnection implementation
  2. Configuration: Call setProtocolVersions() with desired versions (optional, defaults to [6, '5.8.8', '4.4.4'])
  3. Build: Call build() which:
    • Connects to database server
    • Performs handshake and version negotiation
    • Instantiates appropriate V{version} protocol class
    • Sets initial serverState (NEGOTIATION for V5+, CONNECTED otherwise)
  4. Authentication: Call hello() or init(), then logon() (V5+) or include auth in hello()/init()
  5. Query Execution: Pipeline messages via run(), pull(), etc.
  6. Response Consumption: Call getResponse() or getResponses()
  7. Cleanup: Call goodbye() or let connection close automatically

Sources: README.md172-202 src/Bolt.php120-157

Persistent Connection Lifecycle

For PStreamSocket connections:

  1. First Connection: Normal lifecycle, but protocol version cached src/Bolt.php138-140
  2. Subsequent Connections:

Sources: src/Bolt.php159-185 README.md229-233

Design Principles

The architecture follows several key principles:

  1. Separation of Concerns: Connection, protocol, and serialization are distinct layers
  2. Open/Closed Principle: New protocol versions extend AProtocol without modifying existing code
  3. Dependency Injection: IConnection and cache implementations are injected, not hard-coded
  4. Message Pipelining: Multiple messages can be queued before consuming responses for performance
  5. State Machine Enforcement: serverState tracking prevents invalid message sequences (detailed in Server State Management)
  6. Trait Composition: Protocol versions compose functionality from traits representing feature sets

Sources: src/Bolt.php1-262 src/protocol/AProtocol.php1-192