PHP读取RTF慢的根本原因是原生不支持解析,依赖正则剥离控制字导致回溯严重;应改用php-rtf-lib等轻量解析器,配合文件指纹缓存、按需提取和预转换中间格式优化。

PHP 读取 RTF 文件慢,根本原因在于 RTF 是带格式标记的文本格式,不是纯文本,PHP 原生不支持解析,常见做法是用 file_get_contents() 读取原始内容后,再用正则或字符串处理剥离控制字(如 {\b ... \b0}、\par、字体/颜色定义等),而 RTF 控制字嵌套深、转义多、容错差,导致正则匹配回溯严重、反复扫描,小文件就卡顿,大文件直接超时。
用轻量级专用解析器替代正则硬解
避免自己写正则清理 RTF。推荐使用已验证的轻量库:
- php-rtf-lib(GitHub 开源):纯 PHP 实现,专注提取文本+基础样式,无依赖,支持嵌套和常见控制字,比正则快 5–10 倍;
- rtf-html-php(若需转 HTML):内部用状态机解析,不依赖 PCRE 回溯,内存占用低;
- 慎用
exec('unrtf')等系统命令:虽快但有安全风险、不可移植、难捕获错误。
预处理 + 缓存机制减重复解析
RTF 内容通常不变,但每次请求都重解析是最大性能浪费:
- 首次读取后,用
md5_file($rtf_path)生成文件指纹,作为缓存 key; - 将解析出的纯文本(或结构化数组)存入 APCu(本地共享内存)或 Redis,TTL 设为 1 小时以上;
- 后续请求先查缓存,命中则直接返回,跳过全部解析逻辑。
限制解析范围,按需提取
多数场景只需提取正文,无需保留所有格式:
立即学习“PHP免费学习笔记(深入)”;
- 在解析器中关闭样式/表格/图片等非必要节点处理(如 php-rtf-lib 可设
$parser->setIgnoreImages(true)); - 用流式读取(
fopen + fgets)跳过头部冗余段(如{\rtf1\ansi\ansicpg936\...}),定位到\pard或正文起始标记后再解析; - 对超大 RTF(>2MB),加
ini_set('memory_limit', '128M')并设最大解析长度(如只取前 10000 字符),防 OOM。
转存中间格式,彻底规避运行时解析
长期高频访问的 RTF 文件,应在上传或入库时一次性转换:
- 后台任务(Cron 或队列)调用解析器,把 RTF 转成 UTF-8 纯文本或 JSON 结构,存数据库或文件;
- Web 请求只读取已转换结果,响应时间降至毫秒级;
- 配合文件修改时间监听,RTF 更新后自动触发重新转换。
不复杂但容易忽略:慢不在 PHP 本身,而在解析方式。选对工具、加一层缓存、明确要什么,RTF 解析就能从秒级降到几十毫秒。











