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><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/gongju/2519" title="Yii Framework 2.0.51"><img
src="https://img.php.cn/upload/manual/001/503/042/6a6b03d191dbf935.png" alt="Yii Framework 2.0.51" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/gongju/2519" title="Yii Framework 2.0.51">Yii Framework 2.0.51</a>
<p>Yii Framework 2.0.51 官方 Basic 应用模板,适合旧项目兼容、升级验证和开发测试。</p>
</div>
<a href="/xiazai/gongju/2519" title="Yii Framework 2.0.51" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>class PdfTextExtractor
{
/**</p><ul><li><p>从 PDF 文件路径提取纯文本内容</p></li><li><p>@param string $filePath 本地绝对路径,如 '@runtime/uploads/sample.pdf'</p></li><li><p>@return string 提取的文字内容(UTF-8)</p></li><li><p>@throws \Exception 当文件不存在、非 PDF 或解析失败时
*/
public function extractText($filePath): string
{
if (!is_file($filePath)) {
throw new \Exception("PDF file not found: {$filePath}");
}</p><p>// 解析器实例化
$parser = new Parser();
try {
$pdf = $parser->parseFile($filePath);
return $pdf->getText();
} catch (\Throwable $e) {
throw new \Exception("Failed to parse PDF: " . $e->getMessage());
}
}</p></li></ul><pre class="brush:php;toolbar:false;">/**
* 从上传的 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 攻击

















