VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/9-development-guide

⇱ Development Guide | stefanak-michal/php-bolt-driver | DeepWiki


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

Development Guide

This guide provides instructions for contributors who want to set up a development environment, run tests, understand the codebase architecture, and contribute to the php-bolt-driver project.

The development workflow consists of three main phases:

  1. Setup and Dependencies (see page #9.1) - Installing PHP, extensions, and dependencies required for development
  2. Running Tests (see page #9.2) - Executing the comprehensive test suite locally and in CI/CD
  3. Code Organization and Design Patterns (see page #9.3) - Understanding the architectural patterns used throughout the codebase

For information about the library's architecture from a usage perspective, see page #3. For testing strategies from a quality assurance perspective, see page #8.


Quick Start for Contributors

The minimal setup to begin contributing:


Sources: README.md56-73 composer.json10-14 phpunit.xml1-27


Development Workflow Overview

The following diagram illustrates the typical development cycle from repository clone to pull request submission:

Diagram: Development Workflow and CI Integration


Sources: README.md56-73 composer.json53-59 phpunit.xml3-21


Development Environment Components

The php-bolt-driver development environment consists of several interconnected components:

Diagram: Development Environment Architecture


Sources: composer.json10-18 composer.json47-51 phpunit.xml3-21


System Requirements Summary

The following table summarizes the PHP versions and extensions required for development:

ComponentRequirementPurposeSource
PHP8.1 minimum, 8.2-8.5 testedCore runtimecomposer.json11
ext-mbstringRequiredBinary-safe string operations in PackStreamcomposer.json12
ext-curlRequiredAnalytics tracking to Mixpanelcomposer.json13
psr/simple-cacheRequiredCache interface for persistent connectionscomposer.json14
ext-socketsOptionalNeeded for Socket connection classcomposer.json50
ext-opensslOptionalNeeded for SSL/TLS with StreamSocketcomposer.json51
PHPUnit9.x (dev)Test frameworkcomposer.json17

Sources: composer.json10-18 composer.json47-51


Key Development Areas

Contributors typically work in one of the following areas:

Protocol Implementation

Adding or modifying Bolt protocol versions requires understanding the protocol evolution and message structure.

Primary Files:

  • src/protocol/AProtocol.php - Base protocol class with message pipeline
  • src/protocol/V1.php through src/protocol/V6.php - Version-specific implementations
  • src/protocol/v*/ - Trait directories for version-specific behavior

See page #9.3 for detailed design patterns.

PackStream Serialization

Extending data type support or fixing serialization bugs.

Primary Files:

  • src/packstream/v1/Packer.php - PHP to binary conversion
  • src/packstream/v1/Unpacker.php - Binary to PHP conversion
  • src/packstream/v1/structures/ - Structure definitions (Node, Relationship, Path, etc.)

See page #7 for PackStream details.

Connection Management

Improving connection implementations, timeout handling, or SSL configuration.

Primary Files:

  • src/connection/Socket.php - ext-sockets implementation
  • src/connection/StreamSocket.php - Stream + SSL implementation
  • src/connection/PStreamSocket.php - Persistent connections with cache

See page #4 for connection architecture.

Testing Infrastructure

Adding test coverage or improving test utilities.

Primary Files:

  • tests/protocol/ProtocolLayer.php - Mock connection utilities
  • tests/BoltTest.php - Integration test examples
  • tests/structures/ - Structure validation tests
  • phpunit.xml - Test suite configuration

See page #9.2 for running tests.

Sources: src/protocol/AProtocol.php1-193 src/packstream/v1/Packer.php1-100 src/connection/Socket.php1-50 tests/protocol/ProtocolLayer.php1-124


Mapping System Concepts to Code Entities

The following table maps high-level concepts discussed in this wiki to specific code entities for easier navigation:

System ConceptPrimary Class/FileKey Method/PropertyRelated Page
Factory PatternBoltbuild(), handshake()#3.1
Protocol BaseAProtocolwrite(), read(), getResponse()#3.2
Protocol V1/V2V1init(), run(), pullAll()#5.1
Protocol V3V3hello(), begin(), commit()#5.2
Protocol V4.xV4, V4_1, V4_2, V4_3, V4_4pull(), discard(), route()#5.3
Protocol V5/V6V5, V5_1, V5_2, V5_3, V5_4, V6logon(), logoff(), telemetry()#5.4
Server StateAProtocol$serverState, $serverStateTransition#3.3
Message PipelineAProtocol$pipelinedMessages, getResponses()#3.2
PackStream PackerPackerpack(), packStructuresLt#7.1
PackStream UnpackerUnpackerunpack(), unpackStructuresLt#7.1
Graph StructuresNode, Relationship, PathConstructor, properties#7.2
Temporal StructuresDate, DateTime, Duration, TimeConstructor, properties#7.3
Spatial StructuresPoint2D, Point3DConstructor, properties#7.3
Vector StructureVectorConstructor, $type, $data#7.4
Socket ConnectionSocketconnect(), write(), read()#4.1
Stream ConnectionStreamSocketsetSslContextOptions()#4.1, #4.3
Persistent ConnectionPStreamSocketconnect(), cache integration#4.2
PSR-16 CacheFileCacheget(), set(), lock()#3.4
Analytics TrackingBolttrack(), $analyticsOptout#3.4
Test InfrastructureProtocolLayermockConnection(), readCallback()#9.2
Integration TestsBoltTest, MemgraphTest, NornicDBTesttestConnection(), testQuery()#9.2

Sources: src/Bolt.php1-262 src/protocol/AProtocol.php1-193 src/packstream/v1/Packer.php1-100 src/connection/Socket.php1-50 tests/protocol/ProtocolLayer.php1-124


Next Steps

For detailed information on each development area, refer to the following pages:

  • Page #9.1: Setup and Dependencies - Detailed PHP extension requirements, Composer configuration, local database setup, and environment variable configuration
  • Page #9.2: Running Tests - PHPUnit configuration, test suite organization, CI/CD matrix strategy, and debugging test failures
  • Page #9.3: Code Organization and Design Patterns - Factory pattern implementation, protocol inheritance, trait composition, message pipelining, and contribution guidelines

Sources: README.md1-293 composer.json1-60 phpunit.xml1-27


Development Workflow Diagram


Sources: composer.json53-59 .github/workflows/no-db.yml1-35 .github/workflows/neo4j.5.yml1-51


Running Tests

PHPUnit Configuration

The test suite is organized into multiple test suites defined in phpunit.xml (not shown in provided files, but referenced):

Test SuitePurposeDatabase Required
NoDatabaseUnit tests, PackStream tests, protocol mockingNo
Neo4jIntegration tests against Neo4jYes
MemgraphIntegration tests against MemgraphYes
NornicDBIntegration tests against NornicDBYes

Running Tests Locally

Unit tests (no database required):


Integration tests (requires running database):


All tests with coverage:


The Composer script (composer.json53-59) automatically:

  1. Sets XDEBUG_MODE=debug for coverage
  2. Disables process timeout for long-running tests
  3. Runs PHPUnit with default configuration

Test Infrastructure Architecture


Sources: tests/protocol/ProtocolLayer.php1-124 tests/MemgraphTest.php1-154

Test Layer Base Class

The ProtocolLayer base class (tests/protocol/ProtocolLayer.php) provides utilities for protocol-level testing:

Key Methods:

Mock Verification: Tests can populate $writeBuffer with expected hexadecimal byte sequences to verify outgoing messages (tests/protocol/ProtocolLayer.php34). The mock connection automatically validates writes against this buffer.

Integration Test Pattern

The MemgraphTest demonstrates the integration test pattern (tests/MemgraphTest.php):

  1. Connection Setup (tests/MemgraphTest.php29-51):

    • Create connection (Socket or StreamSocket)
    • Instantiate Bolt factory
    • Protocol negotiation via build()
    • Authentication via hello()/logon()
  2. Query Execution (tests/MemgraphTest.php58-83):

    • Test parameter passing for all data types
    • Verify RUN success response
    • Consume PULL responses
    • Validate returned data matches parameters
  3. Transaction Testing (tests/MemgraphTest.php89-121):

    • Begin transaction with begin()
    • Execute queries within transaction
    • Rollback and verify data not persisted
  4. Structure Testing (tests/MemgraphTest.php130-144):

    • Use PHPUnit data providers
    • Test each PackStream structure type
    • Verify round-trip serialization

CI/CD Pipeline Matrix

The GitHub Actions workflow creates an extensive test matrix:


Total CI Jobs: 46 parallel jobs testing across:

  • Neo4j versions: 4.4, 5.4, 5.6, 5.8, 5.12, 5.22, 5.25, 5.26, 2025.09, 2025
  • PHP versions: 8.2, 8.3, 8.4, 8.5
  • Alternative databases: Memgraph, NornicDB

Understanding Test Failures

Common failure patterns:

  1. Connection Timeouts: Check GDB_USERNAME and GDB_PASSWORD environment variables
  2. Protocol Version Mismatch: Verify the database version supports the requested protocol version
  3. Analytics Directory: Tests create php-bolt-analytics in sys_get_temp_dir() (tests/protocol/ProtocolLayer.php103-107)
  4. SSL Issues: Ensure ext-openssl is installed if using StreamSocket with SSL

Sources: tests/protocol/ProtocolLayer.php1-124 tests/MemgraphTest.php1-154 .github/workflows/neo4j.5.yml1-51 .github/workflows/neo4j.4.4.yml1-51 .github/workflows/neo4j.2025.yml1-51 .github/workflows/memgraph.yml1-37 .github/workflows/nornicdb.yml1-40 .github/workflows/no-db.yml1-35


Code Organization and Design Patterns

Factory Pattern - Bolt Class

The Bolt class (src/Bolt.php) implements the factory pattern to instantiate the correct protocol version:


Key Methods:

MethodPurposeLine Reference
__construct(IConnection)Accepts dependency-injected connectionsrc/Bolt.php28
setProtocolVersions(...$v)Configure up to 4 protocol versions to offersrc/Bolt.php187-193
build()Execute handshake and return protocol instancesrc/Bolt.php120-143
handshake()Send 0x6060B017 magic + versions, read responsesrc/Bolt.php205-220
normalBuild()Create protocol for new connectionssrc/Bolt.php145-157
persistentBuild()Reuse protocol for persistent connectionssrc/Bolt.php159-185

Protocol Version String Handling: The factory dynamically constructs class names like \Bolt\protocol\V5_8 from version strings by replacing dots with underscores (src/Bolt.php149).

Protocol Version Inheritance

Protocol versions extend AProtocol and override specific message methods:


Inheritance Strategy: Each protocol version extends the previous version and adds new messages. For example:

  • V3 adds transactions (begin, commit, rollback) to V1
  • V4 replaces pullAll/discardAll with granular pull/discard
  • V5 separates authentication (logon/logoff from hello)
  • V6 adds telemetry for usage tracking

Server State Transitions: The AProtocol base class maintains state transitions via the $serverStateTransition array property (defined in subclasses, checked at src/protocol/AProtocol.php154-165).

Message Pipeline Architecture

The AProtocol class implements message pipelining:


Key Concepts:

PackStream Serialization Architecture

The PackStream layer separates packing and unpacking logic:


Packer/Unpacker Pattern:

  • IPacker interface defines pack(...$params): iterable returning a generator of binary chunks
  • IUnpacker interface defines unpack(string): array and getSignature(): int
  • Protocol classes instantiate versioned packer/unpacker (src/protocol/AProtocol.php50-60)
  • Structure lookup tables map classes to pack functions and signatures to classes

Why Generators?: The Packer::pack() method yields binary chunks rather than returning a complete string, enabling memory-efficient serialization of large datasets without buffering entire messages in memory.

Trait Composition Pattern

Note: While trait composition is mentioned in the TOC purpose, it doesn't appear prominently in the provided source files. The codebase primarily uses class inheritance and interface implementation rather than trait-based composition. If traits are used elsewhere in the codebase not shown in the provided files, contributors should look for trait keywords and use TraitName statements within classes.

FileCache Implementation

The FileCache class (src/helpers/FileCache.php) implements PSR-16 with file locking:


Thread-Safety: The lock() method (src/helpers/FileCache.php191-199) uses flock(LOCK_EX) for exclusive access, allowing analytics tracking from concurrent requests without data corruption.

Analytics Use Case:

  1. AProtocol::__destruct() locks the analytics key (src/protocol/AProtocol.php176-177)
  2. Reads current counts, increments queries and sessions
  3. Writes back and unlocks (src/protocol/AProtocol.php188-190)
  4. Bolt::track() later uploads accumulated data to Mixpanel (src/Bolt.php40-114)

Contribution Guidelines

Before Submitting a Pull Request:

  1. Run All Tests Locally:

    
    
  2. Verify Analytics Opt-Out:

    
    
  3. Check Code Style: While no formal style checker is defined in the provided files, follow PSR-12 coding standards and match existing code patterns.

  4. Update Tests: Add tests for new features in the appropriate test suite (protocol tests for protocol changes, structure tests for new data types).

  5. Documentation: Update relevant wiki pages if changing public APIs or adding features.

Common Contribution Areas:

AreaFiles to ModifyTest Requirements
New protocol versionsrc/protocol/V*.phpProtocol tests + integration tests
New data structuresrc/packstream/v1/structures/*.phpStructure tests
Connection improvementssrc/connection/*.phpConnection tests + timeout tests
Bug fixesVariousRegression test demonstrating fix

Code Review Expectations:

  • All 46 CI jobs must pass
  • No breaking changes to public APIs without major version bump
  • New features should support all tested Neo4j versions where applicable
  • Performance regressions are carefully evaluated

Sources: src/Bolt.php1-262 src/protocol/AProtocol.php1-193 src/helpers/FileCache.php1-220 composer.json1-60


Code Entity Reference Map

This table maps high-level concepts to specific code entities for easier navigation:

ConceptPrimary Classes/FilesKey Methods
FactoryBoltbuild(), handshake()
Protocol BaseAProtocolwrite(), read(), getResponse()
Protocol V1V1init(), run(), pullAll()
Protocol V3V3hello(), begin(), commit()
Protocol V4V4pull(), discard()
Protocol V5V5logon(), logoff()
Protocol V6V6telemetry()
SerializationPacker, Unpackerpack(), unpack()
ConnectionsSocket, StreamSocket, PStreamSocketconnect(), write(), read()
CachingFileCacheget(), set(), lock(), unlock()
Test InfrastructureProtocolLayermockConnection(), readCallback()
Integration TestsMemgraphTesttestConnection(), testQuery()

Sources: All files referenced throughout this document