本文目录导读:

在 PHP 中,pack() 和 unpack() 函数用于在二进制数据和 PHP 变量之间进行转换,以下是详细的使用说明:
pack() 函数 - 将数据打包成二进制字符串
基本语法
pack(string $format, mixed ...$values): string
常用格式字符
| 格式 | 说明 | 示例 |
|---|---|---|
a |
NUL 填充字符串 | a10 - 10字节字符串 |
A |
空格填充字符串 | A10 - 10字节字符串 |
c |
有符号字符(1字节) | c |
C |
无符号字符(1字节) | C |
s |
有符号短整数(2字节) | s |
S |
无符号短整数(2字节) | S |
n |
无符号短整数(大端序) | n |
v |
无符号短整数(小端序) | v |
i |
有符号整数(机器相关) | i |
I |
无符号整数(机器相关) | I |
l |
有符号长整数(4字节) | l |
L |
无符号长整数(4字节) | L |
N |
无符号长整数(大端序,4字节) | N |
V |
无符号长整数(小端序,4字节) | V |
f |
单精度浮点数 | f |
d |
双精度浮点数 | d |
使用示例
// 1. 基本整数打包
$packed = pack('C', 65); // 输出: "A" (ASCII 65)
echo bin2hex($packed); // 输出: 41
// 2. 多个值打包
$packed = pack('C4', 65, 66, 67, 68); // 打包4个字符
echo $packed; // 输出: "ABCD"
// 3. 混合类型
$packed = pack('nvc', 0x1234, 0x5678, 0x9A);
// n: 无符号短整数(大端序)
// v: 无符号短整数(小端序)
// c: 有符号字符
echo bin2hex($packed); // 输出: "123478569a"
// 4. 字符串打包
$packed = pack('a10', 'Hello');
echo strlen($packed); // 输出: 10 (用null填充)
$packed = pack('A10', 'Hello');
echo strlen($packed); // 输出: 10 (用空格填充)
// 5. 使用数字重复格式
$packed = pack('C*', 1, 2, 3, 4); // 打包所有参数
unpack() 函数 - 解包二进制字符串
基本语法
unpack(string $format, string $string): array
使用示例
// 1. 解包单个值
$packed = pack('C', 65);
$result = unpack('Cchar', $packed);
echo $result['char']; // 输出: 65
// 2. 解包多个值
$packed = pack('C4', 65, 66, 67, 68);
$result = unpack('Ca/Cb/Cc/Cd', $packed);
print_r($result);
// 输出: ['a' => 65, 'b' => 66, 'c' => 67, 'd' => 68]
// 3. 解包整数
$packed = pack('n', 0x1234);
$result = unpack('nint', $packed);
echo $result['int']; // 输出: 4660 (0x1234)
// 4. 解包浮点数
$packed = pack('f', 3.14);
$result = unpack('ffloat', $packed);
echo $result['float']; // 输出: 3.14
// 5. 解包字符串
$packed = pack('a10', 'Hello');
$result = unpack('a10str', $packed);
echo rtrim($result['str']); // 输出: "Hello"
// 6. 重复解包
$packed = pack('C*', 1, 2, 3, 4, 5);
$result = unpack('C5nums', $packed);
print_r($result);
// 输出: ['nums1' => 1, 'nums2' => 2, 'nums3' => 3, 'nums4' => 4, 'nums5' => 5]
// 7. 使用 * 解包所有
$result = unpack('C*', $packed);
print_r($result);
// 输出: [1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5]
实用示例
创建二进制文件格式
// 创建一个简单的二进制文件
function writeBinaryFile($filename, $data) {
// 写入文件头:魔数(2字节) + 版本号(2字节) + 文件大小(4字节)
$header = pack('nnV', 0x4D41, 1, strlen($data));
// 写入数据
file_put_contents($filename, $header . $data);
}
// 读取二进制文件
function readBinaryFile($filename) {
$content = file_get_contents($filename);
// 解析文件头
$header = unpack('nmagic/nversion/Vsize', substr($content, 0, 8));
// 读取数据
$data = substr($content, 8, $header['size']);
return [
'magic' => $header['magic'],
'version' => $header['version'],
'size' => $header['size'],
'data' => $data
];
}
网络协议通信
// 创建网络消息
function createMessage($type, $content) {
$payload = pack('n', $type) . $content;
$length = strlen($payload);
return pack('N', $length) . $payload;
}
// 解析网络消息
function parseMessage($buffer) {
if (strlen($buffer) < 4) {
return null;
}
$length = unpack('Nlen', substr($buffer, 0, 4))['len'];
if (strlen($buffer) < 4 + $length) {
return null;
}
$type = unpack('ntype', substr($buffer, 4, 2))['type'];
$content = substr($buffer, 6, $length - 2);
return [
'type' => $type,
'content' => $content
];
}
注意事项
- 字节序问题:注意区分大端序(network byte order)和小端序(little-endian)
- 数据对齐:某些系统可能有字节对齐要求
- 类型范围:确保数据在类型允许的范围内
- 字符串处理:
a和A格式的区别在于填充字符
常用格式组合
// 常见二进制协议格式
$data = pack(
'nCVCV', // 格式:小端序短整数 + 字符 + 无符号整数 + 字符 + 无符号整数
0x1234, // 魔数
1, // 版本
100, // 数据1
2, // 状态
200 // 数据2
);
// 解包上述数据
$result = unpack('nmagic/Cversion/Vdata1/Cstatus/Vdata2', $data);
pack/unpack 在处理二进制数据时非常强大,适用于文件格式解析、网络协议实现、加密算法等领域。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播