Overview
tc-lib-pdf-parser parses raw PDF data into structured PHP arrays for extraction, analysis, and downstream processing.
It is built for tooling: inspecting content, pulling out metadata, checking structure, and feeding migration pipelines. It also backs the page import in tc-lib-pdf.
Repository and API Docs
- GitHub: https://github.com/tecnickcom/tc-lib-pdf-parser
- API docs: https://tcpdf.org/docs/srcdoc/tc-lib-pdf-parser
- Packagist: https://packagist.org/packages/tecnickcom/tc-lib-pdf-parser
Project Metadata
| Item | Value |
|---|---|
| Namespace | \Com\Tecnick\Pdf\Parser |
| License | GNU LGPL v3 |
Installation
composer require tecnickcom/tc-lib-pdf-parser
Where It Fits
When PDFs arrive from outside and have to be read: analysed, merged, mined for content, or stamped and passed on.
Features
Parsing Capabilities
- Cross-reference tables and cross-reference streams, including
/Prevchains and incremental updates - Object streams (
/ObjStm) - Indirect references, resolved on demand and bounded against cycles
- Stream decoding through tc-lib-pdf-filter, including the predictors of
DecodeParms - Structured output suitable for custom extractors
Runtime Design
- Configuration options for tolerant parsing modes
- Pure-PHP parser with no external service dependency
- Typed exceptions for error handling
Parser Options
| Option | Default | Description |
|---|---|---|
decode_streams | true | Decode object stream content while parsing. Set it to false when the caller only needs the raw stream bytes (for example when importing pages), which avoids the cost of decoding streams that are re-emitted unchanged. |
ignore_filter_errors | false | Keep a stream that fails to decode as raw data instead of raising an exception. |
max_stream_size | 33554432 | Maximum size in bytes of a single decoded stream; 0 means unlimited. |
Limits
Parsing is bounded on every axis a hostile document can grow:
- Maximum decoded size of a single stream (
max_stream_size) - Maximum nesting depth of arrays and dictionaries
- Maximum depth of indirect object resolutions, with object reference cycles broken
- Maximum number of chained cross-reference sections
Robustness
- Cross-reference stream
/Indexhandling and the stream predictors are fully implemented, with predictor geometry and row coverage validated. - An out-of-range
startxref, free entries, literal strings and comments in the trailer are handled without aborting the parse. #xxname escapes are decoded, hex strings validated, and unbalanced delimiters and unterminated containers tokenized without spinning.- Dictionary and array parse loops bail out when the offset stops advancing, so malformed input cannot spin forever.
- Error tolerance was improved so partially damaged documents still yield a usable object tree.
Integration Notes
- Treat external PDFs as untrusted input and validate before processing; lower
max_stream_sizewhen the expected documents are small. - Catch the parser exceptions where you can attribute them to a document. A stack trace with no filename is worth very little when a batch of ten thousand fails on one.
- Build fixtures from PDFs you have actually received. Real-world producers emit structures the specification permits and nobody writes by hand, and those are what break a parser.
Requirements
- PHP 8.2 or later
- Extension:
pcre - Package dependency:
tecnickcom/tc-lib-pdf-filter - Composer
Example
<?php
require_once __DIR__ . '/vendor/autoload.php';
$raw = file_get_contents('/path/to/document.pdf');
$parser = new \Com\Tecnick\Pdf\Parser\Parser([
'ignore_filter_errors' => true,
'max_stream_size' => 16 * 1024 * 1024,
]);
$data = $parser->parse((string) $raw);
var_dump($data);
Development and Packaging
- QA and local checks:
make deps,make help,make qa - Coverage report:
make qa-coverage - Packaging:
make rpm,make deb
Support and Contribution
- Sponsor: https://github.com/sponsors/tecnickcom
- Contribution guide: https://github.com/tecnickcom/tc-lib-pdf-parser/blob/main/CONTRIBUTING.md
- Security policy: https://github.com/tecnickcom/tc-lib-pdf-parser/blob/main/SECURITY.md