Yii框架不内置PDF文字提取功能,需用spipu/pdf-parser库(原smalot/pdfparser的维护版),其轻量、无依赖、支持UTF-8和中文;须确保PDF非扫描件,否则需先OCR;推荐封装为服务类并在Controller中调用。

Yii 框架本身不内置 PDF 文字提取功能,需借助第三方 PHP PDF 解析库(如 tcpdf、fpdi、smalot/pdfparser 或更推荐的 setasign/fpdi + setasign/fpdf 组合),但最稳定、兼容性好且支持中文(需正确处理字体)的是 smalot/pdfparser(纯 PHP 实现,无需扩展)或 spipu/pdf-parser(其活跃维护分支)。
推荐方案:使用 spipu/pdf-parser(原 smalot/pdfparser 的现代维护版)
该库轻量、无依赖、支持 UTF-8,能可靠提取文字(含多栏、表格结构较弱的 PDF),对中文 PDF 只要内嵌字体或使用标准编码即可正常读取。
- 安装(Composer):composer require spipu/pdf-parser
- 确保 PDF 不是扫描图(即非图片型 PDF);若为扫描件,需先 OCR(如调用 Tesseract),Yii 不直接处理 OCR
- Yii2 中建议封装为独立服务类,避免在 Controller 中直写解析逻辑
完整可运行代码(Yii2 环境)
以下为一个标准 Yii2 应用中使用的 PDF 文字提取服务示例(放在 common/services/PdfTextExtractor.php):
<?php namespace common\services;
<p>use Spipu\PdfParser\Parser;<p>class PdfTextExtractor
{
/**</p>
-
从 PDF 文件路径提取纯文本内容
@param string $filePath 本地绝对路径,如 '@runtime/uploads/sample.pdf'
@return string 提取的文字内容(UTF-8)
-
@throws \Exception 当文件不存在、非 PDF 或解析失败时 */ public function extractText($filePath): string { if (!is_file($filePath)) { throw new \Exception("PDF file not found: {$filePath}"); }
// 解析器实例化 $parser = new Parser(); try { $pdf = $parser->parseFile($filePath); return $pdf->getText(); } catch (\Throwable $e) { throw new \Exception("Failed to parse PDF: " . $e->getMessage()); } }
/**
* 从上传的 UploadedFile 对象提取文本(常用于表单上传后立即解析)
* @param \yii\web\UploadedFile $uploadedFile
* @return string
*/
public function extractFromUploadedFile($uploadedFile): string
{
$tempPath = $uploadedFile->tempName;
if (!$tempPath || !is_file($tempPath)) {
throw new \Exception('Invalid uploaded file');
}
return $this->extractText($tempPath);
}
}
在 Controller 中调用示例
假设你有一个上传并解析 PDF 的接口:
use common\services\PdfTextExtractor;
use yii\web\UploadedFile;
<p>public function actionParsePdf()
{
$model = new UploadForm(); // 自定义表单模型,含 file 属性</p><pre class="brush:php;toolbar:false;">if (Yii::$app->request->isPost) {
$model->file = UploadedFile::getInstance($model, 'file');
if ($model->file && $model->file->extension === 'pdf') {
$extractor = new PdfTextExtractor();
try {
$text = $extractor->extractFromUploadedFile($model->file);
// 可选:保存到数据库、返回 API 响应等
return $this->asJson(['success' => true, 'text' => mb_substr($text, 0, 2000)]); // 截断防超长
} catch (\Exception $e) {
return $this->asJson(['success' => false, 'error' => $e->getMessage()]);
}
} else {
return $this->asJson(['success' => false, 'error' => 'Please upload a valid PDF file.']);
}
}
return $this->render('upload');
}
注意事项与常见问题
- 中文乱码? 大多因 PDF 使用了未嵌入的中文字体或自定义编码。spipu/pdf-parser 会尽力映射,但无法 100% 还原。可尝试用 Adobe Acrobat “另存为” → 勾选“保留原始字体”再试;或改用 mikehaertl/php-pdftk(需服务器装 pdftk)配合系统字体缓存
-
空白或只返回页数? 说明 PDF 是扫描图像(Raster PDF)。此时需 OCR 流程:用
Imagick将每页转为 PNG,再调用tesseract-ocrCLI 解析 -
性能优化:大文件(>50MB)建议加超时控制、内存限制(
ini_set('memory_limit', '512M'))及分页提取($pdf->getDetails()获取页数后逐页$pdf->getPage($i)->getText()) -
安全提醒:切勿直接解析用户上传的 PDF 路径(如
$_GET['file']),必须校验扩展名、重命名、存入隔离目录(如@runtime/temp/),防止路径遍历或恶意 PDF 攻击











