Developer Guide

PHP pack() and unpack(): Binary Formats (Including Hex)

pack() and unpack() format PHP values into binary strings and back. Hex conversion is only one format code (H/h). Use them when you need structured binary layouts — integers, machine words, mixed records — not as a vague substitute for every string helper.

For plain hex ↔ text, prefer hex2bin/bin2hex. Online: Hex to String · String to Hex.

Mental model

<?php
// pack: values → binary string
// unpack: binary string → array of values

$bin = pack('C*', 0x48, 0x65, 0x6c, 0x6c, 0x6f);
echo $bin; // Hello
print_r(unpack('C*', $bin));

Hex with H / h

<?php
echo pack('H*', '48656c6c6f'); // Hello  (high nibble first — usual)
echo pack('h*', '84656c6c6f'); // nibble order swapped — rarely what you want

echo unpack('H*', 'Hello')[1]; // 48656c6c6f

H* matches hex2bin for typical even-length hex. Prefer hex2bin/bin2hex when hex is the only goal — clearer intent and better errors on PHP 8.

Useful non-hex formats

<?php
// unsigned chars
$packet = pack('C3', 1, 2, 255);

// 32-bit unsigned big-endian (network order)
$be = pack('N', 0x01020304);

// 32-bit unsigned little-endian
$le = pack('V', 0x01020304);

// null-terminated string + byte
$rec = pack('a*C', 'id', 7);

Endianness bugs are common. Match the protocol or file format exactly (n/N/v/V, or machine-dependent i/l only when intentional).

Parsing a tiny binary header

<?php
// magic(2) + version(1) + length(2 BE) + payload
$buf = pack('a2Cn', 'HX', 1, 5) . 'hello';

$parts = unpack('a2magic/Cversion/nlength', $buf);
$payload = substr($buf, 5, $parts['length']);
// magic=HX, version=1, length=5, payload=hello

Practical rules

Related: hex2bin() · string to hex · hex encoding overview.