必须用"r+b"模式打开文件才能安全修改二进制字节,因PHP默认文本模式会转换换行符;需fseek定位后fwrite覆写,注意检查返回值并fflush确保落盘。

用 fopen 以 "r+b" 模式打开才能改字节
PHP 默认的 fopen 是文本模式,会触发换行符转换(比如 \n → \r\n),直接破坏二进制数据。必须显式使用二进制读写模式:"r+b"(可读可写,不截断)或 "c+b"(若文件不存在则创建,存在则不截断)。用 "w+b" 会清空整个文件,极易误删数据。
-
"r+b"最常用:文件必须存在,指针从开头开始,可fseek定位后修改 - 避免
"a+b":它强制将写入位置设为文件末尾,无法随机改中间字节 - Windows 下尤其要注意——不加
b后缀可能引发不可见的字节偏移
fseek 定位 + fwrite 覆盖单字节或字节数组
二进制修改本质是“跳到某偏移、写入新值”。PHP 没有直接的 setByte($offset, $value) 函数,得靠组合操作:
- 用
fseek($fp, $offset, SEEK_SET)移动到目标位置($offset从 0 开始) - 用
fwrite($fp, $data)写入字符串——哪怕只改一个字节,也要传chr(0xFF)这样的单字符字符串 - 写入长度必须与原字节数一致;写入
"AB"会覆盖两个字节,不能只写"A"期望保留第二个字节 - 示例:把第 100 字节(索引 99)改为
0x42:$fp = fopen("file.bin", "r+b");
fseek($fp, 99, SEEK_SET);
fwrite($fp, "\x42");
fclose($fp);
注意文件长度和内存限制
PHP 不支持“在中间插入字节”,只能覆写已有位置。想扩展文件?得先用 ftruncate 拉长,再写入;想缩短?得截断+重写后续内容,或另存新文件。
- 改写超出当前长度的位置会自动扩展文件(但部分系统/配置可能报错,建议先
fstat检查大小) - 大文件别用
file_get_contents全部载入内存——几 MB 就可能触发memory_limit错误 - 频繁小修改建议复用同一个
fopen句柄,避免反复开闭带来的 I/O 开销和锁竞争
改完务必 fflush 和检查 fwrite 返回值
PHP 的文件写入有缓冲,默认不立即落盘。遇到断电或进程崩溃,看似改了实则没保存。
立即学习“PHP免费学习笔记(深入)”;
- 每次
fwrite后检查返回值是否等于预期字节数,false或小于预期说明写失败(磁盘满、权限不足、设备拔出等) - 关键修改后调用
fflush($fp)强制刷写缓冲区 - 如需确保物理写入完成(如固态硬盘/USB 设备),可追加
fsync($fp)(仅 Unix/Linux 有效,Windows 不支持) - 别依赖
fclose自动刷新——它可能失败且无提示
b,以及 fwrite 返回值是否认真校验。这两个点一漏,轻则数据错乱,重则整份文件报废。











