Skip to content
getnextpdf.com

Pro edition

Interop — Deep Reference

This page is the contract-level reference for NextPDF\Pro\Interop\V1. The module contains fourteen public symbols: one serialization contract (InteropResultInterface), one CI integrity guard (SchemaLock), three top-level result DTOs (ExtractedText, DocumentSegmentation, FormData), and nine supporting value objects and enums. Every DTO is an immutable, JSON-serializable view of one analysis result. The wire shape is versioned and locked; nothing on this surface re-runs analysis. The task-oriented view lives on the capability page.

This capability ships in NextPDF Pro (nextpdf/pro) and activates with a Pro-tier license envelope. A deployment without that entitlement does not load the capability’s classes. Compare editions and get a license.

No runtime capability flag gates this module. The classes are available whenever nextpdf/pro is installed and licensed.

SymbolParametersDefault behaviorReturnsThrows or fails withNotes
InteropResultInterfaceContract for top-level result DTOs; extends JsonSerializableDoes not throwSCHEMA_VERSION is the string '1.0'.
InteropResultInterface::toArray()noneSerializes to a JSON-safe array that always carries schema_versionarray<string, mixed>Does not throwImplementations also emit a type discriminator.
InteropResultInterface::toJson()int $flags = 0Encodes the toArray() output; JSON_THROW_ON_ERROR is always OR-ed instringJsonException on non-encodable dataPass flags such as JSON_PRETTY_PRINT.
SchemaLock::verify()noneHashes the on-disk V1 schema.json and compares it against the locked SHA-256boolDoes not throwfalse when the schema file is missing, unreadable, or modified.
SchemaLock::expectedHash()noneReturns the locked hashstringDoes not throwDiagnostic output for CI failure triage.
SchemaLock::actualHash()noneReturns the hash of the current schema filestringDoes not throwSentinel strings FILE_NOT_FOUND / READ_FAILED replace the hash on I/O failure.
BoundingBoxfloat $x, float $y, float $width, float $heightImmutable box in PDF user-space points, origin at the bottom-leftDoes not throwarea(), overlaps(), toArray(), fromArray().
DocumentInfoint $pageCount plus six optional metadata fieldsImmutable document metadataDoes not throwfromArray() type-guards every field; absent fields fall back to defaults.
PageInfoint $pageNumber, float $width, float $height, int $rotation = 0Immutable page metadataDoes not throwisLandscape(); fromArray() coerces numeric strings and floats.
ExtractedTextlist<ExtractedPage> $pages, DocumentInfo $documentInfo, float $processingTimeMs = 0.0Whole-document text-extraction resultJsonException from toJson() onlypage(), totalBlockCount(), plainText(), fromArray().
ExtractedPagePageInfo $pageInfo, list<TextBlock> $textBlocksPer-page container of text blocks in reading orderDoes not throwplainText() joins block content with single spaces.
TextBlockstring $content, BoundingBox $boundingBox, int $pageNumber, string $fontName = '', float $fontSize = 0.0Positioned contiguous text runDoes not throwFont name and size are best-effort (dominant font in the block).
DocumentSegmentationlist<Segment> $segments, DocumentInfo $documentInfo, float $processingTimeMs = 0.0Layout-aware segmentation resultJsonException from toJson() onlysegmentCount(), ofType(), onPage(), contentSegments(), fromArray().
SegmentSegmentType $type, string $content, BoundingBox $boundingBox, int $pageNumber, float $confidence = 1.0, list<Segment> $children = []Classified page region; children nest recursivelyDoes not throwisHighConfidence() threshold is 0.8; descendantCount() is recursive.
SegmentTypestring-backed enumTwelve cases, heading through unknownDoes not throwisContent() and isStructural() partition the cases.
FormDatalist<FormField> $fields, DocumentInfo $documentInfo, float $processingTimeMs = 0.0Whole-document form-extraction resultJsonException from toJson() onlyfield(), dataFields(), filledCount(), toKeyValueMap(), fromArray().
FormFieldstring $name, FormFieldType $type, plus six optional fieldsSingle extracted form fieldDoes not throwisFilled() is value !== ''.
FormFieldTypestring-backed enumEight cases, text through buttonDoes not throwisDataField() is false for button and signature.
interface InteropResultInterface extends JsonSerializable
public const SCHEMA_VERSION = '1.0';
public function toArray(): array;
public function toJson(int $flags = 0): string;
final class SchemaLock
public static function verify(): bool
public static function expectedHash(): string
public static function actualHash(): string
final readonly class ExtractedText implements InteropResultInterface
public function __construct(
public array $pages,
public DocumentInfo $documentInfo,
public float $processingTimeMs = 0.0,
)
public function page(int $pageNumber): ?ExtractedPage
public function totalBlockCount(): int
public function plainText(): string
public static function fromArray(array $data): self
final readonly class DocumentSegmentation implements InteropResultInterface
public function __construct(
public array $segments,
public DocumentInfo $documentInfo,
public float $processingTimeMs = 0.0,
)
public function ofType(SegmentType $type): array
public function onPage(int $pageNumber): array
public function contentSegments(): array
public static function fromArray(array $data): self
final readonly class FormData implements InteropResultInterface
public function __construct(
public array $fields,
public DocumentInfo $documentInfo,
public float $processingTimeMs = 0.0,
)
public function field(string $name): ?FormField
public function dataFields(): array
public function toKeyValueMap(): array
public static function fromArray(array $data): self
  • Versioned envelope. Every top-level DTO (ExtractedText, DocumentSegmentation, FormData) implements InteropResultInterface. Its toArray() output always carries schema_version ('1.0') and a type discriminator: extracted_text, document_segmentation, or form_data.
  • JSON encoding. toJson() delegates to json_encode with JSON_THROW_ON_ERROR OR-ed into the caller’s flags. jsonSerialize() delegates to toArray(), so json_encode($dto) produces the same shape.
  • Deterministic serialization. Key order and shape are fixed by the DTO. Segment::toArray() omits the children key when empty; FormField::toArray() omits bounding_box when it is null. Consumers must treat both keys as optional.
  • Round trip. Each DTO exposes a static fromArray() that accepts a decoded JSON object. Fields are type-guarded at this cross-process boundary: absent or mistyped values fall back to documented defaults instead of throwing.
  • Enum fallbacks. An unrecognized type string maps to SegmentType::Unknown in Segment::fromArray() and to FormFieldType::Text in FormField::fromArray().
  • Coordinates. BoundingBox coordinates are PDF user-space units (points, 1/72 inch) with the origin at the bottom-left corner of the page. Page numbers are one-based throughout.
  • Plain-text joins. ExtractedPage::plainText() joins block content with single spaces. ExtractedText::plainText() joins pages with blank lines ("\n\n").
  • Segmentation queries. ofType(), onPage(), and contentSegments() filter top-level segments only and return re-indexed lists. contentSegments() selects the types where SegmentType::isContent() is true: heading, sub_heading, paragraph, table, list, code.
  • Form queries. FormData::dataFields() and toKeyValueMap() exclude non-data field types (button, signature). filledCount() counts fields whose value is a non-empty string.
  • Schema lock. SchemaLock::verify() reads the V1 schema.json shipped with the package, normalizes CRLF to LF, hashes with SHA-256, and compares against the locked constant in constant time. CI uses it to block silent schema drift; the lock value changes only with a deliberate versioned schema change.
  • Versioning policy. The V1 surface is an explicit public contract. Additive changes bump the schema version; breaking changes require a new major version.
  • The only throwing member on this surface is toJson(): JsonException when the array is not encodable, for example invalid UTF-8 in extracted content.
  • SchemaLock::verify() returns false — never throws — when the schema file is missing, unreadable, or modified. Compare expectedHash() with actualHash() to distinguish drift from I/O failure.
  • fromArray() fallbacks are silent by design. A mistyped page_number becomes 1; a mistyped confidence becomes the default. Validate upstream when fabricated defaults are unacceptable.
  • Numeric-string coercion is asymmetric. PageInfo::fromArray() accepts numeric strings for its int and float fields; Segment and TextBlock accept only int or float for confidence and font_size.
  • BoundingBox::fromArray() requires all four keys per its documented array shape. The DTOs that embed it substitute a zero box (or null for FormField) when the wrapper key is absent.
  • ExtractedPage::fromArray() substitutes a fallback page_info of page 1 at 595 × 842 points when the key is missing or mistyped.
  • FormField::fromArray() accepts only strict booleans for required and read_only; truthy strings and integers map to false.
  • Segment children recurse without a depth limit. Extremely deep nesting is bounded only by PHP’s memory and stack limits.
  • No cryptographic key or signature operation occurs in this module. SchemaLock uses SHA-256 solely as a file-integrity checksum, so there is no FIPS-mode-specific behavior.

Interop V1 is a NextPDF-owned, versioned wire contract. It does not implement an external standard, so there is no normative citation table. BoundingBox semantics align with the PDF user-space coordinate model that the producing Core subsystems use.

  • Branch on schema_version in consumers. Treat additive keys as compatible; reject unknown major versions explicitly.
  • Run SchemaLock::verify() in CI. On failure, log expectedHash() and actualHash() and require a deliberate versioned schema change, never an in-place edit.
  • For cross-process round trips, decode with associative arrays (json_decode($json, true)) and feed the result to the matching fromArray().
  • All DTOs are final and readonly. Extend by composition; derive new views from the public fields.
  • toKeyValueMap() flattens data-bearing fields only. Read signature fields directly from FormData::$fields when their presence matters.
  • Reuse is safe: the DTOs hold no mutable state and no resources, so they can be cached, shared across requests, and serialized repeatedly.

This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.