在 PHP 中,pack() 函数用于将数据按照指定的格式打包成二进制字符串。这在处理网络传输、文件写入以及与 C 语言或其他低级语言交互时非常有用。本文将详细讲解 pack() 函数的用法,并结合实例说明如何将数据打包成二进制格式。
pack() 的基本语法如下:
string pack(string $format, mixed $values, mixed ...$values)
$format:指定数据的格式,由一个或多个格式代码组成。
$values:要打包的值,可以是多个参数。
返回值是一个按指定格式打包后的二进制字符串。
格式代码 | 描述 | 示例 |
---|---|---|
a | NUL 字符填充的字符串 | pack('a4', 'abc') |
A | 空格填充的字符串 | pack('A4', 'abc') |
c | 有符号字符 (1 字节) | pack('c', 65) |
C | 无符号字符 (1 字节) | pack('C', 65) |
s | 有符号短整数 (2 字节) | pack('s', 1234) |
S | 无符号短整数 (2 字节) | pack('S', 1234) |
i | 有符号整型 (机器字长) | pack('i', 123456) |
I | 无符号整型 (机器字长) | pack('I', 123456) |
l | 有符号长整数 (4 字节) | pack('l', 123456) |
L | 无符号长整数 (4 字节) | pack('L', 123456) |
f | 浮点数 (4 字节) | pack('f', 3.14) |
d | 双精度浮点数 (8 字节) | pack('d', 3.14) |
n | 无符号短整数 (16位大端字节序) | pack('n', 1234) |
N | 无符号长整数 (32位大端字节序) | pack('N', 1234) |
<?php
// 打包一个长度为4的字符串和一个32位无符号大端整数
$packed = pack('a4N', 'test', 123456789);
echo bin2hex($packed);
?>
这里 'a4' 表示打包一个长度为 4 的字符串,不足部分以 NUL 字符填充;'N' 表示打包一个 32 位无符号大端整数。bin2hex() 将二进制内容转换成16进制便于查看。
假设你需要构造一个简易的网络数据包,包含命令类型(1字节)和数据长度(4字节大端),然后是数据体:
<?php
$command = 1; // 命令类型,1字节
$data = "Hello, m66.net!"; // 数据体
$length = strlen($data); // 数据长度
// 打包命令类型和数据长度
$header = pack('CN', $command, $length);
// 拼接完整数据包
$packet = $header . $data;
// 输出包的十六进制表示
echo bin2hex($packet);
?>
上面代码中,'C' 打包命令类型(1字节无符号整数),'N' 打包数据长度(4字节大端整数)。数据体原样拼接。
<?php
$number = 65535;
$packed = pack('n', $number); // 按大端字节序打包为16位无符号整数
echo 'Packed data: ' . bin2hex($packed) . PHP_EOL;
$unpacked = unpack('nvalue', $packed); // 解包
echo 'Unpacked value: ' . $unpacked['value'] . PHP_EOL;
?>
pack() 是操作二进制数据的强大工具,尤其适用于网络编程和底层数据处理。通过熟练使用格式代码,可以准确地控制数据的字节排列和类型。