Office-Dokumente mit Gotenberg in PDF umwandeln
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Die Gotenberg-Brücke wandelt ein Office-Dokument in PDF um. Sie sendet das Dokument über HTTPS an einen Gotenberg-Microservice und gibt die PDF-Bytes zurück. Beschreiben Sie den Dienst mit einer unveränderlichen GotenbergConfig, binden Sie einen PSR-18-Client und PSR-17-Factories in die GotenbergBridge ein, prüfen Sie den Dienst mit einem Health-Check und konvertieren Sie anschließend entweder eine Datei von der Festplatte oder bereits im Speicher vorliegende Bytes. Diese Anleitung behandelt die Formaterkennung anhand der Dateiendung, die Health-Probe, den typisierten Fehlervertrag und die Übergabe an die NextPDF-Nachbearbeitung.
Voraussetzungen vorab:
- NextPDF Core und
nextpdf/gotenbergsind installiert. - Ein Gotenberg-Dienst ist über HTTPS erreichbar. Die Brücke lehnt eine reine
http://-URL ab, bevor auch nur eine Anfrage den Prozess verlässt. - Ein PSR-18-Client sowie PSR-17-Request- und -Stream-Factories sind installiert. Für DNS- und TLS-Pinning stellen Sie zusätzlich eine PSR-17-Response-Factory bereit.
- Die Eingabe liegt in einem der sechs erkannten Office-Formate vor:
.docx,.xlsx,.pptx,.odt,.odsoder.odp. Jede andere Endung weist die Brücke mit einemValueErrorzurück.
Dies ist eine How-to-Anleitung. Ein vollständiges, lauffähiges Programm finden Sie im Gotenberg-Quickstart.
Installation
Abschnitt betitelt „Installation“Installieren Sie die Brücke, einen PSR-18-Client und PSR-17-Factories.
composer require nextpdf/gotenberg guzzlehttp/guzzleBetreiben Sie einen über HTTPS erreichbaren Gotenberg-Dienst und beziehen Sie jeden Bearer-Token aus einem Secrets-Manager oder einem injizierten Umgebungswert. Die Brücke liest niemals Umgebungsvariablen aus und erstellt niemals einen HTTP-Client; beides stellen Sie bereit.
Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“GotenbergBridge::convertFile() nimmt einen Pfad von der Festplatte entgegen. Sie kanonisiert den Pfad, um Traversal zu verhindern, ordnet die Dateiendung einem unterstützten Format zu, prüft Größe und Dateinamen und sendet dann eine Multipart-Anfrage an <apiUrl>/forms/libreoffice/convert. convertString() macht dasselbe für Bytes, die bereits im Speicher vorliegen; sie nutzt den ursprünglichen Dateinamen, damit die Endung erkannt werden kann.
Die Formaterkennung erfolgt anhand der Dateiendung. Die Brücke ordnet .docx, .xlsx, .pptx, .odt, .ods und .odp ihren Formaten zu und lehnt alles andere mit einem ValueError ab, bevor irgendein Netzwerkverkehr stattfindet. Das Ergebnisobjekt stellt das erkannte Quellformat als Enum-Wert bereit.
Die Brücke ist ein einzelner synchroner HTTP-Roundtrip mit vorgeschalteter Validierung. Sie führt keine Wiederholungen aus, stellt nichts in eine Warteschlange, legt nichts im Cache ab und begrenzt keine Rate; das gehört in die aufrufende Anwendung. Behandeln Sie jede Umwandlung als Remote-Aufruf an einen Dienst, den Sie zwar betreiben, aber nicht im Prozess steuern, und planen Sie seine Latenz und seine Ausfälle ein.
Die Brücke macht Fehler als typisierte Exceptions sichtbar und gibt niemals ein unvollständiges oder unvalidiertes Ergebnis zurück:
- Ein anderer Status als
200, einContent-Typeohneapplication/pdfoder ein Body, der nicht mit%PDFbeginnt, löst jeweilsGotenbergConvertExceptionaus. Die Brücke gibt nur dann ein Ergebnis zurück, wenn alle drei Prüfungen erfolgreich sind. - Ein Fehler des PSR-18-Clients, einschließlich eines Netzwerkfehlers oder Timeouts, wird als
GotenbergConvertExceptiongekapselt, mit der ursprünglichen Exception als Ursache. - Validierungsfehler (Nicht-HTTPS-URL, private oder reservierte Adresse, zu große Eingabe, unsicherer Dateiname) lösen
RuntimeExceptionaus, bevor irgendein Netzwerkverkehr stattfindet. - Eine nicht erkannte Dateiendung löst
ValueErroraus, bevor irgendein Netzwerkverkehr stattfindet.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“// Configuration (final readonly):new GotenbergConfig( string $apiUrl, // required, must be HTTPS int $timeout = 30, // hard transfer timeout, seconds int $maxFileSize = 52_428_800, // 50 MiB string $apiKey = '', // #[SensitiveParameter]; Bearer when non-empty list<string> $pinnedPublicKeys = [], // sha256/<base64> list<string> $backupPublicKeys = [],)GotenbergConfig::fromArray(array $config): selfGotenbergConfig::isValid(): bool
// The bridge:new GotenbergBridge( GotenbergConfig $config, ClientInterface $httpClient, // PSR-18 RequestFactoryInterface $requestFactory, // PSR-17 StreamFactoryInterface $streamFactory, // PSR-17 ?LoggerInterface $logger = null, // PSR-3 ?HtmlSecurityPolicyInterface $htmlSecurityPolicy = null, ?ResponseFactoryInterface $responseFactory = null, // enables pinned transport)GotenbergBridge::isAvailable(): boolGotenbergBridge::convertFile(string $path): GotenbergConvertResultGotenbergBridge::convertString(string $bytes, string $originalFilename): GotenbergConvertResultDas Ergebnisobjekt stellt pdfData, das sourceFormat-Enum, isValid() (true, wenn der Body nicht leer ist und mit %PDF beginnt) und size() bereit. Die vollständige Feldreferenz, die Schlüsselzuordnung von fromArray() und die Regeln zur Transport-Auswahl finden Sie auf der Gotenberg-Konfigurationsseite, die unter „Siehe auch“ verlinkt ist.
Codebeispiel — Quick Start
Abschnitt betitelt „Codebeispiel — Quick Start“Beschreiben Sie den Dienst, binden Sie die Brücke ein, prüfen Sie sie und konvertieren Sie eine Datei.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Gotenberg\GotenbergBridge;use NextPDF\Gotenberg\GotenbergConfig;use NextPDF\Gotenberg\GotenbergConvertException;
$config = new GotenbergConfig( apiUrl: 'https://gotenberg.example.com', timeout: 60, apiKey: getenv('GOTENBERG_TOKEN') ?: '',);
$bridge = new GotenbergBridge( config: $config, httpClient: $httpClient, // your PSR-18 client requestFactory: $requestFactory, // your PSR-17 factory streamFactory: $streamFactory, // your PSR-17 factory responseFactory: $responseFactory, // enables the pinned transport);
// Probe before converting. The probe validates the URL with no network// traffic, then sends a HEAD to <apiUrl>/health.if (!$bridge->isAvailable()) { throw new RuntimeException('Gotenberg is not reachable.');}
try { $result = $bridge->convertFile('/path/to/report.docx');} catch (GotenbergConvertException $exception) { // Bad config, HTTP failure, non-200, wrong Content-Type, or non-PDF body. throw $exception;}
if (!$result->isValid()) { throw new RuntimeException('Result is not a valid PDF.');}
file_put_contents('/path/to/report.pdf', $result->pdfData);Die Klasse ist NextPDF\Gotenberg\GotenbergConfig (die obige Zeile verwendet genau den Namespace, den Ihr Code importieren muss). isAvailable() gibt false zurück und wirft bei einer leeren URL, einer Nicht-HTTPS-URL, einer Privatadress-URL sowie bei jedem Netzwerkfehler niemals eine Exception; ein Status unter 500 von /health bedeutet verfügbar.
Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Eine Produktionsumwandlung fängt jeden Fehlertyp einzeln ab, wiederholt nur unter den richtigen Bedingungen und begrenzt die Nebenläufigkeit auf Aufruferseite. Die folgende Reihenfolge der catch-Blöcke ist vollständig.
<?php
declare(strict_types=1);
use NextPDF\Gotenberg\GotenbergBridge;use NextPDF\Gotenberg\GotenbergConvertException;use Psr\Log\LoggerInterface;use RuntimeException;use ValueError;
final readonly class OfficeConverter{ public function __construct( private GotenbergBridge $bridge, private LoggerInterface $logger, ) {}
public function convert(string $path): string { try { $result = $this->bridge->convertFile($path); } catch (GotenbergConvertException $exception) { // Transport, non-200, wrong Content-Type, or non-PDF body. // Retry only on transport-level or 502/503/504 causes, with // bounded exponential backoff and jitter — never blind retries. $this->logger->error('gotenberg.convert.failed', [ 'path' => basename($path), 'exception' => $exception::class, ]); throw $exception; } catch (ValueError $exception) { // Extension is not one of the six recognized Office formats. $this->logger->warning('gotenberg.convert.unsupported_format', [ 'path' => basename($path), ]); throw $exception; } catch (RuntimeException $exception) { // Non-HTTPS URL, private address, oversized input, or unsafe name. $this->logger->error('gotenberg.convert.rejected', [ 'path' => basename($path), 'exception' => $exception::class, ]); throw $exception; }
if (!$result->isValid()) { throw new RuntimeException('Gotenberg returned an invalid PDF body.'); }
return $result->pdfData; }}Wiederholen Sie nur bei einer GotenbergConvertException auf Transportebene (einer gekapselten PSR-18-Client-Exception) und bei idempotenten Serverfehlern (502, 503, 504). Eine Antwort der 400er-Klasse bedeutet meist, dass die Eingabe fehlerhaft ist, sodass ein erneuter Versuch mit derselben Eingabe fehlschlägt. Begrenzen Sie die Gesamtzahl der Versuche und die gesamte Wall-Time. Begrenzen Sie die Zahl der laufenden Umwandlungen auf die Kapazität, die Ihr Gotenberg-Deployment trägt. Die Brücke selbst ist zustandslos und lässt sich gefahrlos aus vielen Workern verwenden, aber der Dienst hat eine begrenzte Umwandlungskapazität.
Randfälle & Stolperfallen
Abschnitt betitelt „Randfälle & Stolperfallen“- Die Formaterkennung erfolgt anhand der Dateiendung. Eine
.docx, die in.txtumbenannt wurde, wird mitValueErrorabgelehnt; eine.txt, die in.docxumbenannt wurde, wird an Gotenberg gesendet und schlägt dort fehl. Wenn Sie Uploads annehmen, vertrauen Sie dem tatsächlichen Dateiformat, nicht dem Namen. fromArray()ist bewusst tolerant. Bei fehlerhafter Eingabe setzt sie stillschweigend Standardwerte ein. Validieren Sie das Quell-Array im Boot-Pfad Ihrer Anwendung, damit eine fehlende URL frühzeitig als Konfigurationsfehler auftaucht und nicht erst als Exception bei jeder einzelnen Umwandlung.- Die Größenbeschränkung wird im Prozess durchgesetzt.
maxFileSize(Standard 50 MiB) wird geprüft, bevor die Anfrage gesendet wird, sodass eine zu große Datei niemals Dienstkapazität verbraucht. Senken Sie die Beschränkung auf das, was Ihre Dokumente benötigen; eine kleinere Beschränkung ist eine kostengünstigere Denial-of-Service-Abwehrmaßnahme. - Die Probe ist nicht kostenlos. Rufen Sie
isAvailable()von einem Readiness- oder Health-Endpunkt aus auf, nicht vor jeder Umwandlung. Die Probe bei jeder Umwandlung auszuführen, verdoppelt Ihre Anfragerate an den Dienst ohne jeden Nutzen. - Kein Caching im Prozess. Wenn dasselbe Dokument wiederholt umgewandelt wird, legen Sie das entstehende PDF in Ihrer Anwendung im Cache ab, mit einem Content-Hash der Eingabe als Schlüssel.
renderTimeMssetzen Sie selbst. Das Timing-Feld des Ergebnisses ist0.0, sofern Ihre Integration es nicht misst und setzt. Messen Sie den Aufruf selbst, wenn Sie den Wert brauchen.
Performance
Abschnitt betitelt „Performance“Für die Dauer der Anfrage belegt eine Umwandlung eine Verbindung und einen LibreOffice-Worker auf der Gotenberg-Seite; die Office-Umwandlung erfolgt nicht augenblicklich. Setzen Sie timeout anhand der gemessenen Umwandlungslatenz Ihrer realen Dokumente, mit Puffer. Halten Sie ihn unter jedem vorgelagerten Gateway-Timeout oder der PHP-max_execution_time, damit die Brücke zuerst abläuft und Sie eine typisierte Exception statt eines abgebrochenen Prozesses erhalten. Begrenzen Sie die Nebenläufigkeit mit einer Warteschlange, einem Semaphor oder einem Worker-Pool, der auf die Dienstkapazität dimensioniert ist. Es gibt keinen prozessinternen Cache; fügen Sie in Ihrer Anwendung einen hinzu, wenn Sie dieselbe Eingabe wiederholt umwandeln.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“- HTTPS- und Adressprüfung vor dem Senden. Die Brücke weist eine Nicht-HTTPS-URL und ein Ziel, das in einen privaten oder reservierten Adressraum auflöst, zurück, bevor auch nur eine Anfrage den Prozess verlässt. Jeder weitere Aufruf führt diese Validierung erneut aus, sodass Wiederholungen den SSRF-Schutz nicht umgehen können.
- Gepinnter Transport auf Anfrage. Wenn Sie eine Response-Factory und Pins bereitstellen (oder ein aufgelöster Satz von IP-Adressen vorliegt), bindet die Brücke die Verbindung an die aufgelösten Adressen, erzwingt SPKI-Pinning, prüft Peer und Host, wendet das Timeout an und deaktiviert das Folgen von Redirects. Richten Sie vor einer Zertifikatsrotation einen Backup-Pin ein.
- Vertrauen Sie nicht dem angegebenen Content-Type eines Uploads. Wenn Sie Benutzer-Uploads annehmen, validieren Sie den tatsächlichen Dateityp selbst; die Zuordnung von Endung zu Format ist eine Routing-Entscheidung, keine Echtheitsprüfung.
- Secrets werden maskiert und sind unveränderlich.
apiKeyträgt#[SensitiveParameter], und die Config istfinal readonly. Beziehen Sie den Token aus einem Secrets-Manager; committen Sie ihn niemals. Der protokollierte Umwandlungseintrag enthält die URL, den Dateinamen, das Format und die Inhaltslänge, jedoch niemals den Dateiinhalt oder den Token. - Schreiben Sie niemals einen leeren
catch-Block. Jedes Beispiel fängt den spezifischen Typ ab und protokolliert mit Kontext.
Das vollständige Sicherheits- und Deployment-Modell finden Sie auf der Gotenberg-Seite zu Sicherheit und Betrieb. Der PSR-18-Transportvertrag und der Hinweis, dem Content-Type nicht zu vertrauen, sind auf der vorgelagerten Seite zur Produktionsnutzung an ihre Klauseln gebunden.
Konformität
Abschnitt betitelt „Konformität“Diese Anleitung erhebt keinen eigenen normativen Standardanspruch. Das PSR-18-Transportverhalten der Brücke (ein Client wirft nur, wenn er eine Antwort nicht senden oder parsen kann; ein 4xx/5xx ist ein normaler Rückgabewert), der Hinweis zur Validierung von Datei-Uploads und das TLS-Pinning-Modell sind auf den vorgelagerten Gotenberg-Seiten zu Produktionsnutzung und Konfiguration an PSR-18, OWASP und RFC 7469 gebunden. Diese Cookbook-Seite beschreibt die Verwendung und überlässt die Zitate jenen Seiten. Die Brücke erzeugt PDF-Bytes und beendet dann ihre Arbeit. Signierung, PDF/A-Profile und Wasserzeichen sind Belange der NextPDF-Nachbearbeitung und gehören zur kommerziellen Edition, nicht zu dieser Brücke.
Siehe auch
Abschnitt betitelt „Siehe auch“- Ein generiertes PDF aus einem Controller zurückgeben — ein umgewandeltes PDF als HTTP-Antwort zurückgeben.
- Gotenberg-Quickstart — das vollständige, lauffähige Umwandlungsprogramm.
- Gotenberg-Konfiguration — jedes Feld, die
fromArray()-Zuordnung und die Transport-Auswahl. - Gotenberg-Produktionsnutzung — Secrets, Timeouts, Wiederholungen, Nebenläufigkeit und die Grenze zur Nachbearbeitung.