Przejdź do głównej zawartości

Tworzenie rozszerzeń: przegląd publicznego SPI

NextPDF udostępnia niewielki, celowo dobrany zestaw publicznych kontraktów w przestrzeniach nazw NextPDF\Contracts oraz NextPDF\Event. Zaimplementuj je, aby dodawać czcionki, przechwytywać tekst, obserwować cykl życia dokumentu lub dostarczyć własne zaplecze do podpisywania bez rozgałęziania silnika.

Okno terminala
composer require nextpdf/core:^3

NextPDF oddziela swój publiczny interfejs dostawcy usług (SPI) od kodu wewnętrznego. SPI to zbiór typów, które można implementować lub obserwować. Wszystko pozostałe jest prywatne i może ulec zmianie bez powiadomienia.

Publiczne SPI występuje w trzech formach:

  • Kontrakty rejestrów. Usługi działające przez czas życia procesu, które uzupełniasz przed utworzeniem dokumentów; głównymi przykładami są FontRegistryInterface oraz ImageRegistryInterface. Zarejestruj zasoby, a silnik je odczyta.
  • Kontrakty strategii. Punkty zaczepienia o pojedynczym zadaniu, które silnik wywołuje podczas renderowania. TextPreprocessorInterface obsługuje przechwytywanie tekstu na etapie układu, a HtmlSecurityPolicyInterface kontroluje dostęp do funkcji Hypertext Markup Language (HTML). Dostarczasz zachowanie, a silnik je wywołuje.
  • Kontrakty podpisywania. Zaplecza kryptograficzne. SignerInterface, HsmSignerInterface oraz DeferredSignerInterface pozwalają zapewnić przechowywanie klucza i tworzenie podpisu. Silnik buduje strukturę Cryptographic Message Syntax (CMS), a Twój kod przechowuje klucz.

Za obserwację odpowiada odrębny system zdarzeń w przestrzeni nazw NextPDF\Event, zgodny z PHP Standard Recommendation 14 (PSR-14). Zdarzenia cyklu życia pozwalają reagować na utworzenie dokumentu, nowe strony, ładowanie czcionek, podpisywanie i zapis. Nie zmieniają zachowania silnika.

Każdy kontrakt zawiera w źródłowym PHPDoc znacznik @stability: stable, experimental lub deprecated. Znacznik oraz obietnica zgodności wstecznej dla danego kontraktu informują, jakiego zakresu zmian można się spodziewać. Pełną politykę znajdziesz w temacie Reguły stabilności SPI.

FunkcjonalnośćKontrakt publicznyStabilność
Rejestracja i wyszukiwanie czcionekNextPDF\Contracts\FontRegistryInterfacestabilny (od 1.7.0)
Buforowanie i dekodowanie obrazówNextPDF\Contracts\ImageRegistryInterfacestabilny (od 2.0.0)
Przechwytywanie tekstu na etapie układuNextPDF\Contracts\TextPreprocessorInterfacestabilny (od 1.9.0)
Kontrola dostępu do funkcji HTMLNextPDF\Contracts\HtmlSecurityPolicyInterfacestabilny (od 3.1.0)
Powiązanie fabryki dokumentówNextPDF\Contracts\DocumentFactoryInterfacestabilny (od 1.7.0)
Podpisywanie synchroniczneNextPDF\Contracts\SignerInterfacestabilny (od 1.0.0)
Podpisywanie wsparte sprzętowoNextPDF\Contracts\HsmSignerInterfacestabilny (od 1.0.0)
Podpisywanie odroczone i wsadoweNextPDF\Contracts\DeferredSignerInterfaceeksperymentalny (od 3.0.0)
Znakowanie czasem RFC 3161NextPDF\Contracts\TimestampProviderInterfaceeksperymentalny (od 3.0.0)
Obserwacja cyklu życiaNextPDF\Event\* (zgodne z PSR-14)stabilny dyspozytor; eksperymentalne ładunki

Następujące typy są wewnętrzne. Nie importuj ich, nie dziedzicz po nich ani nie uzależniaj od nich kodu:

  • Każda klasa spoza przestrzeni nazw NextPDF\Contracts oraz NextPDF\Event, chyba że jej PHPDoc zawiera znacznik @stability.
  • Konkretne implementacje silnika, w tym parser HTML, moduł zapisu, potok układu i moduł tworzenia podzbiorów czcionek.
  • Pakiety NextPDF Pro oraz NextPDF Enterprise. Ich klasy wewnętrzne nie są częścią powierzchni open source. Jeśli płatna edycja dostarcza implementację SPI, korzystaj z publicznego kontraktu, a nie z jej typu wewnętrznego.

