VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/9.3-code-organization-and-design-patterns

⇱ Code Organization and Design Patterns | stefanak-michal/php-bolt-driver | DeepWiki


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

Code Organization and Design Patterns

This page documents the architectural patterns, code organization, and design principles used throughout the php-bolt-driver library. It serves as a guide for contributors to understand the codebase structure and maintain consistency when adding new features or protocol versions.

For information about setting up a development environment, see Setup and Dependencies. For instructions on running tests, see Running Tests.

Namespace Organization

The library follows a hierarchical namespace structure that groups related functionality:

NamespacePurposeExamples
Bolt\Top-level factory and entry pointBolt factory class
Bolt\protocol\Protocol version implementationsV1, V2, V3, V4, V4_1, V4_2, V4_3, V4_4, V5, V5_1, V5_2, V5_3, V5_4, V6
Bolt\protocol\v{version}\Protocol-specific traits and componentsv1\InitMessage, v3\HelloMessage, v4\PullMessage
Bolt\connection\Connection implementationsIConnection, Socket, StreamSocket, PStreamSocket
Bolt\packstream\v{version}\PackStream serialization versionsv1\Packer, v1\Unpacker
Bolt\structures\Bolt data structuresNode, Relationship, Path, DateTime, Point2D, Vector
Bolt\enum\Enumeration typesSignature, ServerState, Message
Bolt\helpers\Utility classesFileCache, CacheProvider
Bolt\error\Exception typesBoltException, ConnectException, PackException, UnpackException

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

Trait Composition Pattern

The most distinctive design pattern in this library is the trait composition pattern for protocol version implementations. This pattern enables code reuse across protocol versions while maintaining version-specific behavior without inheritance hierarchies or excessive code duplication.

Pattern Structure


Sources: src/protocol/V1.php1-23 src/protocol/V3.php1-28 src/protocol/V4.php1-29 src/protocol/V4_1.php1-30 src/protocol/V4_3.php1-32

Concrete Example: V1 Protocol

The V1 protocol implementation demonstrates the basic pattern:


This class has no methods of its own—all functionality comes from trait composition. Each trait provides:

  • AvailableStructures: Defines $unpackStructuresLt and $packStructuresLt lookup tables for structure serialization
  • ServerStateTransition: Defines $serverStateTransition array mapping state transitions
  • Message Traits: Each implements a message type (e.g., init(), run(), pullAll())

Sources: src/protocol/V1.php12-23

Trait Reuse Across Versions

The V3 protocol demonstrates cross-version trait reuse:


Key observations:

  • Structures remain stable: V1's AvailableStructures is used until V4_3 introduces new structures
  • State management evolves: Each major version (V1, V3, V4, V5.1) has its own ServerStateTransition
  • Messages accumulate: New versions add traits for new messages while reusing unchanged messages

Sources: src/protocol/V3.php14-27

Trait Composition Matrix

This table shows which trait namespaces contribute to each protocol version:

Protocolv1 Traitsv3 Traitsv4 Traitsv4_1 Traitsv4_3 Traitsv4_4 Traitsv5 Traitsv5_1 Traits
V1
V2
V3
V4
V4_1
V4_2
V4_3
V4_4
V5+

Sources: src/protocol/V1.php14-22 src/protocol/V3.php15-27 src/protocol/V4.php15-28 src/protocol/V4_1.php15-29 src/protocol/V4_3.php15-31 src/protocol/V4_4.php15-31

Benefits of This Pattern

  1. Zero Code Duplication: Common functionality (like reset() or basic structures) is defined once and reused
  2. Version-Specific Behavior: Each protocol version can override specific traits without affecting others
  3. Incremental Evolution: New versions compose traits from previous versions, adding only what's new
  4. Explicit Dependencies: The use statements document which features each version supports
  5. Easy Testing: Each trait can be tested independently, and protocol classes inherit all test coverage

Factory Pattern

The Bolt class implements the factory pattern to create protocol instances. This centralizes protocol instantiation logic and handles version negotiation.

