fgets逐行读大文件时,换行符(\n或\r\n)被原样保留,空行需用trim($line) === ''判断;返回false表示失败或eof,返回空字符串极少见;严禁用于二进制文件。

fgets 逐行读大文件时换行符和空行怎么判断
Windows 和 Linux 的换行符不同,fgets() 会原样保留末尾的 "\r\n" 或 "\n",不处理、不剥离。直接用 empty($line) 判断空行会出错——因为 "\n" 不为空字符串。
-
fgets()返回false表示读取失败(如权限问题)或已到 EOF;返回""(空字符串)极少见,通常只在文件以\0开头等异常情况出现 - 空行实际是
"\n"、"\r\n"或仅含空白字符的行,应统一用trim($line) === ''判断 - 后续若需
json_decode(),必须先trim()去掉换行符,否则解析失败 - 二进制文件(如 ZIP、PDF)严禁用
fgets(),它按行截断会破坏结构,该用fread($fp, 8192)
fopen + fread 分块读取的边界陷阱
fread() 的行为比想象中更“松散”:它不保证每次返回指定长度,也不保证一次读完一行或一个完整数据单元。尤其在 NFS、S3FS 或慢速存储上,返回值可能是任意长度(包括 0 字节)。
-
fread($fp, 8192)返回false→ 立即中断,不能继续循环(常见于权限丢失或磁盘故障) - 返回
''(空字符串)→ 代表 EOF,不是临时卡顿,应退出循环 - 返回非空字符串但长度
- Windows 下打开二进制文件必须用
'rb'模式,否则\r\n会被自动转成\n,导致校验失败或解压报错
流式输出到浏览器时 Nginx/Apache 总是卡住
不是 PHP 没发数据,而是 Web 服务器把响应体缓存住了。Nginx 默认开启 fastcgi_buffering on,Apache 的 mod_deflate 也会拦截未压缩内容。
- PHP 层必须三连发:
ob_flush()+flush()+fflush($fp)(如果用了fopen('php://output')) - Nginx 配置里加
fastcgi_buffering off;和proxy_buffering off;(若走反向代理) - 必须提前发送
Content-Length头(可用filesize($path)),否则服务端启用 chunked 编码,部分旧客户端无法解析进度 -
header('X-Accel-Buffering: no')是 Nginx 专用指令,对 Apache 无效,别白加
stream_context_create() 配置 HTTP 流下载为什么总超时
超时不是设小了,而是设错了地方。http.timeout 在 PHP 7.3+ 已废弃,实际起效的是顶层的 timeout(socket 层),且它控制的是整个请求生命周期,不是单次 read。
- 正确写法:
'timeout' => 600(单位秒),放在 context 根层级,不是http子数组里 - HTTPS 下必须显式配置
ssl.cafile,否则自签名证书或私有 CA 会导致连接直接失败,错误提示常为SSL operation failed -
ignore_errors => false必须设,否则 404/500 响应体照常返回,掩盖真实错误 - 别用
file_get_contents()下载 GB 文件——它内部调用stream_get_contents(),默认会把整个 body 载入内存,OOM 是必然的
fclose(),Linux 进程句柄数很快耗尽,后续所有 fopen() 都返回 false,错误日志却只显示“无法打开文件”,而不是“Too many open files”。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











