Salta ai contenuti

Risoluzione dei problemi di compat-legacy

La maggior parte dei problemi di migrazione rientra in un numero ristretto di schemi ricorrenti. Per ciascuno di quelli elencati di seguito sono riportati sintomo, causa e correzione. In caso di dubbi su un metodo specifico, consultare /integrations/tcpdf-compat/method-coverage/ e la matrice autorevole nel repository docs/TCPDF_COVERAGE.md.

Il processo si interrompeva su un errore PDF; ora viene propagata un’eccezione

Sezione intitolata “Il processo si interrompeva su un errore PDF; ora viene propagata un’eccezione”

Sintomo. Il codice che in precedenza si arrestava in caso di rendering non riuscito ora solleva una RuntimeException non gestita, causando l’errore della richiesta o del job.

Causa. Le chiamate Error() del TCPDF legacy invocano die(). L’adattatore solleva invece una RuntimeException: è una scelta progettuale, così gli errori restano osservabili.

Correzione. Racchiudere i punti di ingresso del rendering in try/catch e mappare l’eccezione sul proprio contratto di errore. Non ripristinare il comportamento di die(). Vedere /integrations/tcpdf-compat/production-usage/ § Gestione degli errori.

new \TCPDF() continua a risolversi nella libreria TCPDF reale

Sezione intitolata “new \TCPDF() continua a risolversi nella libreria TCPDF reale”

Sintomo. LegacyBootstrap::enableAliases() è stato abilitato, ma l’output ha ancora l’aspetto del TCPDF legacy oppure il comportamento non è cambiato.

Causa. enableAliases() registra un alias solo se non esiste già una classe con quel nome. Se tecnickcom/tcpdf è ancora caricabile tramite autoload e il suo \TCPDF viene caricato per primo, l’alias viene ignorato e il codice continua a usare il TCPDF legacy.

Correzione. Durante la migrazione, preferire import espliciti in ciascun file (use NextPDF\Compat\Tcpdf\TCPDF;) in modo che ogni punto di chiamata sia inequivocabile. Rimuovere tecnickcom/tcpdf una volta superato l’audit (vedere /integrations/tcpdf-compat/migration/ Fase 5). Non eseguire entrambe le librerie nello stesso processo con gli alias globali abilitati.

Un metodo “funziona”, ma il parametro che ho passato viene ignorato

Sezione intitolata “Un metodo “funziona”, ma il parametro che ho passato viene ignorato”

Sintomo. Una chiamata va a buon fine e produce un PDF, ma un’opzione passata (link di un’immagine, allineamento, DPI, colore dei segnalibri, …) non ha alcun effetto.

Causa. Il metodo rientra tra quelli che ignorano silenziosamente alcuni parametri. Accetta il parametro per compatibilità a livello di sorgente e poi lo scarta. È un comportamento documentato, non un difetto: vedere /integrations/tcpdf-compat/method-coverage/ §2.

Correzione. Eseguire un audit in modalità strict per individuare ogni chiamata di questo tipo:

examples/troubleshoot-strict.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException;
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();
$pdf->setStrictMode(true);
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 12);
try {
$pdf->Image('logo.png', 10, 10, 50, 0, '', 'https://example.com');
} catch (TcpdfNotImplementedException $e) {
// Message lists every ignored parameter and a migration hint.
echo $e->getMessage(), "\n";
}

Quindi rimuovere il parametro oppure riesprimerlo tramite l’API moderna ($pdf->getDocument()), come in /integrations/tcpdf-compat/migration/ Fase 4.

Sintomo. Il codice che si dirama in base al valore restituito da MultiCell() (per esempio, per calcolare l’altezza utilizzata o il numero di righe) si comporta in modo errato.

Causa. Il MultiCell() dell’adattatore restituisce il segnaposto di compatibilità 1, non il numero di cell/line renderizzate. Analogamente, Write() restituisce 0.

Correzione. Non diramare in base a questi valori restituiti. Se serve l’altezza renderizzata, calcolarla a partire da getStringHeight() / getNumLines(), oppure spostare quella logica sull’API moderna.

setPDFVersion('1.4') non ha prodotto un file PDF 1.4

Sezione intitolata “setPDFVersion('1.4') non ha prodotto un file PDF 1.4”

Sintomo. È stata richiesta una versione PDF meno recente, ma l’output resta PDF 2.0.

Causa. L’output è sempre PDF 2.0 (ISO 32000-2). setPDFVersion() rientra nell’insieme dei metodi non applicabili; l’adattatore emette un avviso e prosegue.

Correzione. Rimuovere la chiamata. Se un consumatore a valle richiede una versione PDF meno recente, gestire separatamente quel vincolo del consumatore; l’adattatore non può effettuare il down-targeting.

setSignature() non ha avuto alcun effetto — il PDF non è firmato

Sezione intitolata “setSignature() non ha avuto alcun effetto — il PDF non è firmato”