Factory Architecture


Sources: src/Bolt.php116-143 src/Bolt.php145-157 src/Bolt.php159-185

Factory Methods

The Bolt class provides these key methods:

MethodPurposeLine Reference
__construct(IConnection $connection)Initialize factory with connectionsrc/Bolt.php28-38
setProtocolVersions(int|float|string ...$v)Set up to 4 protocol versions to negotiatesrc/Bolt.php187-193
setPackStreamVersion(int $version)Configure PackStream version (default: 1)src/Bolt.php195-199
build(): AProtocolExecute handshake and return protocol instancesrc/Bolt.php120-143
handshake(): stringPerform Bolt handshake negotiationsrc/Bolt.php205-220

Dynamic Protocol Instantiation

The factory uses dynamic class instantiation based on the negotiated version string:


This pattern allows:

  • Automatic protocol selection: No if/else chains for version checking
  • Easy version addition: Add new protocol by creating class V{version}
  • Graceful degradation: If server selects unsupported version, clear error message

Sources: src/Bolt.php145-157

Persistent Connection Optimization

For PStreamSocket connections, the factory implements a caching optimization:


This optimization:

  1. Checks if connection type is PStreamSocket
  2. Retrieves cached protocol version (15-minute TTL)
  3. Instantiates protocol without handshake
  4. Validates connection state with reset()
  5. Falls back to handshake if validation fails

Sources: src/Bolt.php159-185 src/Bolt.php138-140

Connection Strategy Pattern

The library implements the strategy pattern for connection management through the IConnection interface. Three implementations provide different capabilities:


Sources: src/Bolt.php28 src/protocol/AProtocol.php47

Connection Selection

Applications choose a strategy based on requirements:

StrategyUse CaseTrade-offs
SocketLow-level control, binary operationsRequires ext-sockets extension
StreamSocketSSL/TLS connections, cloud deploymentsPHP streams API, slightly higher overhead
PStreamSocketLong-running applications, high query volumeConnection reuse reduces handshake overhead; requires cache

Example instantiation:


Sources: src/Bolt.php28

Abstract Protocol Base Class

The AProtocol abstract class provides core functionality shared by all protocol versions:


Key Responsibilities

  1. Message Pipeline Management: $pipelinedMessages array tracks queued messages awaiting responses src/protocol/AProtocol.php24
  2. Serialization Coordination: Manages IPacker and IUnpacker instances src/protocol/AProtocol.php26-27
  3. Server State Tracking: Maintains ServerState and $openStreams counter src/protocol/AProtocol.php29 src/protocol/AProtocol.php39
  4. Protocol Version Detection: getVersion() method extracts version from class name src/protocol/AProtocol.php108-115
  5. Response Handling: getResponse() and getResponses() consume pipelined responses src/protocol/AProtocol.php120-168

Sources: src/protocol/AProtocol.php21-192

Write/Read Abstraction

The base class provides protected methods for connection I/O:


These methods handle:

  • Chunked message assembly: Messages are chunked with 2-byte length headers
  • End-of-message detection: Double zero bytes (0x00 0x00) signal message end
  • Automatic unpacking: Binary data is automatically deserialized via IUnpacker
  • Analytics tracking: $writeCalls counter for usage metrics

Sources: src/protocol/AProtocol.php67-103

Iterator Pattern for Response Handling

The library uses PHP generators (iterator pattern) for memory-efficient response streaming:


Generator Implementation


This pattern enables:

  • Streaming results: Large result sets don't require full buffering in memory
  • Lazy evaluation: Responses are consumed only when needed
  • Memory efficiency: Critical for 50K+ record queries (tested in performance suite)

Sources: src/protocol/AProtocol.php120-168

PSR-16 Cache Interface

The library implements PSR-16 Simple Cache Interface for persistent connection metadata storage:


FileCache Implementation Details

The FileCache class stores data in sys_get_temp_dir()/php-bolt-filecache/:

