Ir al contenido

Migrar de mPDF a NextPDF

Esta guía traslada un código base basado en mPDF al núcleo de NextPDF. El verbo central de mPDF es WriteHTML(), que se asigna directamente a Document::writeHtml(). El trabajo de fondo consiste en mapear el array de configuración del constructor (mPDF configura todo mediante un único array asociativo que se pasa a new Mpdf([...])) y entender la diferencia en el manejo de fuentes. NextPDF y mPDF son motores independientes, así que un documento migrado es compatible con la salida de mPDF, no idéntico byte a byte a ella. Esta guía cubre el mapa de verbos, el mapa del array de configuración, la diferencia de fuentes, la diferencia de compatibilidad con CSS, las diferencias de comportamiento y una secuencia segura.

La matriz de compatibilidad con CSS es la autoridad sobre qué funciones de HTML/CSS están verificadas. Esta guía describe el comportamiento; no afirma equivalencia visual con mPDF.

Ventana de terminal
composer require nextpdf/core:^3

Mantén mpdf/mpdf instalado durante la transición. Elimínalo tras el cambio final (consulta la secuencia de migración segura).

El objeto Mpdf de mPDF es una gran fachada única. Se configura con un array del constructor, y WriteHTML() más los verbos de paginación (AddPage, SetHTMLHeader, SetHTMLFooter) controlan la salida. NextPDF separa la configuración en el objeto de valor inmutable NextPDF\Core\Config y procesa el contenido con Document::writeHtml(). No hay una cadena «mode» en el constructor. NextPDF analiza el HTML que pasas y luego emite el documento con save(), output() o getPdfData().

