Skip to content

Bytes

A useful value object to work with bytes as a slice of unsigned 8-bit integers.


The bytes package provides a simple Castor\Bytes object to aid uint8 operations over a PHP byte string.

Installation

Add the Castor repository to your composer.json.

{
"repositories": [{
"type": "composer",
"url": "https://castor-labs.github.io/php-packages"
}]
}

And then install with composer.

Terminal window
composer require castor/bytes

Motivation

PHP doesn’t provide an easy way of manipulating bytes on a string using uint8, because it doesn’t expose strings as uint8 arrays. The Castor\Bytes class solves this problem by providing a way of manipulating bytes on a string using the uint8 representation. This allows for easy bit manipulation on a string.

Usage

The package is minimal and easy to use. Here are some of the things you can do with it.

Bit/Byte Manipulation

By far, the most convenient feature of the castor/bytes package is that it allows you to easily manipulate bytes, or the individual bits of those bytes without getting yourself tangled in messy code using the \pack, \unpack, \char and \ord functions.

Simply querying for an offset as you would do for an array will return the uint8 representation of that byte.

use Castor\Bytes;
$bytes = Bytes::fromHex('0f40f0');
$bytes[1]; // 64

You can also set any uint8 value at any offset as you would do with an array.

use Castor\Bytes;
$color = Bytes::fromHex('00ff00'); // A very bright green
$color[1] = 0;
$color->toHex(); // "000000", black color

Bit operations are crucial to implement certain protocols or standards. For example, we use this library in our UUID package to manipulate UUID bits. And manipulating bits is very easy using the array syntax in combination with the bitwise operators.

use Castor\Bytes;
$bytes = Bytes::fromHex('abf2d8');
$bytes[1] = $bytes[1] & 0x0F | 0x30; // Set 4 most significant bits to 0011
$bytes->toHex(); // "ab32d8"

In order to perform safe operations when accessing the offsets, always check for the bytes length using the Castor\Bytes::len() method.

use Castor\Bytes;
$color = Bytes::fromHex('ddff00');
$color[$color->len() - 1]; // 0

Creating and Casting Castor\Bytes

As you have seen, you can create the bytes class from a hexadecimal string, and cast it back to an hexadecimal string.

use Castor\Bytes;
Bytes::fromHex('0f40f0')->toHex()); // '0f40f0'

However, there is no much point in doing that. Sometimes you might want to create from hexadecimal and cast to a uint8 array, or viceversa.

use Castor\Bytes;
Bytes::fromUint8(15, 64, 240)->toHex(); // "0f40f0"
Bytes::fromHex('0f40f0')->toUint8Array()); // [15, 64, 240]

Of course, you can also create bytes from raw byte string, and cast to the raw byte string representation:

use Castor\Bytes;
$bytes = new Bytes('Hello');
$bytes->toUint8Array(); // [72, 101, 108, 108, 111]
$bytes = Bytes::fromUint8(72, 101, 108, 108, 111);
$bytes->toString(); // "Hello"

Reading and Writing

Castor\Bytes implements both the Castor\IO\Reader and Castor\IO\Writer interfaces, so you can use this in memory buffer to read and write bytes.

You can also create bytes by consuming $n amount of bytes from a Castor\IO\Reader using the consume static factory:

use Castor\Bytes;