FeatureImplementation
Storage formatSerialized PHP data
TTL supportSeparate .ttl/ subdirectory stores expiration timestamps
File lockinglock(key) and unlock(key) methods for atomic operations
Key validationRegex: /^[\w\.]+$/i (alphanumeric, underscore, dot only)
Automatic cleanuphas() method removes expired entries

Sources: src/helpers/FileCache.php1-219

Usage in Persistent Connections


Cached data:

  • Key: Connection identifier (IP:port combination)
  • Value: Negotiated protocol version string (e.g., "4.3")
  • TTL: 15 minutes (900 seconds)

Sources: src/Bolt.php138-140 src/Bolt.php162

Message Trait Structure

Each message type is implemented as a separate trait, following a consistent pattern:


Example: RunMessage Trait

Message traits typically implement both public and protected methods:


Pattern components:

  1. Public method accepts parameters and returns Response or $this (for pipelining)
  2. Packs message via $this->packer->pack(signature, ...params)
  3. Writes via $this->write()
  4. Adds to $this->pipelinedMessages[]
  5. Protected _run() generator handles response reading

Sources: src/protocol/AProtocol.php67-73 src/protocol/AProtocol.php138-149

Testing Infrastructure Patterns

The test suite employs several patterns to ensure comprehensive coverage:

Test Layer Hierarchy


Mock Connection Pattern

The ProtocolLayer base class provides mock connection infrastructure:


Features:

  • Write verification: Compares actual bytes to expected hex strings in self::$writeBuffer
  • Read simulation: Returns pre-packed responses from self::$readArray
  • Stateless testing: No actual database connection required

Sources: tests/protocol/ProtocolLayer.php41-96

Code Style and Contribution Guidelines

File Organization Conventions

  1. One class per file: Each protocol version, trait, or structure has its own file
  2. Namespace mirrors directory: Bolt\protocol\v3\RunMessagesrc/protocol/v3/RunMessage.php
  3. Traits in version namespaces: Protocol-specific traits in v{version}\ subdirectories
  4. Shared components in base namespace: Enums, errors, helpers in top-level Bolt\ subnamespaces

Class Naming Conventions

TypeConventionExample
Protocol version classesV{version} (underscores for dots)V4_3 for version 4.3
Message traits{MessageName}MessageHelloMessage, PullMessage
Structure classesPascalCase descriptive nameNode, UnboundRelationship, Point3D
EnumsPascalCaseSignature, ServerState, Message
ExceptionsSuffix with ExceptionBoltException, ConnectException

Adding a New Protocol Version

To add support for a new Bolt protocol version (e.g., V7):

  1. Create protocol class at src/protocol/V7.php:

    
    
  2. Create new trait directory src/protocol/v7/ for version-specific features

  3. Implement new traits following the message trait pattern

  4. Update AvailableStructures if new structure types are added

  5. Add ServerStateTransition if state machine changes

  6. Write tests in tests/protocol/V7Test.php

  7. Update documentation in relevant wiki pages

Sources: src/protocol/V1.php1-23 src/protocol/V3.php1-28 src/protocol/V4_3.php1-32

Testing Requirements

All contributions must include:

  • Unit tests for protocol message handling (using ProtocolLayer base)
  • Integration tests if new structures or connection features are added
  • All tests passing in CI/CD pipeline across PHP 8.2-8.5
  • No database dependency for unit tests (use mock connections)

Sources: tests/protocol/ProtocolLayer.php1-123

Summary

The php-bolt-driver codebase employs several well-established design patterns:

  1. Trait Composition: Enables incremental protocol evolution without code duplication
  2. Factory Pattern: Centralizes protocol instantiation with version negotiation
  3. Strategy Pattern: Provides pluggable connection implementations
  4. Iterator Pattern: Memory-efficient response streaming via generators
  5. PSR-16 Cache: Standard interface for persistent connection metadata

These patterns combine to create a maintainable, extensible architecture that supports multiple Bolt protocol versions (1.0 through 6.0) with minimal redundancy. Contributors should follow established patterns when adding new protocol versions or features.

Refresh this wiki

On this page