本文目录导读:

- 使用
fwrite()写入二进制数据 - 使用
pack()和unpack()打包数据 - 写入整数和浮点数
- 使用
fseek()定位写入 - 完整示例:创建二进制文件
- 字节顺序(Endianness)注意事项
- 最常用的格式化字符表
在 PHP 中进行二进制写入,主要有以下几种方法:
使用 fwrite() 写入二进制数据
这是最基本的方法,可以写入字符串形式的二进制数据:
<?php
// 打开文件(二进制模式)
$file = fopen('data.bin', 'wb'); // 'wb' = 写入 + 二进制模式
// 写入二进制数据(使用 pack 将数据转换为二进制)
$data = pack('C*', 0x48, 0x65, 0x6C, 0x6C, 0x6F); // 写入 "Hello"
fwrite($file, $data);
fclose($file);
?>
使用 pack() 和 unpack() 打包数据
pack() 函数可以将多个值打包成二进制字符串:
<?php
$file = fopen('data.bin', 'wb');
// 打包不同类型的数据
$data = pack('CCnN',
0x01, // 1字节无符号整数
0x02, // 1字节无符号整数
1000, // 2字节无符号整数(小端序)
500000 // 4字节无符号整数(小端序)
);
fwrite($file, $data);
// 常用格式化字符:
// C = 无符号字符(1字节)
// c = 有符号字符(1字节)
// S = 无符号短整数(2字节,小端)
// n = 无符号短整数(2字节,大端)
// L = 无符号长整数(4字节,小端)
// N = 无符号长整数(4字节,大端)
fclose($file);
?>
写入整数和浮点数
<?php
$file = fopen('numbers.bin', 'wb');
// 写入整数
fwrite($file, pack('L', 123456)); // 4字节整数
fwrite($file, pack('n', 789)); // 2字节大端序整数
// 写入浮点数
fwrite($file, pack('f', 3.14159)); // 4字节浮点数(IEEE 754)
fwrite($file, pack('d', 3.1415926)); // 8字节双精度浮点数
fclose($file);
?>
使用 fseek() 定位写入
<?php
$file = fopen('data.bin', 'wb');
// 写入头部数据
fwrite($file, pack('N', 0)); // 预写4字节
// 跳转到指定位置
fseek($file, 0); // 回到文件开头
fwrite($file, pack('N', 100)); // 写入数据长度
// 在文件末尾追加
fseek($file, 0, SEEK_END);
fwrite($file, "尾部数据");
fclose($file);
?>
完整示例:创建二进制文件
<?php
// 创建一个二进制文件,模拟简单文件格式
$file = fopen('myfile.bin', 'wb');
// 文件头
$header = array(
'magic' => 'MYBIN', // 文件标识
'version' => 1,
'count' => 3
);
// 写入文件头
fwrite($file, $header['magic']); // 5字节
fwrite($file, pack('C', $header['version'])); // 1字节
fwrite($file, pack('N', $header['count'])); // 4字节
// 写入记录
$records = array(
array(1, 10.5, 'A'),
array(2, 20.8, 'B'),
array(3, 30.2, 'C')
);
foreach ($records as $record) {
fwrite($file, pack('N', $record[0])); // ID
fwrite($file, pack('d', $record[1])); // 双精度浮点数
fwrite($file, pack('C', ord($record[2]))); // 单字符
}
fclose($file);
echo "二进制文件创建成功!\n";
// 读取验证
$file = fopen('myfile.bin', 'rb');
$magic = fread($file, 5);
$version = unpack('C', fread($file, 1))['1'];
$count = unpack('N', fread($file, 4))['1'];
echo "Magic: $magic\n";
echo "Version: $version\n";
echo "Count: $count\n";
for ($i = 0; $i < $count; $i++) {
$id = unpack('N', fread($file, 4))['1'];
$float = unpack('d', fread($file, 8))['1'];
$char = chr(unpack('C', fread($file, 1))['1']);
echo "Record $i: ID=$id, Float=$float, Char=$char\n";
}
fclose($file);
?>
字节顺序(Endianness)注意事项
<?php
$file = fopen('endian.bin', 'wb');
// 小端序(Intel/x86)
fwrite($file, pack('L', 0x11223344)); // 44 33 22 11
// 大端序(网络字节序)
fwrite($file, pack('N', 0x11223344)); // 11 22 33 44
// 检测系统字节序
$test = unpack('L', pack('l', 1));
echo ($test[1] == 1 ? '小端序' : '大端序');
fclose($file);
?>
最常用的格式化字符表
| 字符 | 描述 | 字节数 |
|---|---|---|
C |
无符号字符 | 1 |
c |
有符号字符 | 1 |
n |
无符号短整数(大端) | 2 |
v |
无符号短整数(小端) | 2 |
N |
无符号长整数(大端) | 4 |
V |
无符号长整数(小端) | 4 |
f |
单精度浮点数 | 4 |
d |
双精度浮点数 | 8 |
x |
空字节 | 1 |
选择合适的方法取决于你的具体需求,包括数据格式、平台兼容性等因素。