yii框架不直接读取pdf,乱码源于php扩展解析时编码链路断裂;需先验证pdf是否为文字型,再用pdftotext等工具指定utf-8编码提取,并确保生成pdf时嵌入中文字体。

Yii 框架本身不直接读取或渲染 PDF,所谓“Yii 读取 PDF 返回乱码”,实际是 PHP 后端用扩展(如 tcpdf、mpdf、fpdi 或 pdftotext)解析 PDF 内容时,输出的文本出现中文显示为问号、方块或符号错乱。根本原因不在 Yii,而在字符编码处理链路断裂——从 PDF 字体解码、文本提取到 PHP 输出响应,任一环节未正确识别或声明 UTF-8,都会导致乱码。
确认PDF是否含可提取文字
很多“乱码”其实是假象:PDF 是扫描图片(非文字型),直接调用文本提取函数会返回空或乱符。先验证:
- 用 Adobe Acrobat 或浏览器打开该 PDF,尝试鼠标选中文字——能选中说明是文字型;不能选中,大概率是图像,需 OCR 处理。
- 在命令行运行:pdftotext -listfonts your.pdf,若无中文字体列表(如 SimSun、NotoSansCJK),说明字体未嵌入或为图片。
PHP 提取时强制指定编码与字体映射
使用 poppler-utils 的 pdftotext 是最稳的命令行方案,比纯 PHP 库更可靠:
- 安装 poppler(Ubuntu/Debian:sudo apt install poppler-utils;macOS:brew install poppler)
- 执行:pdftotext -enc UTF-8 -layout input.pdf output.txt
- 在 Yii 中调用:exec("pdftotext -enc UTF-8 -layout " . escapeshellarg($pdfPath) . " " . escapeshellarg($txtPath), $output, $returnCode);
- 读取 $txtPath 前,确保 PHP 文件本身以 UTF-8 无 BOM 编码保存,并在响应头加:header('Content-Type: text/plain; charset=utf-8');
用 mPDF 或 TCPDF 生成 PDF 时预防乱码
如果你是在 Yii 中用 mPDF/TCPDF 生成 PDF 后再读取,乱码常源于生成阶段就未嵌入中文字体:
- mPDF:必须加载支持中文的字体(如 simsun 或 noto-sans-sc),并在构造时指定:$mpdf = new \Mpdf\Mpdf(['autoScriptToLang' => true, 'autoLangToFont' => true, 'fontDir' => [__DIR__.'/fonts/'], 'fontdata' => ['simsun' => ['R' => 'simsun.ttf']] ])
- TCPDF:调用 addTTFfont() 注册中文字体,并在 setFont() 中显式使用,不能依赖系统默认字体。
- 生成后立即用 pdftotext 验证输出是否正常,避免“生成即乱码”却误判为读取问题。
绕过解析,用浏览器前端临时提取
对临时调试或小批量场景,可跳过服务端解析:
- 将 PDF 文件路径传给前端,在 iframe 或 embed 中加载;
- 用 JS 触发 window.getSelection().toString() 获取已选文本;
- 或借助开源库如 pdf.js(Mozilla 官方)在前端解析并导出文本,再 POST 回 Yii 接口。
- 优势:完全规避 PHP 字符集转换风险,适合快速验证内容是否可读。