Sintomo. setSignature() è stato chiamato con un certificato, ma il PDF di output non contiene alcuna firma.

Causa. setSignature() non è implementato sul motore core tramite questo adattatore. In modalità predefinita è un’operazione nulla; in modalità strict solleva un’eccezione.

Correzione. La firma richiede un’edizione commerciale di NextPDF e l’API di firma moderna. Vedere /integrations/tcpdf-compat/security-and-operations/ § Firme digitali. Non aspettarsi che la chiamata legacy setSignature() firmi alcunché.

Output() ha corrotto la mia risposta HTTP o l’output del worker

Sezione intitolata “Output() ha corrotto la mia risposta HTTP o l’output del worker”

Sintomo. Dati binari illeggibili in una risposta HTTP oppure un log del worker contaminato da byte PDF.

Causa. È stata usata una destinazione di output che scrive sul percorso di output (I/D) in un contesto in cui la risposta è gestita dall’applicazione. L’adattatore non riversa nel buffer come fa il TCPDF legacy, ma I/D guidano comunque l’output del motore.

Correzione. Nei worker e negli handler sotto il proprio controllo, usare Output($path, 'F') per scrivere un file oppure Output($name, 'S') per ottenere i byte ed emetterli direttamente. La mappatura delle destinazioni (senza distinzione tra maiuscole e minuscole, con spazi rimossi) è verificata in tests/Unit/Compat/Tcpdf/Bridge/OutputBridgeTest.php:

CodiceRestituisceEffetto collaterale
Sbyte PDF (%PDF…)nessuno
Fstringa vuotascrive un file
Ecorpo MIME base64nessuno
FI / FDstringa vuotascrive un file, poi output del motore
I / D / sconosciutostringa vuotaoutput del motore (inline/download)

Le asserzioni PDF byte-per-byte falliscono dopo il passaggio

Sezione intitolata “Le asserzioni PDF byte-per-byte falliscono dopo il passaggio”

Sintomo. I test di snapshot che confrontano i byte PDF grezzi falliscono ovunque.

Causa. Il motore è un’implementazione PDF 2.0 indipendente. L’output visibile è compatibile per i metodi delegati, ma i byte differiscono. È un comportamento previsto.

Correzione. Ridefinire la baseline per effettuare le asserzioni sul contenuto renderizzato (testo estratto), sulla struttura (numero di pagine, dimensione delle pagine) o su un controllo rapido (str_starts_with($bytes, '%PDF')). Vedere /integrations/tcpdf-compat/migration/ Fase 4.

Una costante legacy K_* / PDF_* ha il valore sbagliato

Sezione intitolata “Una costante legacy K_* / PDF_* ha il valore sbagliato”

Sintomo. Un percorso personalizzato o un valore predefinito impostato tramite una costante non ha effetto.

Causa. L’adattatore definisce automaticamente una costante solo se non è già definita, e lo fa alla prima costruzione. Se la propria define() viene eseguita dopo la costruzione del primo adattatore, il valore predefinito dell’adattatore ha già prevalso.

Correzione. Definire tutte le costanti personalizzate K_* / PDF_* nel proprio bootstrap, prima che venga creata qualsiasi istanza dell’adattatore. Vedere /integrations/tcpdf-compat/configuration/ § Ordine di risoluzione della configurazione.

Mancata corrispondenza della versione del motore durante la costruzione

Sezione intitolata “Mancata corrispondenza della versione del motore durante la costruzione”

Sintomo. La costruzione fallisce o mostra un comportamento inatteso dopo l’aggiornamento di una dipendenza.

Causa. L’adattatore richiede nextpdf/core ^3.0. Una versione del core risolta al di fuori di tale intervallo non è supportata.

Correzione. Eseguire composer show nextpdf/core e bloccare il motore a ^3.0. Vedere /integrations/tcpdf-compat/install/ § Verificare la versione del motore.

DomandaDove cercare
Che cosa fa effettivamente il metodo X qui?/integrations/tcpdf-compat/method-coverage/, docs/TCPDF_COVERAGE.md
Quali chiamate perdono parametri?Audit in modalità strict (questa pagina; /integrations/tcpdf-compat/migration/)
Perché il processo non si è arrestato su un errore?/integrations/tcpdf-compat/security-and-operations/ § Comportamenti rafforzati
Perché l’output non è firmato / non è PDF/A?/integrations/tcpdf-compat/security-and-operations/
Conflitto tra alias e import esplicitoQuesta pagina; /integrations/tcpdf-compat/boot-and-discovery/
  • /integrations/tcpdf-compat/migration/ — migrazione a fasi che previene la maggior parte dei problemi sopra elencati
  • /integrations/tcpdf-compat/method-coverage/ — riferimento del comportamento per ciascun metodo
  • /integrations/tcpdf-compat/boot-and-discovery/ — registrazione degli alias ed evitamento dei conflitti
  • docs/TCPDF_COVERAGE.md — matrice di copertura autorevole