yii框架无内置pdf文本提取功能,需用smalot/pdfparser封装为可配置组件,支持中文但不处理扫描版pdf;推荐方案是创建pdftextextractor类并注册为应用组件,避免直接new实例或误用生成类库。

Yii 框架本身不提供 PDF 文本提取功能,它没有内置的 PDF 解析器。要从 PDF 文件中提取文本内容,需借助第三方 PHP 库(如 smalot/pdfparser、setasign/fpdi 配合 tcpdf、或 spipu/html2pdf 的反向解析能力),再将其封装为 Yii 组件使用。
你真正需要的,是一个可复用、可配置、能注入到 Yii 应用生命周期中的 PDF 文本提取服务,而不是“Yii 自带组件”。
✅ 推荐方案:用 smalot/pdfparser 封装为 Yii2 组件
这是目前最轻量、稳定、支持中文(需 PDF 内含可选中文编码)且无需外部二进制依赖的纯 PHP 解决方案。
安装依赖
composer require smalot/pdfparser
创建 PDF 提取组件(@app/components/PdfTextExtractor.php)
<?php namespace app\components;
use Smalot\PdfParser\Parser;
class PdfTextExtractor
{
public function extract($filePath): string
{
if (!is_file($filePath) || !is_readable($filePath)) {
throw new \InvalidArgumentException("PDF file not found or unreadable: $filePath");
}
try {
$parser = new Parser();
$pdf = $parser->parseFile($filePath);
return trim($pdf->getText()); // 返回纯文本,已自动合并多页
} catch (\Exception $e) {
throw new \RuntimeException("Failed to parse PDF text: " . $e->getMessage(), 0, $e);
}
}
}
在配置中注册为应用组件(config/web.php)
'components' => [
'pdfExtractor' => [
'class' => 'app\components\PdfTextExtractor',
],
// …其他组件
],
在控制器或服务中调用
$text = Yii::$app->pdfExtractor->extract('@webroot/uploads/invoice.pdf');
echo mb_substr($text, 0, 200) . '...'; // 示例:截取前200字
⚠️ 注意:该库无法识别扫描版 PDF(图片型)。若 PDF 是 OCR 后的图像文档,需先用
tesseract-ocr+imagick预处理,或改用mupdf/poppler-utils命令行工具(需服务器支持)。
❌ 不推荐的“伪组件”方式
- 直接在控制器里
new Parser()调用:破坏可测试性与复用性,不满足 Yii 组件设计初衷; - 试图用
yii2-export或mpdf反向提取文本:它们是生成 PDF 的库,不具备解析能力; - 依赖
fpdi:它只负责导入已有 PDF 页面,不提供文本抽取接口。
? 中文 PDF 提取常见问题
| 现象 | 原因 | 解法 |
|---|---|---|
| 提取为空或乱码 | PDF 使用 CID 字体但未嵌入 ToUnicode 表 | 尝试用 Adobe Acrobat “另存为文本”验证是否真可读;优先选用已 OCR 处理过的 PDF |
报 Invalid PDF header
|
文件损坏或实际是 ZIP/加密文件 | 先用 file $path 或 head -c 10 $path 检查魔数(应为 %PDF-) |
| 内存溢出(大 PDF) |
smalot/pdfparser 会加载整份结构到内存 |
对超 50MB 文件加 try/catch + ini_set('memory_limit', '512M'),或改用流式解析库(如 setasign/fpdi-fpdf 配合自定义解析逻辑) |
? 进阶建议:对接 OCR 流程(可选)
当必须处理扫描件时,可扩展组件:
- 判断 PDF 是否含文字层(用
$pdf->getDetails()['Pages']看是否有/Contents); - 若无,则调用
shell_exec('pdftoppm -f 1 -l 1 -png ' . escapeshellarg($filePath) . ' /tmp/page')截图第一页; - 再用
tesseract /tmp/page-1.png stdout -l chi_sim提取中文(需提前安装tesseract-ocr-chi-sim)。
该逻辑可封装进 PdfTextExtractor::extractWithOcr() 方法,按需启用。
不复杂但容易忽略:PDF 文本提取不是“开箱即用”的功能,关键在选对底层库 + 封装成 Yii 组件 + 明确处理边界(空页、扫描件、内存、编码)。











