PHP无法直接解析PDF文本,需借助外部工具:首选pdftotext(Poppler)处理文字型PDF;扫描件需调用阿里云等OCR云服务;纯PHP库如smalot/pdfparser仅适用于简单场景。

PHP 本身不能直接识别 PDF 的文本内容,因为 PDF 是结构化二进制格式(含对象、字体映射、压缩流等),不是纯文本。直接用 file_get_contents() 读取只会得到乱码。真正可行的方式是借助外部工具或服务做解析层,PHP 负责调度和处理结果。
以下是三种主流、稳定、生产可用的路径,按推荐优先级排序:
✅ 推荐方案:用 pdftotext(Poppler)命令行工具
最适合大多数常规 PDF(文字型、非扫描件、无强加密),速度快、准确率高、支持排版保留。
-
前提条件
立即学习“PHP免费学习笔记(深入)”;
- Linux/Unix 服务器(Ubuntu/Debian:
sudo apt install poppler-utils;CentOS:sudo yum install poppler-utils) - PHP 开启
exec()(检查disable_functions配置中未禁用)
- Linux/Unix 服务器(Ubuntu/Debian:
-
基础用法(提取全文)
$pdfPath = '/path/to/doc.pdf'; $txtPath = sys_get_temp_dir() . '/pdf_' . uniqid() . '.txt';
// -layout 保留换行与空格,-enc UTF-8 防止中文乱码 exec("pdftotext -layout -enc UTF-8 '{$pdfPath}' '{$txtPath}' 2>&1", $output, $returnCode);
if ($returnCode === 0 && file_exists($txtPath)) { $text = file_get_contents($txtPath); unlink($txtPath); // 清理临时文件 } else { throw new Exception('pdftotext 执行失败:' . implode("\n", $output)); }
- **进阶:只提取某页某区域(适合结构化表单/证书)**
```php
// 提取第1页中 x=100~400, y=200~600 的矩形区域(单位:点)
$cmd = "pdftotext -f 1 -l 1 -x 100 -y 200 -W 300 -H 400 '{$pdfPath}' - 2>/dev/null";
$output = shell_exec($cmd);
$text = trim($output) ?: '';⚠️ 注意:坐标需用 Adobe Acrobat 或 Evince 等工具手动测量;加密 PDF 会静默失败,建议先用
pdfinfo $pdfPath检查Encrypted: yes。
? 备选方案:调用 OCR 云服务(适合扫描件/PDF 图片)
当 PDF 是拍照生成、扫描件或含大量图片时,pdftotext 无法识别文字,必须走 OCR。
-
阿里云 OCR(推荐)
- 支持整份 PDF(最多 50 页/次),自动分页识别、返回带坐标的 JSON
- 需开通「文档识别 > PDF 文档识别」服务,获取 AccessKey
- 示例关键步骤:
- 用
pdftk或ghostscript拆分大 PDF(每份 ≤50 页) - 调用
ocr_document_recognize接口上传 - 解析返回的
data.blocks[].words[]提取文字
- 用
ComPDFKit / 其他 API
同样需申请 key,通过 cURL 发送 PDF 文件二进制流,接收结构化 JSON 结果,适合不想维护服务器环境的场景。
? 纯 PHP 库(仅限简单场景)
如无法安装系统工具、无命令行权限,可考虑:
-
smalot/pdfparser(最常用)
use Smalot\PdfParser\Parser; $parser = new Parser(); $pdf = $parser->parseFile('doc.pdf'); $text = $pdf->getText(); // 对纯文字 PDF 可用,但遇自定义字体、加密、扫描件易失效- ✅ 无需扩展,Composer 一键集成
- ❌ 不处理图像 OCR,对 JBIG2、嵌入字体、弱加密 PDF 支持差
其他库(如
setasign/fpdi、TCPDF)主要面向生成/修改 PDF,不推荐用于文本识别。
不复杂但容易忽略:识别前务必判断 PDF 类型——
-
file --mime-type doc.pdf看是否为application/pdf -
pdfinfo doc.pdf | grep "Pages\|Encrypted"快速探查页数与加密状态 - 打开 PDF 查看是否能手动复制文字:能复制 →
pdftotext;不能 → 走 OCR。



















