Skip to content

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).


Pdf

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