Wygenerowana mapa kontraktów jest miarodajna i odtwarzana ze źródła dla każdego wydania. Traktuj znacznik PHPDoc @stability w każdym pliku interfejsu jako jedyne źródło prawdy. Tabelę powyżej traktuj jako pomocniczą.

Zarejestruj czcionkę, a następnie nasłuchuj zdarzenia jej załadowania. Oba kroki korzystają wyłącznie z typów publicznych.

<?php
declare(strict_types=1);
use NextPDF\Contracts\FontRegistryInterface;
use NextPDF\Event\Content\FontLoadedEvent;
use NextPDF\Event\EventDispatcher;
use NextPDF\Event\ListenerProvider;
/** @var FontRegistryInterface $fonts */
$fonts->register('/srv/fonts/Inter-Regular.ttf', 'Inter');
$listeners = new ListenerProvider();
$listeners->addListener(
FontLoadedEvent::class,
static function (FontLoadedEvent $event): void {
\error_log("Font loaded: {$event->family} {$event->style}");
},
);
$dispatcher = new EventDispatcher($listeners);

W długotrwałym procesie roboczym zbuduj rejestry raz przy starcie, zablokuj je i wstrzyknij współdzielony dyspozytor za pośrednictwem fabryki dokumentów.

<?php
declare(strict_types=1);
use NextPDF\Contracts\DocumentFactoryInterface;
use NextPDF\Contracts\FontRegistryInterface;
use NextPDF\Event\EventDispatcher;
use NextPDF\Event\ListenerProvider;
use Psr\Log\LoggerInterface;
final class DocumentBootstrap
{
public function __construct(
private readonly FontRegistryInterface $fonts,
private readonly DocumentFactoryInterface $factory,
private readonly LoggerInterface $logger,
) {}
public function warmup(): EventDispatcher
{
$this->fonts->warmup([
'/srv/fonts/Inter-Regular.ttf',
'/srv/fonts/Inter-Bold.ttf',
]);
$this->fonts->lock();
$listeners = new ListenerProvider();
$listeners->addListener(
\NextPDF\Event\Security\SignatureAppliedEvent::class,
fn (object $event): mixed => $this->logger->info('Signature applied'),
);
return new EventDispatcher($listeners);
}
}
  • Blokada rejestru. Po wywołaniu FontRegistryInterface::lock() metody zmieniające stan zgłaszają wyjątek LogicException. Blokuj rejestr dopiero po zakończeniu rozgrzewki.
  • Niezgodność stabilności. Kontrakt experimental może ulec zmianie w wydaniu pomocniczym. Sprawdź deklarowaną stabilność, zanim oprzesz na nim kod w środowisku produkcyjnym.
  • Dyscyplina przestrzeni nazw. Typ spoza NextPDF\Contracts lub NextPDF\Event bez znacznika @stability jest wewnętrzny, nawet jeśli technicznie ma widoczność public.

Nieużywane SPI nie generuje żadnego narzutu. Jeśli z klasą zdarzenia nie jest powiązany żaden nasłuchiwacz, dyspozytor zdarzeń zwraca sterowanie natychmiast po pojedynczym sprawdzeniu hasListeners(). Rejestry przechowują proste dane PHP i obsługują rozgrzewkę przy starcie, aby rozłożyć koszt opóźnienia pierwszego żądania.

Kontrakty podpisywania to powierzchnia wrażliwa pod względem bezpieczeństwa. HsmSignerInterface wymaga, aby klucz prywatny nigdy nie opuścił granicy sprzętu. Implementacja musi spełniać ten wymóg. Kontrakt dla zewnętrznego zaplecza podpisującego oraz jego model zagrożeń opisuje kontrakt dostawcy systemu zarządzania kluczami (KMS).

Ta strona przeglądowa nie formułuje żadnych twierdzeń normatywnych. Zgodność dla poszczególnych kontraktów, w tym PDF Advanced Electronic Signatures (PAdES) i zarządzanie kluczami, jest udokumentowana na odpowiednich stronach SPI.

NextPDF Pro oraz NextPDF Enterprise dostarczają produkcyjne implementacje kilku kontraktów podpisywania i weryfikacji, w tym podpisywanie wsparte systemem zarządzania kluczami. Opierasz kod na publicznym kontrakcie, a edycja dostarcza implementację, dzięki czemu Twój kod pozostaje przenośny między edycjami.

Słownik definiuje pojęcia SPI, punkt rozszerzenia, znacznik stabilności oraz obietnica zgodności wstecznej; ich kanoniczne definicje znajdziesz w opublikowanym słowniku.