Yii不内置PDF文本提取功能,需借助smalot/pdfparser(纯PHP推荐)或系统pdftotext命令;扫描件需OCR,加密PDF需传密码,中文乱码需检查字体嵌入,大文件需调高内存限制。

Yii 本身不提供直接读取 PDF 并提取文本的内置功能,它依赖 PHP 扩展或第三方库来完成 PDF 解析。核心思路是:在 Yii 控制器中调用底层 PDF 文本提取工具(如 tcpdf、smalot/pdfparser 或系统命令 pdftotext),将结果返回给前端或用于后续处理。
使用 smalot/pdfparser(推荐,纯 PHP,无需扩展)
这是最轻量、兼容性好、无需安装系统级工具的方案:
- 通过 Composer 安装:
composer require smalot/pdfparser - 在控制器中解析并输出文本:
use Smalot\PdfParser\Parser;
public function actionExtractPdfText()
{
$filePath = '@app/web/uploads/report.pdf'; // 确保路径真实存在且可读
$realPath = \Yii::getAlias($filePath);
if (!is_file($realPath)) {
throw new \yii\web\HttpException(404, 'PDF 文件不存在');
}
$parser = new Parser();
$pdf = $parser->parseFile($realPath);
$text = $pdf->getText(); // 提取全部可见文本(含换行和空格)
// 直接输出纯文本(浏览器会显示为 text/plain)
\Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
\Yii::$app->response->headers->set('Content-Type', 'text/plain; charset=utf-8');
return $text;
}
调用系统 pdftotext 命令(高效,适合大文件)
如果服务器已安装 Poppler 工具集(Linux/macOS 常见),pdftotext 提取速度快、准确率高:
- 先确认命令可用:
which pdftotext或pdftotext -v - 在控制器中安全执行(注意路径转义与超时):
$filePath = \Yii::getAlias('@app/web/uploads/report.pdf');
$escapedPath = escapeshellarg($filePath);
$outputFile = tempnam(sys_get_temp_dir(), 'pdf2txt_') . '.txt';
// 执行转换(-layout 保留原文排版结构)
$cmd = "pdftotext -layout {$escapedPath} {$outputFile} 2>/dev/null";
exec($cmd, $output, $returnCode);
if ($returnCode !== 0 || !is_file($outputFile)) {
throw new \yii\web\HttpException(500, 'PDF 文本提取失败');
}
$text = file_get_contents($outputFile);
unlink($outputFile); // 清理临时文件
return $text;
注意事项与常见问题
PDF 文本提取不是“所见即所得”,效果受原始 PDF 类型影响极大:
- 扫描件 PDF(图片型):上述方法完全无效,必须先 OCR(如 Tesseract + imagick),Yii 中需额外集成
-
加密 PDF:smalot/pdfparser 支持带密码的 PDF,调用时传入密码参数:
$parser->parseFile($path, 'your_password') -
中文乱码:smalot/pdfparser 对中文字体支持较好;若出现方块或空格,检查 PDF 是否嵌入字体,或尝试用
pdftotext -enc UTF-8 -
内存限制:大 PDF(>50MB)可能触发 PHP 内存溢出,建议加
ini_set('memory_limit', '512M');或改用流式命令行方式
不建议的做法
不要尝试用 file_get_contents() 直接读取 PDF 二进制再正则匹配——PDF 是复杂结构的二进制/混合文本格式,没有解析器无法可靠提取语义文本。也不要用 Yii 的 sendFile(),它只负责传输,不解析内容。



















