Skip to content
getnextpdf.com

Pro edition

Classifier

NextPDF\Pro\Classifier assigns a document type (invoice, contract, report, and so on) and a detected language using deterministic heuristics over the document text and structure. It is rule-based, not a machine-learning model.

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 classifier classes are available whenever nextpdf/pro is installed.

Terminal window
composer require nextpdf/pro:^3

DocumentClassifier orchestrates three collaborators:

  • StructureAnalyzer inspects the PDF for page count, image and font counts, and form/signature fields, producing a StructureAnalysis.
  • HeuristicClassifier (the default ClassifierInterface) scores the text against per-type keyword dictionaries and applies structural heuristics (for example, short documents bias away from “report”), yielding a DocumentType and a confidence.
  • LanguageDetector identifies the language from character-trigram frequency profiles for ten languages, falling back to English below a confidence threshold.

classifyFromText() accepts already-extracted text (with optional raw PDF bytes for structure); classifyFromFile() accepts raw PDF bytes and extracts text by parsing the §9.4 text-showing operators directly.

The load-bearing decision is to classify with deterministic heuristics, not a machine-learning model. A rule-based pipeline is a pure function of its input: identical bytes always yield an identical type, confidence, and language, with no model drift and no network call. That determinism lets the result expose an explicit confidence, an isConfident() gate, and a per-type scores map, so the module shows how it decided rather than hiding the choice behind a model. Callers therefore route low-confidence documents to manual review by contract, and text too short to score falls back to en under the same fixed rule. The trade is deliberate: accuracy is bounded by fixed keyword and trigram profiles, in exchange for reproducibility, inspectability, and a classifier that runs entirely in-process.

Design background: An API that refuses to guess.

  • Input. Extracted text (classifyFromText) or raw PDF bytes (classifyFromFile). Empty input is valid and yields a low-confidence result, typically DocumentType::Other.
  • Output. A ClassificationResult with the DocumentType, a confidence in [0.0, 1.0], detected structural features, an ISO 639-1 language code, and metadata. isConfident(0.7) is the documented threshold helper.
  • Determinism. Classification and language detection are pure functions of the input — same input, same result, no randomness, no network.
  • Scope. Twelve document types and ten language profiles, both fixed in this release. Custom strategies can be supplied via ClassifierInterface.
TypeKindKey members
NextPDF\Pro\Classifier\DocumentClassifierfinal classstatic create(): self, classifyFromText(string $text, string $pdfData = ''): ClassificationResult, classifyFromFile(string $pdfData): ClassificationResult
NextPDF\Pro\Classifier\ClassifierInterfaceinterfaceclassify(string $text, StructureAnalysis $structure): ClassificationResult, supports(string $contentType): bool
NextPDF\Pro\Classifier\HeuristicClassifierfinal classimplements ClassifierInterface
NextPDF\Pro\Classifier\StructureAnalyzerfinal classanalyze(string $pdfData): StructureAnalysis
NextPDF\Pro\Classifier\LanguageDetectorfinal classdetect(string $text): string
NextPDF\Pro\Classifier\ClassificationResultfinal readonly classDocumentType $type, float $confidence, array $features, string $language, isConfident(float $threshold = 0.7): bool
NextPDF\Pro\Classifier\DocumentTypeenum12 cases (Invoice, Contract, Form, Report, Letter, Receipt, Legal, Medical, Financial, Technical, Academic, Other); label(): string
<?php
declare(strict_types=1);
use NextPDF\Pro\Classifier\DocumentClassifier;
$result = DocumentClassifier::create()
->classifyFromText('Invoice #4471 — Amount due: $1,200.00');
printf(
"%s (%.0f%% confidence), lang=%s\n",
$result->type->label(),
$result->confidence * 100,
$result->language,
);
<?php
declare(strict_types=1);
use NextPDF\Pro\Classifier\DocumentClassifier;
use NextPDF\Pro\Classifier\DocumentType;
function routeDocument(string $pdfBytes): string
{
$result = DocumentClassifier::create()->classifyFromFile($pdfBytes);
if (! $result->isConfident(0.7)) {
return 'manual-review';
}
return match ($result->type) {
DocumentType::Invoice, DocumentType::Receipt => 'accounts-payable',
DocumentType::Contract, DocumentType::Legal => 'legal-intake',
default => 'general-inbox',
};
}
  • Confidence is heuristic. Treat results below the threshold as “uncertain” and route to manual review, as the production sample does.
  • Language detection needs enough text; very short strings fall back to English by design.
  • classifyFromFile() uses bounded byte-level text extraction; heavily compressed or image-only PDFs reduce the text available to score.
  • Document-type and language sets are fixed in this release; extend classification by implementing ClassifierInterface, not by mutating built-in dictionaries.

Classification runs in-process with no network calls and no storage of the input. The result includes a DocumentType and language code, not the source text. If callers persist metadata, review it for incidental PII before storage.

The module emits no telemetry and logs no input. Callers adding logging should record only the resulting DocumentType and language code, never the classified text.

Keyword scoring and trigram counting are linear in text length. Structure analysis is linear in PDF byte length with a bounded decompression cap. See performance_budget.

classifyFromFile() parses untrusted PDF bytes with bounded scanning and a decompression-size cap to resist decompression-bomb input. No embedded scripts are executed.

ClaimSpec clauseStatus
Text recovered via Tj for file classificationISO 32000-2:2020 §9.4Verified (unit suite)
Text recovered via TJ for file classificationISO 32000-2:2020 §9.4Verified (unit suite)
Machine-learning / model-based classificationNot supported (heuristic only)

No Core equivalent exists for document classification or language detection.

This classifier is rule-based and deterministic. It performs no embedding, vector similarity, model inference, or semantic understanding. Those capabilities are not part of this module and are not implied by it.

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.