Contrats : 41 interfaces publiques (SPI)
NextPDF\Contracts est l’interface publique de fournisseur de services (SPI) : 41 interfaces et enums sous src/Contracts/ qui portent une balise @stability explicite et une promesse de rétrocompatibilité. Les packages d’extension, les ponts de framework et les éditions Pro et Enterprise s’appuient sur ces types, jamais sur des classes concrètes.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »Le moteur distingue deux surfaces. Les classes concrètes sous src/Core/, src/Html/ et src/Writer/ ne s’accompagnent d’aucune promesse de compatibilité. Elles peuvent changer librement d’une version mineure à l’autre. L’espace de noms Contracts fonctionne à l’inverse. C’est un ensemble soigneusement sélectionné de types dont les signatures sont figées au niveau de stabilité qu’ils déclarent. Tout ce qui se trouve hors du moteur dépend de cet espace de noms, et de rien de plus profond. Cela inclut les ponts Laravel, Symfony et CodeIgniter, le shim compat-tcpdf, NextPDF Server, ainsi que les éditions Pro et Enterprise.
Chaque contrat déclare l’un des quatre niveaux dans son PHPDoc. Un contrat stable ne permet aucune modification incompatible dans une version mineure ou correctrice. Les nouvelles méthodes n’y apparaissent qu’avec des implémentations par défaut. Un contrat experimental peut changer dans une version mineure, avec un avis de dépréciation. Un contrat deprecated nomme son remplaçant. Quelques-uns ne sont que des contrats, comme StreamingWriterInterface et CursorInterface. Le type est publié et figé, mais aucune implémentation de production n’est encore fournie.
La liste des niveaux qui fait autorité est docs/extension-points.json (manifeste version 3.0.0, 67 points publiés répartis entre Contracts et Event). Un test vérifiable automatiquement, tests/Unit/Contracts/StabilityContractTest.php, lit ce manifeste. Il fait échouer la build dans cinq cas. Le premier est un type listé qui manque. Le deuxième est une nature obtenue par réflexion qui contredit le manifeste. Le troisième est une balise PHPDoc @stability qui s’écarte du manifeste. Le quatrième est un contrat sous src/Contracts/ qui est absent du manifeste. Le cinquième est un type @internal qui y apparaît. La surface de contrat ne peut pas dériver sans être détectée.
Les contrats se répartissent en neuf domaines. Chacun a sa page dédiée : construction de documents, signature, encodage de codes-barres, typographie, politique de sécurité, extraction, observabilité et streaming. Cette répartition reflète la façon dont un intégrateur adopte le moteur. Tu t’appuies sur le contrat de document pour générer des PDF. Tu t’appuies sur les contrats de signature pour ajouter une signature. Tu t’appuies sur les contrats de politique de sécurité pour contraindre du HTML non fiable.
La résolution d’une implémentation optionnelle suit un seul et même schéma dans tout le moteur. Le cœur vérifie la présence d’une classe concrète avec class_exists() et la convertit vers le contrat. LtvManagerInterface et PdfAManagerInterface résolvent leurs implémentations Pro de cette manière. Le cœur reste donc Apache-2.0 sans dépendance dure envers du code commercial.
Surface de l’API
Section intitulée « Surface de l’API »| Contrat | Nature | Stabilité | Depuis | Domaine |
|---|---|---|---|---|
PdfDocumentInterface | interface | stable | 1.0.0 | document |
DocumentFactoryInterface | interface | stable | 1.7.0 | document |
ResettableService | interface | stable | 1.7.0 | document |
OutputDestination | enum | stable | 1.0.0 | document |
Orientation | enum | stable | 1.0.0 | document |
Alignment | enum | stable | 1.0.0 | document |
SignerInterface | interface | stable | 1.0.0 | signature |
HsmSignerInterface | interface | stable | 1.0.0 | signature |
DeferredSignerInterface | interface | experimental | 3.0.0 | signature |
TimestampProviderInterface | interface | experimental | 3.0.0 | signature |
LtvManagerInterface | interface | stable | 1.10.0 | signature |
CryptoPolicyInterface | interface | stable | 1.9.0 | signature |
Barcode1DEncoderInterface | interface | stable | 1.0.0 | code-barres |
Barcode2DEncoderInterface | interface | stable | 1.0.0 | code-barres |
BarcodeEncoderInterface | interface | stable | 3.0.0 | code-barres |
Gs1DataParserInterface | interface | stable | 1.0.0 | code-barres |
FontRegistryInterface | interface | stable | 1.7.0 | typographie |
TextPreprocessorInterface | interface | stable | 1.9.0 | typographie |
HtmlSecurityPolicyInterface | interface | stable | 3.1.0 | politique de sécurité |
ExternalResourcePolicyInterface | interface | stable | 4.0.0 | politique de sécurité |
InspectorInterface | interface | experimental | 2.2.0 | extraction |
EmbeddingServiceInterface | interface | experimental | 2.1.0 | extraction |
VectorIndexInterface | interface | experimental | 2.1.0 | extraction |
JobNotificationInterface | interface | experimental | 2.2.0 | observabilité |
SpectrumInterface | interface | experimental | 2.1.0 | observabilité |
StreamingWriterInterface | interface | experimental | 3.1.0 | streaming |
CursorInterface | interface | experimental | 3.1.0 | streaming |
Le tableau liste les contrats principaux. Les autres types — les DTO objets-valeur (TextSegment, TextPreprocessResult), le sous-espace de noms EInvoice, les enums de comportement (DegradationPolicy, UnderlineStyle) et les contrats d’import (ImportedFormObjectInterface, EmbeddedPdfObjectInterface, ChromeRenderResultInterface) — sont documentés sur les pages de domaine sous Voir aussi. La liste complète et lisible par la machine est docs/extension-points.json, répliquée dans .ai/contracts-map.md.
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Hello World');$doc->addPage();$doc->setFont('helvetica', '', 24);$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);$doc->save(__DIR__ . '/output/01-hello-world.pdf');Document::createStandalone() renvoie un Document concret qui satisfait PdfDocumentInterface. Dans tes propres services, utilise l’interface comme type-hint afin que les éléments internes du moteur restent interchangeables.
Exemple de code — Production
Section intitulée « Exemple de code — Production »<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Core\PdfFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\FontRegistry;
// Created once at process boot in a RoadRunner/Swoole/Octane worker.$fontRegistry = new FontRegistry();$imageRegistry = new ImageRegistry(maxCacheBytes: 50 * 1024 * 1024);$documentFactory = new DocumentFactory($fontRegistry, $imageRegistry);
$factory = PdfFactory::new() ->withCompress(true) ->withDocumentFactory($documentFactory);
for ($request = 1; $request <= 3; $request++) { $doc = $factory->create(); $doc->setTitle("Worker Request #{$request}"); $doc->addPage(); $doc->setFont('helvetica', 'B', 16); $doc->cell(0, 12, "Worker Request #{$request}", newLine: true); $doc->save(__DIR__ . "/output/14-worker-request-{$request}.pdf");}DocumentFactory implémente DocumentFactoryInterface. Elle conserve des singletons FontRegistryInterface et ImageRegistryInterface pendant toute la durée de vie du processus et les injecte dans chaque Document jetable, si bien qu’un worker analyse chaque police une seule fois sur des milliers de requêtes.
Cas limites & pièges
Section intitulée « Cas limites & pièges »- Un type qui n’existe que comme contrat compile, mais n’a aucun support à l’exécution. Un
newcontreStreamingWriterInterfaceouCursorInterfacene peut pas réussir, car aucune classe ne les implémente encore. Traite-les comme une API déclarée à l’avance. - La balise PHPDoc
@stabilityest la source de vérité pour un type donné.docs/extension-points.jsonest la source de vérité pour l’ensemble. Quand ils se contredisent,StabilityContractTestéchoue — ne masque pas le désaccord en modifiant l’un des deux côtés. experimentalne signifie pas instable en pratique ; cela veut dire que la promesse de compatibilité est plus faible. Lis le champbc_promisede chaque contrat dans.ai/contracts-map.mdavant de t’y lier.- Une classe
@internaln’est jamais un contrat, même si d’autres packages peuvent techniquement la référencer. Le test de stabilité rejette tout type@internalqui apparaît dans le manifeste. - Ajouter une méthode à une interface
stableest une modification incompatible pour ceux qui l’implémentent, sauf si la méthode est livrée avec une implémentation par défaut. Le moteur ajoute des capacités au moyen de nouvelles interfaces, pas en élargissant celles qui existent déjà.
Performance
Section intitulée « Performance »Programmer contre Contracts n’ajoute aucun coût mesurable à l’exécution : un type-hint d’interface se résout au moment de l’édition de liens, pas à chaque appel. Le performance_budget de l’exemple de worker de cette page est de 1500 ms en temps réel et 64 Mo de pic sur trois documents. L’analyse des polices sur la première requête domine ce budget. Les requêtes suivantes réutilisent le cache du registre, avec un travail attribuable aux contrats qui descend à un nombre de millisecondes à un chiffre. Le modèle de coût est en O(1) par dispatch de contrat ; le travail réside dans l’implémentation concrète, documentée sur chaque page de domaine.
Notes de sécurité
Section intitulée « Notes de sécurité »La SPI est aussi une frontière de sécurité. HtmlSecurityPolicyInterface et ExternalResourcePolicyInterface sont des contrats deny-by-default (refus par défaut) qui contraignent ce que du HTML non fiable peut faire avant d’atteindre un renderer. CryptoPolicyInterface contrôle le choix de l’algorithme et de la force de clé pour la signature et le chiffrement. Comme ce sont des contrats, un intégrateur peut fournir une politique plus stricte sans forker le moteur. Appuie-toi sur le niveau stable pour toute politique pertinente pour la sécurité. Les contrats de politique experimental peuvent changer de forme entre des versions mineures. Les pages de domaine de la signature et de la politique de sécurité présentent le modèle de menace complet et les références normatives.
Conformité
Section intitulée « Conformité »Cette vue d’ensemble ne fait aucune affirmation normative directe ; chaque page de domaine fournit son propre bloc citations. Les contrats de signature correspondent à ISO 32000-2 §12.8 (signatures numériques) et ETSI EN 319 142 (références PAdES). Le gestionnaire PDF/A correspond à ISO 19005-4. Consulte les pages signature, politique de sécurité et extraction pour les tableaux de conformité au niveau des clauses.
Contexte commercial
Section intitulée « Contexte commercial »Les éditions Pro et Enterprise implémentent le code de production derrière plusieurs contrats du cœur : LtvManagerInterface (validation à long terme), PdfAManagerInterface (application de PDF/A), les signataires Hardware Security Module (HSM) et différés, les encodeurs de codes-barres, ainsi que les contrats d’embedding et d’index vectoriel. Le cœur publie et fige l’interface ; le package Premium livre l’implémentation. Cela garde le moteur open-source Apache-2.0 tout en offrant aux déploiements commerciaux une mise à niveau immédiate sans changement d’API.
Voir aussi
Section intitulée « Voir aussi »- Contracts / Document — contrats de document PDF, de factory et de registre.
- Contracts / Signing — contrats de signataire, HSM, horodatage et LTV.
- Contracts / Security Policy — contrats de politique crypto, HTML et de ressources.
- Contracts / Typography — contrats de registre de polices et de prétraitement du texte.
- Contracts / Extraction — contrats d’inspecteur, PDF/A, embedding et facture électronique.
- Core — les classes concrètes qui satisfont ces contrats.
- Event — la surface SPI événementielle publiée aux côtés de
Contracts.