17370845950

php读取rtf文件内存溢出何解_php读取rtf内存优化法【方案】
PHP读取RTF内存溢出的根本原因是全量加载富文本导致内存耗尽,解决需分块流式解析、控制字识别与括号深度跟踪,或转交unrtf/textutil预处理,辅以上传校验与降级策略。

PHP读取RTF文件时出现内存溢出,根本原因在于RTF是富文本格式,包含大量控制字、嵌套结构和冗余内容,而PHP默认用file_get_contents()file()一次性加载整个文件到内存,对大文件(如几十MB的RTF)极易触发Fatal error: Allowed memory size exhausted。解决核心是:避免全量加载、按需解析、流式处理。

分块读取 + 控制字识别(轻量级解析)

不依赖第三方库,用fopen()配合fgets()fread()

行/分块读取,边读边识别关键RTF结构(如{\rtf1\par\b}),跳过无用控制字和嵌套注释。适用于只需提取纯文本或简单格式标记的场景。

  • 设置合理缓冲区大小(如4096字节),避免单次读取过大
  • 维护一个“括号深度计数器”,遇{加1、遇}减1,深度为0时认为一个逻辑块结束
  • 忽略以\*开头的私有控制字(如\*\bkmkstart)和注释{\*\footnote ...}

使用rtf2html类库 + 内存限制适配

推荐轻量级开源库如rtf-html-php,它本身采用流式解析思想。但需手动改造其加载逻辑,防止内部仍调用file_get_contents()

  • 将原始loadRtf()方法改为接受资源句柄(fopen($file, 'r'))而非文件路径
  • 在解析循环中用stream_get_line($fp, 1024, '}')按“块”读取,结合状态机处理嵌套
  • 设置ini_set('memory_limit', '64M')仅作兜底,不依赖它扛大文件

转交系统工具预处理(最稳方案)

对可靠性要求高的生产环境,不建议PHP硬扛RTF解析。可调用系统级工具先转成中间格式,再由PHP安全读取:

  • Linux下用unrtf --text $input.rtf > $output.txt(需安装unrtf包)
  • macOS可用textutil -convert txt $input.rtf -output $output.txt
  • PHP中用proc_open()执行命令,通过管道实时读取stdout,避免生成临时大文件
  • 超时控制+返回码校验(如unrtf退出码非0则报错)必不可少

前置校验 + 用户友好降级

防患于未然比事后抢救更有效:

  • 上传时用$_FILES['file']['size']拦截超过5MB的RTF文件,前端提示“建议转为TXT/PDF后上传”
  • 对已上传文件,用fstat()快速获取大小,大于阈值(如3MB)直接返回“文件过大,请精简后重试”
  • 提供“仅提取前2000字符”的快速预览模式,满足多数查看需求