PHPackages                             rcalicdan/mysql-binary-protocol - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. rcalicdan/mysql-binary-protocol

ActiveLibrary[Database &amp; ORM](/categories/database)

rcalicdan/mysql-binary-protocol
===============================

Mysql Binary Protocol for my fiber async libary credits to Ivan Chepurnyi this a modernise implementation of his works

2.1.1(3mo ago)0506↓50%2MITPHPPHP ^8.3CI passing

Since Jul 9Pushed 2mo agoCompare

[ Source](https://github.com/rcalicdan/php-mysql-binary)[ Packagist](https://packagist.org/packages/rcalicdan/mysql-binary-protocol)[ RSS](/packages/rcalicdan-mysql-binary-protocol/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (4)Dependencies (3)Versions (5)Used By (2)

MySQL Binary Protocol
=====================

[](#mysql-binary-protocol)

A pure PHP implementation of the MySQL binary protocol for low-level packet serialization and deserialization. This library provides the building blocks for implementing MySQL clients, proxies, and protocol analyzers.

[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)

Overview
--------

[](#overview)

This library handles the **protocol layer** of MySQL communication - parsing and building binary packets according to the MySQL wire protocol specification. It does NOT handle network I/O, connection management, or provide a high-level database client API.

**What this library does:**

- Parse MySQL protocol packets (handshake, authentication, commands, responses)
- Build MySQL protocol packets for sending to servers
- Handle both text and binary result set protocols
- Support MySQL 4.1+ protocol features including prepared statements
- Provide authentication scrambling for `mysql_native_password` and `caching_sha2_password`

**What this library does NOT do:**

- Network I/O (sockets, streams)
- Connection pooling or management
- Transaction state tracking

Requirements
------------

[](#requirements)

- PHP 8.3 or higher
- No external dependencies

Installation
------------

[](#installation)

```
composer require rcalicdan/mysql-binary-protocol
```

Quick Start
-----------

[](#quick-start)

### 1. Parsing a Handshake Packet

[](#1-parsing-a-handshake-packet)

```
use Rcalicdan\MySQLBinaryProtocol\Frame\Handshake\HandshakeParser;
use Rcalicdan\MySQLBinaryProtocol\Buffer\Reader\BufferPayloadReaderFactory;

// Assume you received this data from a MySQL server socket
$rawPacketData = /* binary data from socket */;

// Create a payload reader from the raw data
$readerFactory = new BufferPayloadReaderFactory();
$payloadReader = $readerFactory->createFromString($rawPacketData);

// Parse the handshake
$parser = new HandshakeParser();
$handshake = $parser->parse($payloadReader, strlen($rawPacketData), 0);

echo "Server version: {$handshake->serverVersion}\n";
echo "Connection ID: {$handshake->connectionId}\n";
echo "Auth plugin: {$handshake->authPlugin}\n";
```

### 2. Building a Handshake Response

[](#2-building-a-handshake-response)

```
use Rcalicdan\MySQLBinaryProtocol\Frame\Handshake\HandshakeResponse41;
use Rcalicdan\MySQLBinaryProtocol\Auth\AuthScrambler;
use Rcalicdan\MySQLBinaryProtocol\Constants\CapabilityFlags;
use Rcalicdan\MySQLBinaryProtocol\Constants\CharsetIdentifiers;

// Scramble the password using the server's auth data
$password = 'mypassword';
$authResponse = AuthScrambler::scrambleNativePassword(
    $password,
    $handshake->authData
);

// Build capabilities (what features the client supports)
$capabilities = CapabilityFlags::CLIENT_PROTOCOL_41
    | CapabilityFlags::CLIENT_SECURE_CONNECTION
    | CapabilityFlags::CLIENT_PLUGIN_AUTH
    | CapabilityFlags::CLIENT_CONNECT_WITH_DB;

// Build the handshake response
$responseBuilder = new HandshakeResponse41();
$responsePayload = $responseBuilder->build(
    capabilities: $capabilities,
    charset: CharsetIdentifiers::UTF8MB4,
    username: 'myuser',
    authResponse: $authResponse,
    database: 'mydb',
    authPluginName: $handshake->authPlugin
);

// Wrap it in a packet and send to server
$packetWriter = new UncompressedPacketWriter();
$packet = $packetWriter->write($responsePayload, sequenceId: 1);

// Send $packet to the MySQL server via socket
```

### 3. Executing a Query

[](#3-executing-a-query)

```
use Rcalicdan\MySQLBinaryProtocol\Frame\Command\CommandBuilder;
use Rcalicdan\MySQLBinaryProtocol\Packet\UncompressedPacketWriter;

$commandBuilder = new CommandBuilder();
$packetWriter = new UncompressedPacketWriter();

// Build a COM_QUERY packet
$queryPayload = $commandBuilder->buildQuery('SELECT * FROM users WHERE id = 1');
$packet = $packetWriter->write($queryPayload, sequenceId: 0);

// Send $packet to server
```

### 4. Parsing Response Packets

[](#4-parsing-response-packets)

```
use Rcalicdan\MySQLBinaryProtocol\Frame\Response\OkPacketParser;
use Rcalicdan\MySQLBinaryProtocol\Frame\Response\ErrPacketParser;

// After receiving response from server
$responseData = /* binary data from socket */;
$reader = $readerFactory->createFromString($responseData);

// Check first byte to determine packet type
$firstByte = ord($responseData[0]);

if ($firstByte === 0x00) {
    // OK Packet
    $parser = new OkPacketParser();
    $ok = $parser->parse($reader, strlen($responseData), 1);
    echo "Affected rows: {$ok->affectedRows}\n";
    echo "Last insert ID: {$ok->lastInsertId}\n";
} elseif ($firstByte === 0xFF) {
    // Error Packet
    $parser = new ErrPacketParser();
    $error = $parser->parse($reader, strlen($responseData), 1);
    echo "Error {$error->errorCode}: {$error->errorMessage}\n";
}
```

### 5. Using Prepared Statements

[](#5-using-prepared-statements)

```
use Rcalicdan\MySQLBinaryProtocol\Frame\Response\StmtPrepareOkPacketParser;

// Prepare a statement
$preparePayload = $commandBuilder->buildStmtPrepare(
    'INSERT INTO users (name, email) VALUES (?, ?)'
);
$packet = $packetWriter->write($preparePayload, sequenceId: 0);
// Send to server...

// Parse the response to get statement ID
$response = /* receive from server */;
$parser = new StmtPrepareOkPacketParser();
$prepareOk = $parser->parse($reader, strlen($response), 1);
$statementId = $prepareOk->statementId;

// Execute the prepared statement
$executePayload = $commandBuilder->buildStmtExecute(
    statementId: $statementId,
    params: ['John Doe', 'john@example.com']
);
$packet = $packetWriter->write($executePayload, sequenceId: 0);
// Send to server...
```

### 6. Parsing Result Sets

[](#6-parsing-result-sets)

```
use Rcalicdan\MySQLBinaryProtocol\Frame\Result\ColumnDefinitionParser;
use Rcalicdan\MySQLBinaryProtocol\Frame\Result\TextRowParser;

// After executing a SELECT query, parse column definitions
$columnParser = new ColumnDefinitionParser();
$columns = [];

for ($i = 0; $i < $columnCount; $i++) {
    $columnData = /* receive column packet from server */;
    $reader = $readerFactory->createFromString($columnData);
    $columns[] = $columnParser->parse($reader, strlen($columnData), $i + 2);
}

// Then parse row data
$rowParser = new TextRowParser($columnCount);
while ($hasMoreRows) {
    $rowData = /* receive row packet from server */;
    $reader = $readerFactory->createFromString($rowData);
    $row = $rowParser->parse($reader, strlen($rowData), $sequenceId);

    foreach ($row->values as $i => $value) {
        echo "{$columns[$i]->name}: {$value}\n";
    }
}
```

Architecture
------------

[](#architecture)

The library is organized into several layers:

### Buffer Layer

[](#buffer-layer)

- **`ReadBuffer`**: Efficient streaming buffer for reading binary data
- **`BinaryIntegerReader`**: Reads integers of various sizes (1-8 bytes)
- **`BufferPayloadReader`**: Implements `PayloadReader` for reading MySQL data types
- **`BinaryWriter`**: Writes integers and floats in little-endian format
- **`BufferPayloadWriter`**: Implements `PayloadWriter` for writing MySQL data types

### Packet Layer

[](#packet-layer)

- **`UncompressedPacketReader`**: Reads MySQL packets with proper framing
- **`UncompressedPacketWriter`**: Writes MySQL packets with headers
- **`PayloadReader` Interface**: Abstraction for reading various MySQL data types
- **`PayloadWriter` Interface**: Abstraction for writing MySQL data types

> **Note:** Compressed packet support (`CompressedPacketReader` and `CompressedPacketWriter`) is not yet implemented and will be added in a future release.

### Frame Layer

[](#frame-layer)

Parsers and builders for specific MySQL protocol frames:

#### Handshake

[](#handshake)

- **`HandshakeParser`**: Parses server handshake (greeting) packets
- **`HandshakeV10`**: Represents a handshake frame
- **`HandshakeResponse41`**: Builds client authentication response

#### Commands

[](#commands)

- **`CommandBuilder`**: Builds command packets (COM\_QUERY, COM\_PING, etc.)
- **`ParameterBuilder`**: Builds bound parameters for prepared statements

#### Responses

[](#responses)

- **`OkPacketParser`**: Parses OK packets
- **`ErrPacketParser`**: Parses error packets
- **`StmtPrepareOkPacketParser`**: Parses prepared statement responses

#### Result Sets

[](#result-sets)

- **`ColumnDefinitionParser`**: Parses column metadata
- **`TextRowParser`**: Parses text protocol result rows
- **`BinaryRowParser`**: Parses binary protocol result rows (from prepared statements)

### Authentication

[](#authentication)

- **`AuthScrambler::scrambleNativePassword()`**: MySQL 4.1+ native password hashing
- **`AuthScrambler::scrambleCachingSha2Password()`**: MySQL 8.0+ SHA-256 password hashing

### Constants

[](#constants)

- **`CapabilityFlags`**: Client/server capability flags
- **`Command`**: Command type constants
- **`MysqlType`**: MySQL data type identifiers
- **`StatusFlags`**: Server status flags
- **`CharsetIdentifiers`**: Character set identifiers

Advanced Usage
--------------

[](#advanced-usage)

### Streaming Packet Reading

[](#streaming-packet-reading)

```
use Rcalicdan\MySQLBinaryProtocol\Packet\UncompressedPacketReader;
use Rcalicdan\MySQLBinaryProtocol\Buffer\ReadBuffer;
use Rcalicdan\MySQLBinaryProtocol\Buffer\Reader\BinaryIntegerReader;
use Rcalicdan\MySQLBinaryProtocol\Buffer\Reader\BufferPayloadReaderFactory;

$buffer = new ReadBuffer();
$integerReader = new BinaryIntegerReader();
$readerFactory = new BufferPayloadReaderFactory();
$packetReader = new UncompressedPacketReader(
    $integerReader,
    $buffer,
    $readerFactory
);

// Read data from socket in chunks
while ($chunk = socket_read($socket, 8192)) {
    $packetReader->append($chunk);

    // Process all complete packets
    while ($packetReader->readPayload(function($payload, $length, $sequence) {
        // Handle the packet
        $firstByte = $payload->readFixedInteger(1);
        // ... parse based on packet type
    })) {
        // Packet was successfully read
    }
}
```

### Custom Packet Processing

[](#custom-packet-processing)

```
use Rcalicdan\MySQLBinaryProtocol\Frame\FrameParser;
use Rcalicdan\MySQLBinaryProtocol\Packet\PayloadReader;

class MyCustomPacketParser implements FrameParser
{
    public function parse(PayloadReader $reader, int $length, int $sequenceNumber): Frame
    {
        // Read custom packet structure
        $field1 = $reader->readFixedInteger(4);
        $field2 = $reader->readNullTerminatedString();
        $field3 = $reader->readLengthEncodedStringOrNull();

        return new MyCustomFrame($field1, $field2, $field3);
    }
}
```

Testing
-------

[](#testing)

The library includes comprehensive test coverage using Pest:

```
composer test
```

Protocol Reference
------------------

[](#protocol-reference)

This library implements the MySQL Client/Server Protocol as documented in:

- [MySQL Internals Manual - Client/Server Protocol](https://dev.mysql.com/doc/internals/en/client-server-protocol.html)
- [MySQL Protocol Documentation](https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basics.html)

### Supported Features

[](#supported-features)

- Protocol Version 10 (MySQL 3.21+)
- CLIENT\_PROTOCOL\_41 capability
- CLIENT\_SECURE\_CONNECTION (auth data)
- CLIENT\_PLUGIN\_AUTH (pluggable authentication)
- Text protocol result sets
- Binary protocol result sets (prepared statements)
- COM\_QUERY, COM\_PING, COM\_QUIT, COM\_INIT\_DB
- COM\_STMT\_PREPARE, COM\_STMT\_EXECUTE, COM\_STMT\_CLOSE
- mysql\_native\_password authentication
- caching\_sha2\_password authentication
- Length-encoded integers and strings
- NULL bitmap handling
- Compressed packets (CLIENT\_COMPRESS)

### Not Yet Supported

[](#not-yet-supported)

- Authentication plugin switching
- Multi-statement queries
- Local INFILE
- Stored procedure OUT parameters

Use Cases
---------

[](#use-cases)

This library is designed for:

1. **Custom MySQL Clients**: Build custom MySQL clients
2. **Protocol Analyzers**: Analyze MySQL network traffic
3. **Proxy Servers**: Create MySQL proxies for load balancing, query logging, etc.
4. **Testing Tools**: Simulate MySQL client/server interactions
5. **Educational**: Learn how the MySQL protocol works

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

License
-------

[](#license)

This library is open-sourced software licensed under the [MIT license](LICENSE).

Related Projects
----------------

[](#related-projects)

- [krowinski/php-mysql-replication](https://github.com/krowinski/php-mysql-replication) - MySQL binlog replication in PHP
- [EcomDev/php-mysql-binary-protocol](https://github.com/EcomDev/php-mysql-binary-protocol) - This library is a fork of EcomDev/php-mysql-binary-protocol with additional features and improvements.

Support
-------

[](#support)

For bugs and feature requests, please use the [GitHub issue tracker](https://github.com/rcalicdan/mysql-binary-protocol/issues).

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance84

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~70 days

Total

4

Last Release

101d ago

Major Versions

1.0.0 → 2.0.02026-01-25

PHP version history (2 changes)1.0.0PHP ^8.2

2.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/adefeba01f7aab9f1eed1cc3f5015be296d86126a4adb50257d81ec0bf23c8ca?d=identicon)[RCalicdan](/maintainers/RCalicdan)

---

Top Contributors

[![rcalicdan](https://avatars.githubusercontent.com/u/163510169?v=4)](https://github.com/rcalicdan "rcalicdan (40 commits)")

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/rcalicdan-mysql-binary-protocol/health.svg)

```
[![Health](https://phpackages.com/badges/rcalicdan-mysql-binary-protocol/health.svg)](https://phpackages.com/packages/rcalicdan-mysql-binary-protocol)
```

###  Alternatives

[doctrine/orm

Object-Relational-Mapper for PHP

10.2k285.3M6.2k](/packages/doctrine-orm)[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k115.1M102](/packages/jdorn-sql-formatter)[illuminate/database

The Illuminate Database package.

2.8k52.4M9.4k](/packages/illuminate-database)[ramsey/uuid-doctrine

Use ramsey/uuid as a Doctrine field type.

90440.3M211](/packages/ramsey-uuid-doctrine)[reliese/laravel

Reliese Components for Laravel Framework code generation.

1.7k3.4M16](/packages/reliese-laravel)[wildside/userstamps

Laravel Userstamps provides an Eloquent trait which automatically maintains `created\_by` and `updated\_by` columns on your model, populated by the currently authenticated user in your application.

7511.7M13](/packages/wildside-userstamps)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
