Pack: примеры (PHP)

Функция pack в PHP: полный обзор с практическими примерами
Раздел: Преобразование типов/форматов
pack(string $format, mixed ...$values): string
Что такое функция pack

Функция pack в PHP используется для упаковки данных в бинарную строку согласно указанному формату. Она преобразует данные из PHP-типов в бинарное представление, которое часто требуется при работе с файлами, сетевыми протоколами, шифрованием или взаимодействии с внешними системами.

Синтаксис и параметры

Синтаксис функции: pack(string $format, mixed ...$values): string

Параметр $format - строка, определяющая формат упаковки. Состоит из кодов форматов:

  • a - строка с NUL-дополнением
  • A - строка с пробельным дополнением
  • h - шестнадцатеричная строка, младший полубайт first
  • H - шестнадцатеричная строка, старший полубайт first
  • c - знаковый char (1 байт)
  • C - беззнаковый char (1 байт)
  • s - знаковый short (16 бит, порядок байт зависит от машины)
  • S - беззнаковый short (16 бит)
  • n - беззнаковый short (16 бит, big endian)
  • v - беззнаковый short (16 бит, little endian)
  • i - знаковый integer (зависит от размера и порядка байт)
  • I - беззнаковый integer
  • l - знаковый long (32 бита)
  • L - беззнаковый long (32 бита)
  • N - беззнаковый long (32 бита, big endian)
  • V - беззнаковый long (32 бита, little endian)
  • f - float (зависит от платформы)
  • d - double (зависит от платформы)
  • x - NUL-байт
  • X - возврат на один байт
  • @ - заполнение NUL-байтами до абсолютной позиции

Параметр ...$values - значения для упаковки. Их количество и типы должны соответствовать спецификаторам в формате.

Базовые примеры использования
Упаковка чисел
echo bin2hex(pack('C', 65));
41
echo bin2hex(pack('n', 258));
0102
Работа со строками
echo bin2hex(pack('A5', 'AB'));
4142202020
echo bin2hex(pack('a5', 'AB'));
4142000000
Комбинированные форматы
$data = pack('Cna5', 65, 258, 'test');
echo bin2hex($data);
4101027465737400
Похожие функции в PHP

unpack() - обратная функция для распаковки бинарных данных. Используется вместе с pack для полного цикла преобразований.

bin2hex() и hex2bin() - преобразуют бинарные данные в шестнадцатеричное представление и обратно. Проще для чтения человеком, но менее эффективны по объему.

sprintf() с %-форматами - подходит для форматирования строк, но не для бинарных данных. Не поддерживает порядок байт.

hash() с алгоритмами типа md5, sha256 - для хеширования, а не упаковки данных.

Функцию pack выбирают когда нужен точный контроль над бинарным представлением, особенно при работе с сетевыми протоколами или файловыми форматами.

Альтернативы в других языках
Python: struct.pack
import struct
result = struct.pack('>I', 123456)
print(result.hex())
0001e240
JavaScript: DataView и ArrayBuffer
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, 123456, false);
console.log(Array.from(new Uint8Array(buffer)).map(b => b.toString(16).padStart(2, '0')).join(''));
0001e240
MySQL: HEX и UNHEX
SELECT HEX('A'), UNHEX('41');
41 | A

В отличие от PHP, в Python struct.pack требует явного указания порядка байт в формате. JavaScript работает с типизированными массивами, что более многословно. MySQL имеет ограниченные возможности для бинарной упаковки.

Типичные ошибки
Несоответствие количества аргументов
pack('CC', 65);
Warning: pack(): 2 arguments expected, 1 provided
Некорректные значения
echo bin2hex(pack('C', 300));
2c

Значение 300 обрезается до 44 (300 % 256).

Ошибки в формате
pack('Z', 'test');
Warning: pack(): Invalid format type Z
Проблемы с порядком байт
$little = pack('V', 123456);
$big = pack('N', 123456);
echo bin2hex($little), ' ', bin2hex($big);
40e20100 0001e240

Разный результат на little-endian и big-endian системах если не указать явно порядок байт.

Изменения в новых версиях PHP

В PHP 7.2.0 добавлена поддержка форматов e, E, g и G для упаковки чисел с плавающей точкой с учетом порядка байт.

В PHP 8.0.0 улучшены сообщения об ошибках при несоответствии количества аргументов.

В PHP 8.1.0 добавлены форматы q, Q, j и J для 64-битных целых чисел с различными вариантами порядка байт.

echo bin2hex(pack('Q', 123456789012345));
b9f4110700000000
Расширенные примеры
Создание бинарного заголовка
Пример php
$header = pack('CCnN', 0x45, 0x00, 1024, time());
echo bin2hex($header);
450004000000000065b0f17d
Работа с IPv4 адресами
Пример php
$ip = pack('C4', 192, 168, 1, 1);
echo inet_ntop($ip);
192.168.1.1
Упаковка чисел с плавающей точкой
Пример php
$float = pack('f', 3.14159);
echo bin2hex($float);
d00f4940
Использование заполнения
Пример php
$data = pack('a5@10a5', 'hello', 'world');
echo bin2hex($data);
68656c6c6f000000000000000000776f726c6400
Создание сложной структуры
Пример php
$struct = pack('NnA10f', 0x12345678, 0xABCD, 'test', 1.234);
echo bin2hex($struct);
12345678abcd746573740000000000f46f9d3f
Работа с шестнадцатеричными данными
Пример php
$hex = pack('H*', '48656c6c6f');
echo $hex;
Hello
Генерация UUID
Пример php
$uuid = pack('H*', sprintf('%04x%04x%04x%04x%04x%04x%04x%04x',
    mt_rand(0, 0xffff), mt_rand(0, 0xffff),
    mt_rand(0, 0xffff),
    mt_rand(0, 0x0fff) | 0x4000,
    mt_rand(0, 0x3fff) | 0x8000,
    mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
));
echo bin2hex($uuid);
f47ac10b58cc4372a5670a02b1e091ae

PHP pack function comments

En
Pack Pack data into binary string