smalot/pdfparser
Standalone PHP library to parse PDF files and extract content. Reads objects/headers, metadata, and ordered page text; supports compressed PDFs and various encodings. Configure parsing via custom configs. Note: no support for secured PDFs or form data.
Installation:
composer require smalot/pdfparser
Ensure your project uses PHP 7.1+.
Basic Usage:
use Smalot\PdfParser\Parser;
$parser = new Parser();
$pdf = $parser->parseFile('/path/to/document.pdf');
$text = $pdf->getText();
Key Methods:
parseFile(): Parse a PDF file from disk.parseContent(): Parse PDF content from a string.parseStream(): Parse PDF content from a stream (e.g., HTTP request).getText(): Extract all text from the PDF.getPagesText(): Extract text from specific pages (e.g., $pdf->getPagesText([1, 2])).Extract metadata and text from an uploaded PDF in a Laravel controller:
use Smalot\PdfParser\Parser;
public function processPdf(Request $request)
{
$request->validate(['pdf' => 'required|file|mimes:pdf']);
$parser = new Parser();
$pdf = $parser->parseFile($request->file('pdf')->getRealPath());
return response()->json([
'metadata' => $pdf->getMetadata(),
'text' => $pdf->getText(),
'pages' => $pdf->getPagesText(),
]);
}
Text Extraction:
$pdf->getText() for full document text.$pdf->getPagesText([$pageNumbers]) for targeted pages.$text = $pdf->getPagesText(range(1, 3));
Metadata Handling:
$pdf->getMetadata():
$metadata = $pdf->getMetadata();
// Example: $metadata['Author'], $metadata['Title']
Streaming Parsing:
$parser = new Parser();
$pdf = $parser->parseStream($request->pdf);
Custom Configurations:
CustomConfig:
use Smalot\PdfParser\Config\CustomConfig;
$config = new CustomConfig();
$config->setOption('ignore_images', true); // Skip image XObjects
$parser = new Parser($config);
Laravel Storage: Parse files stored in Laravel's filesystem:
use Illuminate\Support\Facades\Storage;
$path = Storage::path('uploads/document.pdf');
$pdf = $parser->parseFile($path);
Queue Jobs:
Offload parsing to a queue (e.g., PdfParseJob):
PdfParseJob::dispatch($filePath)->onQueue('pdf');
Service Provider:
Bind the parser in AppServiceProvider for dependency injection:
$this->app->singleton(Parser::class, function () {
return new Parser(new CustomConfig());
});
Validation: Validate PDF content before processing:
$text = $pdf->getText();
if (str_contains($text, 'confidential')) {
abort(403, 'Access denied');
}
Memory Limits:
setMemoryLimit() in CustomConfig:
$config->setMemoryLimit(512); // MB
parseStream) is more memory-efficient for large files.Malformed PDFs:
try {
$pdf = $parser->parseFile($path);
} catch (\Smalot\PdfParser\Exceptions\ParseException $e) {
Log::error("PDF parse error: " . $e->getMessage());
return response()->json(['error' => 'Invalid PDF'], 400);
}
Encrypted PDFs:
pdftotext) for secured files.Text Extraction Quirks:
$config->setOption('ignore_images', true);
$config->setOption('ignore_forms', true);
Line Endings:
\r\n vs \n) may cause parsing issues. Normalize input if needed.Log Raw Data: Inspect raw PDF content for debugging:
$rawContent = file_get_contents($path);
Log::debug('PDF Header:', substr($rawContent, 0, 100));
Check Object Structure: Dump parsed objects to understand the PDF structure:
$objects = $pdf->getObjects();
dd($objects[1]->getData()); // Inspect object #1
Validate Metadata: Ensure metadata keys exist before accessing:
$author = $pdf->getMetadata()['Author'] ?? 'Unknown';
Custom Text Processing:
Override formatContent() in a subclass:
class CustomParser extends Parser {
protected function formatContent($content) {
$content = parent::formatContent($content);
return str_replace(['[REDACTED]', '(REDACTED)'], '', $content);
}
}
Hooks for Post-Processing: Use events or callbacks after parsing:
$pdf = $parser->parseFile($path);
$text = $pdf->getText();
$processedText = app()->call([TextProcessor::class, 'process'], ['text' => $text]);
Performance Optimization:
$cacheKey = 'pdf_text_' . md5($path);
$text = Cache::remember($cacheKey, now()->addHours(1), function () use ($pdf) {
return $pdf->getText();
});
Testing:
$mockParser = Mockery::mock(Parser::class);
$mockParser->shouldReceive('parseFile')->andReturn($mockPdf);
Default Options:
Review CustomConfig options:
$config->setOption('ignore_comments', true); // Skip PDF comments
$config->setOption('ignore_inline_images', true); // Skip inline images
Character Encoding: Force UTF-8 encoding if needed:
$config->setOption('charset', 'UTF-8');
Page Order: Extract pages in reverse order:
$pages = array_reverse($pdf->getPagesText());
How can I help you explore Laravel packages today?