pack
Packs values into a binary string according to a format of type codes and repeaters.
pack(string $format, mixed ...$values): string- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$format | string | A sequence of single-letter type codes, each optionally followed by a repeat count or * to consume all remaining values. |
$valuesoptional | mixed | The values to pack, in the order the format codes consume them. Variadic. |
Return value
stringA binary string containing the packed data.
Errors
Throws a ValueError for an unknown format code, a bad repeater, or when the format asks for more values than were supplied. Verified on PHP 8.5: pack('NN', 1) throws ValueError with the message "Type N: too few arguments", not ArgumentCountError. ArgumentCountError is only raised by the engine when pack() is called with no arguments at all.
Changelog
- PHP 8.0.0No longer returns false on failure; an invalid format code, a bad repeater or too few values now throw a ValueError instead.
- PHP 7.2.0float and double codes gained explicit big-endian and little-endian support.
- PHP 7.1.1The e, E, g and G codes were added for byte-order control on floats and doubles.
pack() turns PHP values into raw bytes. You describe the layout with one letter per field, optionally followed by a count: pack('Nn', $id, $port) writes a 32-bit big-endian integer followed by a 16-bit big-endian one.
Picking the right code
Fixed-width, explicit-endian codes are almost always what you want, because they behave the same on every machine:
n/v— unsigned 16-bit, big/little endianN/V— unsigned 32-bit, big/little endianJ/P— unsigned 64-bit, big/little endiana/A/Z— NUL-padded, space-padded and NUL-terminated strings
Avoid i, l, s, f and d in anything that crosses machines: their size or byte order follows the host CPU, so a file written on one box may not read back on another.
What trips people up
A repeater on a string code is a width, not a repeat: pack('a10', 'hi') produces one ten-byte field, whereas pack('C10', ...) consumes ten separate values. And the result is binary — echoing it to a terminal or into JSON will mangle it. Wrap it in bin2hex() or base64_encode() for display.
Example
When to use it
- Building a fixed-layout message header for a binary network protocol.
- Writing a small binary file format such as a custom index or cache header.
- Converting an integer to its 4-byte big-endian representation for a checksum or hash input.
Frequently asked questions
What is the difference between pack and unpack?
pack() converts PHP values into a binary string; unpack() reads a binary string back into an array of PHP values. They use the same format codes.
Which pack format should I use for a 32-bit integer?
Use N for big-endian (network byte order) or V for little-endian. Avoid l and L unless the data never leaves the current machine, because their byte order follows the CPU.
Why is my packed string shorter than expected?
On string codes the repeater is a field width, not a repeat count, so a10 is one 10-byte field rather than ten fields — check the result with strlen(). Note that pack() does not silently stop when it runs out of values: since PHP 8.0 a format that asks for more values than were supplied throws a ValueError ("Type N: too few arguments") instead of producing a shorter string.
More examples
Endianness made visible
The same number comes out as 0a0b0c0d, 0d0c0b0a and 000000000a0b0c0d, showing exactly how the byte order and width codes differ.
<?php
$value = 0x0A0B0C0D;
echo 'N (big endian): ', bin2hex(pack('N', $value)), "\n";
echo 'V (little endian): ', bin2hex(pack('V', $value)), "\n";
echo 'J (64-bit BE): ', bin2hex(pack('J', $value)), "\n";Fixed-width string fields
Each field occupies exactly 8 bytes; the padding differs (NUL, space, NUL-terminated) and unpack shows that A strips trailing whitespace while a keeps the NUL bytes.
<?php
$record = pack('a8A8Z8', 'nul', 'space', 'zero');
echo strlen($record), " bytes\n";
echo str_replace("\0", '.', $record), "\n";
print_r(unpack('a8one/A8two/Z8three', $record));
Discussion