PHP API Reference
PDF Oxide ships a pure-PHP binding built on PHP’s built-in FFI extension. The PHP code is a thin layer over the same libpdf_oxide cdylib used by the Python, Node, Go, C#, Ruby, and Java bindings.
composer require oxide/pdf-oxide
All classes live under the PdfOxide\ namespace. PHP 8.2+ with ext-ffi enabled is required. Composer’s post-install hook downloads the matching prebuilt native library; set PDF_OXIDE_CDYLIB_PATH to point at a custom build, or PDF_OXIDE_SKIP_DOWNLOAD=1 to skip the download.
For the Rust API, see the Rust API Reference. For the Python API, see the Python API Reference. For the JavaScript API, see the Node.js API Reference or WASM API Reference.
The binding exposes 10 classes:
| Class | Purpose |
|---|---|
PdfOxide\PdfDocument |
Open, read, extract, and page-iterate PDFs |
PdfOxide\Pdf |
Create PDFs (Markdown to PDF, HTML to PDF), version, model prefetch |
PdfOxide\PdfPage |
Per-page lightweight view |
PdfOxide\MarkdownConverter |
Static Markdown / HTML / plain-text conversion |
PdfOxide\AutoExtractor |
Typed-reason extraction and page classification |
PdfOxide\AutoExtractResult |
Readonly result value object for AutoExtractor |
PdfOxide\DocumentEditor |
Edit, scrub metadata, destructive redaction, save |
PdfOxide\PdfSigner |
PAdES B-B / B-T / B-LT / B-LTA signing |
PdfOxide\PdfValidator |
PDF/A, PDF/UA, and PDF/X compliance checks |
PdfOxide\PdfPolicy |
Set-once process-global crypto-governance policy |
PdfDocument
The primary class for opening, reading, and extracting PDF files.
use PdfOxide\PdfDocument;
Constructors / Factory Methods
PdfDocument::open(string $path): self
Open a PDF from a file path.
PdfDocument::openBytes(string $bytes): self
Open a PDF from an in-memory byte string (e.g. downloaded from S3 or received over HTTP).
PdfDocument::extractTextOnce(string $path): string
Open a file, extract all text in one call, and release the handle.
Document Info
$doc->pageCount(): int
Return the number of pages in the document.
$doc->version(): array
Return the PDF version as a [major, minor] integer array.
$doc->hasStructureTree(): bool
Check whether the document is a Tagged PDF with a structure tree.
$doc->hasFormFields(): bool
Check whether the document contains AcroForm form fields.
$doc->hasSignatures(): bool
Check whether the document contains digital signatures.
$doc->getSourcePath(): ?string
Return the source file path the document was opened from, or null for byte-loaded documents.
Text Extraction
$doc->extractText(int $pageIndex): string
Extract plain text from a single zero-indexed page.
$doc->extractStructured(int $page): array
Extract structured page content (spans, characters, and dimensions) as an associative array.
$doc->extractTextAuto(int $pageIndex): string
Extract text from a page using automatic native-text-or-OCR selection.
Conversion
$doc->toMarkdown(int $pageIndex = 0): string
Convert a single page to Markdown.
$doc->toMarkdownAll(): string
Convert the whole document to Markdown.
$doc->toHtml(int $pageIndex = 0): string
Convert a single page to HTML.
Page Access
$doc->page(int $index): PdfPage
Return a lightweight PdfPage view for the given zero-based index.
$doc->pages(): array
Return all pages as an array of PdfPage objects.
$doc->pagesIter(): \Generator
Lazily iterate over pages, yielding one PdfPage at a time.
Lifecycle
$doc->isOpen(): bool
Return whether the native handle is still open.
$doc->close(): void
Release the native handle. Also called automatically by __destruct().
$doc->getHandle(): CData
Return the raw FFI handle (advanced / interop use).
Create new PDFs from source content, and access library-level helpers.
use PdfOxide\Pdf;
Factory Methods
Pdf::fromMarkdown(string $markdown): self
Create a PDF from Markdown content.
Pdf::fromHtml(string $html): self
Create a PDF from HTML content.
Pdf::fromText(string $text): self
Create a PDF from plain text.
Saving
$pdf->save(): string
Render the PDF and return its bytes as a string.
$pdf->saveTo(string $path): void
Render the PDF and write it to a file path.
Library Helpers
Pdf::version(): string
Return the underlying native library version string.
Pdf::prefetchAvailable(): bool
Return whether OCR model prefetch is available in this build.
Pdf::prefetchModels(array $languages): string
Prefetch OCR models for the given language codes; returns a status string.
Pdf::VERSION // string constant, e.g. "0.3.69"
Lifecycle
$pdf->isOpen(): bool
$pdf->close(): void
$pdf->getHandle(): CData
Inspect, release, or access the raw native handle.
PdfPage
A lightweight per-page view returned by PdfDocument::page(), pages(), or pagesIter().
use PdfOxide\PdfPage;
Methods
$page->parent(): PdfDocument
Return the owning PdfDocument.
$page->index(): int
Return the zero-based page index.
$page->text(): string
Extract plain text from this page.
$page->textAuto(): string
Extract text from this page using automatic native-text-or-OCR selection.
$page->toMarkdown(): string
Convert this page to Markdown.
$page->toHtml(): string
Convert this page to HTML.
$page->__toString(): string
Return the page’s plain text when the object is used in string context.
MarkdownConverter
Static helpers for converting an open PdfDocument to Markdown, HTML, or plain text.
use PdfOxide\MarkdownConverter;
Methods
MarkdownConverter::toMarkdown(PdfDocument $doc, int $pageIndex): string
Convert a single page to Markdown.
MarkdownConverter::toMarkdownAll(PdfDocument $doc): string
Convert the whole document to Markdown.
MarkdownConverter::toHtml(PdfDocument $doc, int $pageIndex): string
Convert a single page to HTML.
MarkdownConverter::toPlainText(PdfDocument $doc, int $pageIndex): string
Convert a single page to plain text.
AutoExtractor
Typed-reason extraction with native-text-or-OCR selection and per-page document classification.
use PdfOxide\AutoExtractor;
Constants
| Constant | Value | Meaning |
|---|---|---|
AutoExtractor::MODE_AUTO |
0 |
Auto-select native text or OCR |
AutoExtractor::MODE_TEXT_ONLY |
1 |
Native text only, never OCR |
AutoExtractor::MODE_FORCE_OCR |
2 |
Always run OCR |
Factory Methods
AutoExtractor::of(PdfDocument $doc, int $mode = self::MODE_AUTO): self
Create an extractor over a document with an explicit mode.
AutoExtractor::fast(PdfDocument $doc): self
Create an extractor tuned for speed.
AutoExtractor::balanced(PdfDocument $doc): self
Create an extractor balancing speed and fidelity.
AutoExtractor::highFidelity(PdfDocument $doc): self
Create an extractor tuned for maximum fidelity.
Extraction
$ex->extractText(): string
Extract text from the whole document.
$ex->extractTextForPage(int $pageIndex): string
Extract text from a single page.
$ex->extractAutoPage(int $pageIndex): AutoExtractResult
Extract a single page, returning a typed AutoExtractResult with reason and confidence.
$ex->extractAutoDocument(): AutoExtractResult
Extract the whole document, returning a typed AutoExtractResult.
$ex->extractPageJson(int $pageIndex): string
Extract a single page as a JSON string.
$ex->extractDocumentJson(): string
Extract the whole document as a JSON string.
Classification
$ex->classifyPageKind(int $pageIndex): string
Classify a single page (e.g. text_layer, scanned, image_text, mixed, empty).
$ex->classifyDocumentKinds(): array
Classify every page, returning an array of page-kind strings.
Accessors
$ex->document(): PdfDocument
Return the underlying PdfDocument.
$ex->mode(): int
Return the active extraction mode constant.
AutoExtractResult
Readonly value object returned by AutoExtractor::extractAutoPage() and extractAutoDocument().
use PdfOxide\AutoExtractResult;
Properties
| Property | Type | Description |
|---|---|---|
text |
string |
Extracted text |
reason |
string |
One of the REASON_* constants |
confidence |
float |
Confidence in [0.0, 1.0] |
ocrUsed |
bool |
Whether OCR ran for this result |
regions |
array |
Per-region rich detail |
pagesNeedingOcr |
array |
Page indices that still need OCR |
Constants
| Reason constant | Value |
|---|---|
REASON_OK |
ok |
REASON_NATIVE_TEXT_HIGH_CONFIDENCE |
native_text_high_confidence |
REASON_NO_TEXT_LAYER_PRESENT |
no_text_layer_present |
REASON_OCR_REQUESTED_BUT_UNAVAILABLE |
ocr_requested_but_unavailable |
REASON_OCR_LOW_CONFIDENCE_FALLBACK |
ocr_low_confidence_fallback |
REASON_IMAGE_TABLE_RECONSTRUCTED |
image_table_reconstructed |
REASON_EMPTY |
empty |
| Kind constant | Value |
|---|---|
KIND_TEXT_LAYER |
text_layer |
KIND_SCANNED |
scanned |
KIND_IMAGE_TEXT |
image_text |
KIND_MIXED |
mixed |
KIND_EMPTY |
empty |
Methods
$result->isOk(): bool
Return whether the extraction succeeded with no degradation.
$result->isOcrFallback(): bool
Return whether an OCR-unavailable or low-confidence fallback path engaged.
DocumentEditor
Edit a PDF in place: scrub metadata, apply destructive redactions, set the producer, and save.
use PdfOxide\DocumentEditor;
Constructor
DocumentEditor::open(string $path): self
Open a PDF for editing.
Redaction
$editor->addRedaction(int $pageIndex, float $x1, float $y1, float $x2, float $y2): self
Queue a rectangular redaction region (coordinates in PDF points). Fluent — returns $this.
$editor->redactionCount(int $pageIndex): int
Return the number of pending redactions on a page.
$editor->applyRedactionsDestructive(bool $scrubMetadata = true): int
Permanently apply all queued redactions (fails closed on error). Returns the number applied; optionally scrubs metadata.
Metadata
$editor->scrubMetadata(): self
Remove document metadata. Fluent — returns $this.
$editor->getProducer(): string
Return the document’s Producer string.
$editor->setProducer(string $producer): self
Set the document’s Producer string. Fluent — returns $this.
Document Info
$editor->version(): array
Return the PDF version as a [major, minor] array.
$editor->pageCount(): int
Return the number of pages.
$editor->isModified(): bool
Return whether the document has unsaved modifications.
$editor->sourcePath(): string
Return the source file path.
Saving
$editor->saveTo(string $path): void
Write the edited PDF to a file path.
$editor->save(): string
Render the edited PDF and return its bytes as a string.
Lifecycle
$editor->isOpen(): bool
$editor->close(): void
$editor->getHandle(): CData
Inspect, release, or access the raw native handle.
PdfSigner
PAdES digital signing with B-B, B-T, B-LT, and B-LTA conformance levels.
use PdfOxide\PdfSigner;
Constants
| Constant | Value | Level |
|---|---|---|
PdfSigner::LEVEL_B_B |
0 |
PAdES B-B (baseline) |
PdfSigner::LEVEL_B_T |
1 |
PAdES B-T (with timestamp) |
PdfSigner::LEVEL_B_LT |
2 |
PAdES B-LT (long-term) |
PdfSigner::LEVEL_B_LTA |
3 |
PAdES B-LTA (long-term with archive timestamp) |
Constructor / Factory
PdfSigner::fromPkcs12(string $keystorePath, string $password): self
Create a signer from a PKCS#12 (.p12 / .pfx) keystore.
Signing
$signer->sign(
string $pdfBytes,
string|int $level = self::LEVEL_B_B,
?string $tsaUrl = null,
?string $reason = null,
?string $location = null,
): string
Sign PDF bytes and return the signed PDF bytes. Levels above B-B require a tsaUrl. $level accepts the LEVEL_B_* ordinal or a short tag ('b', 't', 'lt', 'lta').
PdfSigner::signWithHandle(
string $pdfBytes,
CData $certificateHandle,
string|int $level,
?string $tsaUrl = null,
?string $reason = null,
?string $location = null,
): string
Static convenience: sign without constructing a managed signer instance. The caller retains ownership of $certificateHandle.
Verification
PdfSigner::verify(string $pdfBytes): bool
Return whether the PDF bytes carry a signature dictionary and byte range.
Lifecycle
$signer->isOpen(): bool
$signer->close(): void
Inspect or free the signing credentials.
PdfValidator
Static PDF/A, PDF/UA, and PDF/X compliance checks against an open PdfDocument.
use PdfOxide\PdfValidator;
Constants
| PDF/A constant | Value | PDF/UA constant | Value | |
|---|---|---|---|---|
PDFA_1B |
0 |
PDFUA_1 |
1 |
|
PDFA_1A |
1 |
PDFUA_2 |
2 |
|
PDFA_2B |
2 |
|||
PDFA_2A |
3 |
|||
PDFA_2U |
4 |
|||
PDFA_3B |
5 |
|||
PDFA_3A |
6 |
|||
PDFA_3U |
7 |
Methods
PdfValidator::isPdfA(PdfDocument $doc, int $level = self::PDFA_1B): bool
Return whether the document conforms to the given PDF/A level.
PdfValidator::isPdfUa(PdfDocument $doc, int $level = self::PDFUA_1): bool
Return whether the document conforms to the given PDF/UA level.
PdfValidator::isPdfX(PdfDocument $doc): bool
Not implemented — pdf_oxide currently has no public PDF/X validator exposed in the C ABI. Calling this always throws BadMethodCallException.
PdfValidator::validatePdfA(PdfDocument $doc, int $level = self::PDFA_1B): array
Run a full PDF/A validation and return a structured result array (conformance flag plus any violations).
PdfPolicy
Set-once, process-global crypto-governance policy. Must be configured before opening any PDF.
use PdfOxide\PdfPolicy;
Constants
| Constant | Value |
|---|---|
PdfPolicy::COMPAT |
compat |
PdfPolicy::STRICT |
strict |
PdfPolicy::FIPS_STRICT |
fips_strict |
Methods
PdfPolicy::current(): string
Return the active policy mode.
PdfPolicy::set(string $mode): void
Set the process-global policy (one of the policy constants). Set-once per process.
PdfPolicy::fipsAvailable(): bool
Return whether a FIPS-validated crypto provider is available.
PdfPolicy::activeProvider(): string
Return the name of the active crypto provider.
PdfPolicy::compat(): string
PdfPolicy::strict(): string
PdfPolicy::fipsStrict(): string
Convenience accessors returning the corresponding policy-mode string.
Error Handling
All PDF-specific errors extend PdfOxide\Exceptions\PdfException. Specialized subclasses let you catch narrower failure categories.
use PdfOxide\PdfDocument;
use PdfOxide\Exceptions\PdfException;
try {
$doc = PdfDocument::open('file.pdf');
echo $doc->extractText(0);
} catch (PdfException $e) {
error_log("PDF error: {$e->getMessage()}");
}
Exception (under PdfOxide\Exceptions\) |
Cause |
|---|---|
PdfException |
Base class for all PDF errors |
ParseException |
Malformed or unparseable PDF |
IoException |
File read/write failure |
NotFoundException |
Missing file, page, or object |
EncryptionException |
Encryption / password failure |
ValidationException |
Invalid argument or input |
SignatureException |
Signing or signature-verification failure |
RedactionException |
Redaction failure |
SearchException |
Search failure |
OptimizationException |
Optimization failure |
ComplianceException |
PDF/A or PDF/UA compliance failure |
AccessibilityException |
Accessibility / tagging failure |
UnsupportedException |
Unsupported feature or operation |
InvalidStateException |
Operation on a closed or invalid handle |
InternalError |
Internal native error |
Complete Example
use PdfOxide\PdfDocument;
use PdfOxide\Pdf;
use PdfOxide\AutoExtractor;
use PdfOxide\DocumentEditor;
use PdfOxide\PdfSigner;
use PdfOxide\PdfValidator;
// --- Extraction ---
$doc = PdfDocument::open('input.pdf');
echo $doc->pageCount(), " pages\n";
for ($i = 0; $i < $doc->pageCount(); $i++) {
echo "Page {$i}: ", strlen($doc->extractText($i)), " chars\n";
}
echo $doc->toMarkdownAll();
// --- Auto-extraction with typed reasons ---
$ex = AutoExtractor::of($doc);
$result = $ex->extractAutoPage(0);
if (!$result->isOk()) {
error_log("degraded extraction: {$result->reason}");
}
$doc->close();
// --- Creation ---
$pdf = Pdf::fromMarkdown("# Invoice\n\n**Total:** \$42.00\n");
$pdf->saveTo('invoice.pdf');
$pdf->close();
// --- Destructive redaction ---
$editor = DocumentEditor::open('in.pdf');
$editor->addRedaction(0, 100.0, 700.0, 300.0, 720.0);
$editor->applyRedactionsDestructive();
$editor->saveTo('redacted.pdf');
$editor->close();
// --- PAdES B-T signature ---
$signer = PdfSigner::fromPkcs12('certs/sign.p12', 'p12-password');
$signed = $signer->sign(
pdfBytes: file_get_contents('contract.pdf'),
level: PdfSigner::LEVEL_B_T,
tsaUrl: 'https://freetsa.org/tsr',
reason: 'Final contract',
);
file_put_contents('signed.pdf', $signed);
$signer->close();
// --- Compliance check ---
$doc = PdfDocument::open('archive.pdf');
var_dump(PdfValidator::isPdfA($doc, PdfValidator::PDFA_2B));
$doc->close();
Other Language Bindings
PDF Oxide ships native bindings for every major ecosystem: Rust, Python, Node.js, WASM, C#, Golang, Java, Ruby, C++, Swift, Kotlin, Dart, R, Julia, Zig, Scala, Clojure, Objective-C, and Elixir.
Next Steps
- Types & Enums — all shared types and enums
- Page API Reference — consistent per-page iteration across bindings
- Getting Started with PHP — tutorial