In PHP, when processing binary data, the pack() and unpack() functions are two very practical tools. They can convert data into binary strings in a specific format, or parse binary strings into structured data. This is very critical for implementing the serialization and deserialization of custom data structures, or interacting with underlying protocols and file formats.
This article will explain in detail how to combine pack() and unpack() functions to implement the parsing and conversion of custom data structures.
pack(format, args...) : Package the parameter args into a binary string according to the format string.
unpack(format, data) : Unpack the binary string data into an associative array according to the format string.
The format string is composed of format code, which defines the data type, length and endianness. For example:
C : Unsigned characters (1 byte)
n : Unsigned 16-bit big-endian endian endian integer
V : Unsigned 32-bit little-endian endian endian integer
a : NUL filled string
A : Space filled string
For more format codes, please refer to the official PHP document .
Suppose we define a simple data structure as follows:
Field name | type | Length (bytes) | illustrate |
---|---|---|---|
type | uint8 | 1 | Data type identification |
length | uint16 | 2 | Subsequent data length |
payload | Byte Stream | length | Specific data content |
Our goals are:
Package the PHP data structure into binary data that meets the above format;
The binary data is parsed and the type, length and payload fields are extracted.
<?php
function packData(int $type, string $payload): string {
$length = strlen($payload);
// 'C' - 1Byte unsigned integers
// 'n' - 2Byte unsigned big endian integer
// 'a*' - String of any length,NULfilling(这里不需要filling)
return pack('Cn', $type, $length) . $payload;
}
// test
$type = 5;
$payload = "Hello, World!";
$binaryData = packData($type, $payload);
echo bin2hex($binaryData);
?>
Here pack('Cn', $type, $length) first packs the type and length separately, and then splice the original string $payload .
During parsing, first take out the type and length of the fixed length part, and then intercept the remaining payload according to the length .
<?php
function unpackData(string $binaryData): array {
// Before the first release3Bytes,type(1byte) + length(2byte大端)
$header = unpack('Ctype/nlength', substr($binaryData, 0, 3));
$type = $header['type'];
$length = $header['length'];
// Take out the remainingpayloaddata
$payload = substr($binaryData, 3, $length);
return [
'type' => $type,
'length' => $length,
'payload' => $payload,
];
}
// test
$data = $binaryData; // Assume from abovepackDataOutput
$result = unpackData($data);
var_dump($result);
?>
Integrate the above two functions to implement serialization and deserialization of custom structures:
<?php
function packData(int $type, string $payload): string {
$length = strlen($payload);
return pack('Cn', $type, $length) . $payload;
}
function unpackData(string $binaryData): array {
$header = unpack('Ctype/nlength', substr($binaryData, 0, 3));
$type = $header['type'];
$length = $header['length'];
$payload = substr($binaryData, 3, $length);
return [
'type' => $type,
'length' => $length,
'payload' => $payload,
];
}
// Example of usage
$type = 10;
$payload = "PHP pack/unpack Demo";
$packed = packData($type, $payload);
echo "二进制data(hex):" . bin2hex($packed) . "\n";
$unpacked = unpackData($packed);
echo "Analysis results:\n";
print_r($unpacked);
?>
Running results:
二进制data(hex):0a0017... (hexEncoded binary content)
Analysis results:
Array
(
[type] => 10
[length] => 23
[payload] => PHP pack/unpack Demo
)
pack() and unpack() are powerful tools for processing binary data, supporting multiple data types and endian conversion;
To parse custom data structures, you can first define a fixed header format, and then use string operations to process variable-length fields;
Combined with binary processing, PHP can also easily deal with network protocols, file format parsing and other scenarios.