Fuentes: mPDF incluye un directorio de fuentes, un mapa fontdata y un conjunto de respaldo de «core fonts». NextPDF resuelve las fuentes mediante un único directorio de fuentes y la coincidencia de font-family de CSS, y siempre subdivide las fuentes incrustadas (ISO 32000-2 §9, iso32000_2_sec9#x1.x45.p7). La lógica de matching/fallback de fuentes es específica del motor (CSS Fonts 4 §5.5, css_fonts_4#x1.x5.x5.x1.p13), así que la sustitución de glifos puede diferir. Esta es la principal diferencia visible, tratada en la diferencia en el manejo de fuentes.

La API de HTML de NextPDF se documenta en el módulo Html. Puntos de entrada principales: Document::createStandalone(), Document::writeHtml(string $html): static, Document::writeHtmlCell(...), Document::addPage(), Document::output(?string, OutputDestination), Document::save(string $path): void, Document::getPdfData(): string y el objeto de valor NextPDF\Core\Config.

Los nombres de los métodos públicos de mPDF que figuran abajo están confirmados frente al repositorio público upstream (mpdf/mpdf, development): consulta el sidecar de procedencia _source-sidecar-upstream-api.md dentro del repositorio. No se reproduce ningún texto de la documentación upstream.

mPDFNextPDFNotas
new Mpdf([...])Document::createStandalone($config)El array de configuración de mPDF se asigna a NextPDF\Core\Config; consulta el mapa de configuración. Usa DocumentFactory para procesos de larga duración.
$mpdf->WriteHTML($html)$doc->writeHtml($html)Asignación directa. El segundo argumento $mode de mPDF (documento completo vs. solo CSS vs. elemento) no tiene análogo en NextPDF: pasa HTML completo.
$mpdf->WriteFixedPosHTML(...)$doc->writeHtmlCell(...)Región de HTML posicionada o dimensionada; asigna los argumentos x/y/width/height.
$mpdf->AddPage(...)$doc->addPage()Las anulaciones por llamada de orientation/format/margen de mPDF no son argumentos en NextPDF; en su lugar, cambia el modelo del documento entre llamadas.
$mpdf->SetHTMLHeader($html) / SetHTMLFooter($html)header/footer mediante la API de LayoutLos encabezados HTML recurrentes de mPDF se asignan al mecanismo de header/footer de NextPDF, no a HTML insertado al inicio del cuerpo.
$mpdf->Output($name, $dest)$doc->output($name, OutputDestination::…)Los caracteres de destino de mPDF (I/D/F/S) se asignan al enum OutputDestination (Inline/Download/file mediante save()/string mediante getPdfData()).
$mpdf->Output('','S')$doc->getPdfData()Devuelve los bytes.
$mpdf->Output($path,'F')$doc->save($path)Escribe en una ruta de archivo.
$mpdf->SetTitle($t)$doc->setTitle($t)Queda en el diccionario de información / XMP de la §14 de ISO 32000-2 (iso32000_2_sec14#x1.x5.p5).
$mpdf->SetProtection($perms,...)$doc->setEncryption(...) (API de Security)Los permisos son cooperativos con el lector, no control de acceso: consulta las Notas de seguridad.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// mPDF:
// $mpdf = new \Mpdf\Mpdf();
// $mpdf->WriteHTML('<h1>Invoice</h1>');
// $mpdf->Output('out.pdf', \Mpdf\Output\Destination::FILE);
// NextPDF — default page is A4 portrait:
$doc = Document::createStandalone();
$doc->setTitle('Invoice');
$doc->addPage();
$doc->writeHtml('<h1>Invoice</h1>');
$doc->save(__DIR__ . '/out.pdf');
echo "Wrote out.pdf\n";

Esto se alinea con examples/04-text-and-fonts.php, el respaldo ejecutable de los conceptos de manejo de fuentes de esta guía. Usa un tamaño de página explícito, márgenes y un cuerpo de contenido que ejercita la selección de fuentes.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\OutputDestination;
use NextPDF\Core\Config;
use NextPDF\Core\Document;
use NextPDF\ValueObjects\Margin;
use NextPDF\ValueObjects\PageSize;
// Equivalent of: new Mpdf(['format'=>'A4','margin_left'=>20, ...]).
// Margin constructor order is (top, right, bottom, left) — NOT L,R,T,B.
$config = new Config(
pageSize: new PageSize(595.276, 841.890, 'A4'),
margins: new Margin(16.0, 20.0, 16.0, 20.0), // top,right,bottom,left in points
fontsDirectory: __DIR__ . '/fonts',
);
$doc = Document::createStandalone($config);
$doc->setTitle('Quarterly Report');
$doc->addPage();
$html = <<<'HTML'
<h1 style="font-family:'DejaVu Sans';color:#1E3A8A;">Quarterly Report</h1>
<p>Body text resolves through CSS font-family matching against the configured
fonts directory. mPDF's fontdata map has no direct analogue — register the
family via CSS and the fonts directory instead.</p>
HTML;
$doc->writeHtml($html);
// Equivalent of $mpdf->Output('report.pdf', Destination::DOWNLOAD):
$doc->output('report.pdf', OutputDestination::Download);
  • Argumento $mode en WriteHTML. El WriteHTML($html, $mode) de mPDF (2 = solo CSS, 1 = elemento) no tiene equivalente. Incorpora tu CSS en el HTML que pasas; no hay una secuencia de «escribir CSS y luego escribir el cuerpo».
  • Anulaciones por AddPage. mPDF permite que AddPage() cambie el format/orientation a mitad del documento mediante argumentos. El addPage() de NextPDF no recibe esos argumentos; el cambio de tamaño del modelo ocurre a través del documento, no de la llamada a la página.
  • HTML de encabezado/pie de página. Los encabezados recurrentes de mPDF son fragmentos HTML registrados por separado; no los pegues en el cuerpo. Asígnalos al mecanismo de header/footer de NextPDF.
  • Nombres de fuentes. mPDF normaliza los nombres de fuentes mediante su tabla fontdata/core-font. NextPDF compara la font-family de CSS con el directorio de fuentes; un alias de mPDF que se resolvía en silencio puede necesitar un @font-face/family explícito.
  • Caracteres de destino. 'I'/'D'/'F'/'S' no se aceptan; usa el enum OutputDestination o save()/getPdfData().

writeHtml() es de una sola pasada (ADR-001); la memoria máxima sigue el tamaño del documento, no un DOM retenido. Presupuesto para el ejemplo de esta guía: wall_ms: 2000, peak_mb: 128. Para documentos largos, pagina el contenido mediante addPage() en lugar de usar una sola cadena gigante. Es el mismo consejo que aplica a la fragmentación por $mode de mPDF, pero expresado a través del modelo de páginas.

  • Los permisos son cooperativos con el lector. SetProtection()setEncryption() proporciona confidencialidad, no control de acceso: los bits de permiso de ISO dependen de un lector que coopere. No presentes el cifrado como control de acceso ante los usuarios.
  • Metadatos. SetTitle() y la información del documento quedan en el diccionario de información / XMP de la §14 de ISO 32000-2 (iso32000_2_sec14#x1.x5.p5); nunca almacenes secretos ahí.
  • NextPDF no ejecuta scripts incrustados en el documento; ninguna directiva de mPDF habilita eso aquí.
DeclaraciónEspecificaciónCláusulareference_id
Las fuentes se escriben como programas de fuente embedded/subset.ISO 32000-2§9
El format/margins de la página se asigna al cuadro de límite de la página.ISO 32000-2§7
Los metadatos de título / protección quedan en el diccionario de información / XMP.ISO 32000-2§14
La coincidencia / el respaldo de fuentes es específico del motor.CSS Fonts 4§5.5

NextPDF produce contenido ISO 32000-2; no afirma identidad visual con mPDF. Un cambio de renderer requiere volver a revisar la salida.

No aplica. El núcleo cubre la ruta de migración de mPDF descrita aquí.


Detalle de migración (secciones requeridas R6)

Sección titulada «Detalle de migración (secciones requeridas R6)»

Equipos que usan mpdf/mpdf para generar PDF desde HTML del lado del servidor. Si tu superficie es new Mpdf([...]) + WriteHTML + Output (+ header/footer opcional), la asignación de verbos y el mapa de configuración la cubren.

Dentro del alcance: el array de configuración del constructor Mpdf, WriteHTML/Output/AddPage, headers/footers, fuentes, protección, metadatos. Fuera del alcance: las clases internas de mPDF y la superficie de ayudantes para QR/código de barras/marca de agua (asígnalas a los módulos correspondientes de NextPDF — Barcode, Graphics — no tratados aquí).

Compatibilidad de comportamiento, no un shim de reemplazo directo: no hay un shim de la clase Mpdf. Cada sitio de llamada se reescribe. La expectativa sobre las funciones CSS queda limitada a las filas verificadas de la matriz de compatibilidad con CSS.

Mapa del array de configuración del constructor

Sección titulada «Mapa del array de configuración del constructor»

Las claves de configuración de mPDF están confirmadas frente al repositorio público upstream (mpdf/mpdf, development). No se reproduce ningún texto de la documentación upstream.

Clave de configuración de mPDFNextPDFNotas
mode(sin equivalente)La cadena de modo de mPDF ('utf-8', 'c', '+aCJK', …) selecciona el comportamiento de font/script. NextPDF siempre es Unicode; el CJK se maneja mediante la selección de fuentes, no mediante un modo. Elimina la clave.
formatConfig->pageSize (PageSize VO)Los formatos con nombre pasan a ser dimensiones explícitas en puntos; los arrays [w,h] se asignan a un PageSize.
orientationintercambia PageSize width/heightNo hay indicador de orientación; horizontal = ancho > alto.
default_font_sizefont-size base de CSSSe define mediante tu hoja de estilos base, no mediante una clave del constructor.
default_fontCSS font-family / fuente registradaDefine la familia predeterminada mediante CSS / registro de fuentes.
margin_left / margin_right / margin_top / margin_bottomConfig->margins (Margin VO) en puntosUn solo objeto de valor Margin; el orden de su constructor es Margin(top, right, bottom, left) (verifícalo frente a src/ValueObjects/Margin.php), no el orden de las claves de mPDF.
margin_header / margin_footerdesplazamiento de header/footer mediante la API de LayoutAsígnalo a la configuración de header/footer de NextPDF, no a claves del constructor.
  • Un único directorio de fuentes. La lista de directorios de fuentes de mPDF + el mapa fontdata + el respaldo de core-font se condensan en Config->fontsDirectory más la coincidencia de font-family de CSS.
  • Siempre subdivide. NextPDF siempre subdivide las fuentes incrustadas (ISO 32000-2 §9, iso32000_2_sec9#x1.x45.p7); los indicadores de subdivisión de mPDF no tienen equivalente y no se necesitan.
  • La coincidencia es específica del motor. La lógica de matching/fallback de fuentes difiere según el motor (CSS Fonts 4 §5.5, css_fonts_4#x1.x5.x5.x1.p13); un alias de fuente de mPDF puede necesitar un @font-face explícito o el nombre exacto de la familia. Restablece la línea base del renderizado de glifos tras la migración; las diferencias de sustitución son esperadas, no defectos.
  • Sustitución de fuentes (ver arriba): la principal diferencia visible.
  • Sin $mode en WriteHTML: pasa HTML completo con CSS insertado.
  • Sin anulación de formato por AddPage: el cambio de tamaño del modelo ocurre a través del documento.
  • Los permisos son cooperativos con el lector (consulta las Notas de seguridad).
  • Motor de maquetación independiente: el ajuste de línea / la paginación difieren en contenido denso; restablece la línea base de las diferencias visuales.

Estas son diferencias de comportamiento documentadas, no defectos en ninguno de los motores.

  • mode: cadena del constructor — no se modela (siempre Unicode).
  • Los argumentos de format/orientation/margen por AddPage(): no son argumentos en NextPDF.
  • El mapa fontdata de mPDF: reemplazado por el directorio de fuentes + la coincidencia de CSS.
  • Los caracteres de destino 'I'/'D'/'F'/'S' de mPDF: reemplazados por el enum OutputDestination + save()/getPdfData().
  1. Añade nextpdf/core junto a mpdf/mpdf (conserva mPDF por ahora).
  2. Elige un documento de bajo riesgo. Convierte new Mpdf([...]) mediante el mapa de configuración y WriteHTML/Output mediante el mapa de verbos.
  3. Registra las fuentes que usa el documento en Config->fontsDirectory y añade declaraciones explícitas de @font-face/family para cualquier alias de mPDF.
  4. Genera ambos PDF para la misma entrada; compáralos visualmente. Las diferencias (sustitución de fuentes, ajuste de línea) son esperadas en motores independientes: acéptalas documento por documento.
  5. Asigna cualquier HTML de header/footer al mecanismo de header/footer de NextPDF.
  6. Repite por documento, primero el de menor riesgo; mantén mPDF instalado hasta el último cambio.
  7. Elimina mpdf/mpdf de composer.json tras el cambio final.
  • Captura la salida de mPDF de documentos representativos antes de cambiar el código (entradas de referencia; los bytes diferirán).
  • Por cada documento migrado, verifica mediante tu propia comprobación de aceptación (comparación visual + extracción de texto). El comportamiento de fuentes/HTML de NextPDF se ejercita con examples/04-text-and-fonts.php y examples/08-html-basic.php más las suites de Html/Font de tests/ del núcleo. La aceptación de la migración es específica de cada documento y es responsabilidad tuya.
  • Añade una prueba de regresión por cada documento migrado.

Cada afirmación de comportamiento de NextPDF en esta página está respaldada por una prueba dentro del repositorio, un ejemplo, una firma de origen o un ADR; o bien, cuando se trata de una propiedad del formato PDF, por las cláusulas de ISO 32000-2 / CSS fijadas por RAG en las citations: del frontmatter y la tabla de Conformidad. El comportamiento de mPDF se formula solo como «motor independiente: espera diferencias documentadas»; no se reclama ninguna paridad que un artefacto dentro del repositorio no demuestre.

Afirmación de comportamiento de NextPDFEvidencia dentro del repositorio (ruta)
WriteHTML() se asigna directamente a Document::writeHtml(string $html): static.src/Core/Concerns/HasTextOutput.php (writeHtml()); examples/08-html-basic.php.
WriteFixedPosHTML(...) se asigna a writeHtmlCell(...).src/Core/Concerns/HasTextOutput.php (writeHtmlCell()).
createStandalone() usa A4 vertical de forma predeterminada (595.276 × 841.890 pt).src/Core/Config.php (PageSize predeterminado); tests/Unit/Core/DocumentCreateStandaloneAndConfigWithersEdgeCaseTest.php.
Margin usa el orden de constructor (top, right, bottom, left).src/ValueObjects/Margin.php (orden de las propiedades promovidas).
El destino de salida es el enum NextPDF\Contracts\OutputDestination; 'I'/'D'/'F'/'S' no se aceptan.src/Contracts/OutputDestination.php (casos Inline/Download/File/String); tests/Unit/Core/Concerns/DocumentOutputDestinationDispatchTest.php.
Output('','S')getPdfData(); Output($path,'F')save($path).src/Core/Concerns/HasOutput.php (getPdfData(), save(), output()).
SetProtection() se asigna a setEncryption(...); los permisos son cooperativos con el lector.src/Core/Concerns/HasSecurity.php (setEncryption()); ISO 32000-2 §14 (citations: del frontmatter).
SetTitle()setTitle(); los metadatos quedan en el diccionario de información / XMP.src/Core/Concerns/HasMetadata.php (setTitle()); tests/Unit/Core/Concerns/DocumentInfoMetadataSetterBaselineTest.php; ISO 32000-2 §14 (citations: del frontmatter).
Las fuentes siempre se incrustan como programas de subconjunto.tests/Unit/Core/Concerns/DocumentTextOutputFontSubsettingAndBorderEdgeCaseTest.php; examples/04-text-and-fonts.php; ISO 32000-2 §9 (citations: del frontmatter).
La coincidencia / el respaldo de fuentes es específico del motor (diferencia de sustitución).CSS Fonts 4 §5.5 (citations: del frontmatter + Conformidad).
writeHtml() es de una sola pasada; la memoria máxima sigue el tamaño del documento.docs/architecture/adr/ADR-001-stream-based-rendering-pipeline.md.

Ambos paquetes permanecen instalados hasta el cambio final, así que la reversión por sitio de llamada consiste en devolver ese sitio de llamada a la ruta de mPDF. Tras el cambio final, la reversión consiste en restaurar mpdf/mpdf y el código anterior desde el control de versiones. No hay ninguna migración de datos involucrada.

Consulta Rendimiento. El modelo de una sola pasada elimina el coste del búfer retenido de mPDF. El nuevo coste por documento es la resolución anticipada de fuentes (paso 3), que se puede almacenar en caché mediante el directorio de fuentes.

  • Mantener la clave mode y esperar de ella un comportamiento CJK (se elimina; el CJK es selección de fuentes).
  • Pasar WriteHTML($html, 2) (modo solo CSS): inserta el CSS en su lugar.
  • Pegar HTML de header/footer en el cuerpo.
  • Esperar la misma fuente para un alias de mPDF sin una familia explícita.
  • Esperar una salida byte/pixel-identical (motores independientes: esta guía nunca afirma un reemplazo directo ni una compatibilidad del 100%).
  • Tratar la matriz de compatibilidad con CSS como orientativa: es la autoridad sobre las funciones verificadas.