Migrar de mPDF a NextPDF
De un vistazo
Sección titulada «De un vistazo»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.
Instalación
Sección titulada «Instalación»composer require nextpdf/core:^3Mantén mpdf/mpdf instalado durante la transición. Elimínalo tras el cambio final (consulta la secuencia de migración segura).
Resumen conceptual
Sección titulada «Resumen conceptual»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.
Superficie de la API
Sección titulada «Superficie de la API»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.
Asignación de verbos de la API
Sección titulada «Asignación de verbos de la API»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.
| mPDF | NextPDF | Notas |
|---|---|---|
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 Layout | Los 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. |
Ejemplo de código — Inicio rápido
Sección titulada «Ejemplo de código — Inicio rápido»<?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";Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producció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 configuredfonts directory. mPDF's fontdata map has no direct analogue — register thefamily 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);Casos límite y trampas
Sección titulada «Casos límite y trampas»- Argumento
$modeenWriteHTML. ElWriteHTML($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 queAddPage()cambie el format/orientation a mitad del documento mediante argumentos. EladdPage()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 lafont-familyde 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 enumOutputDestinationosave()/getPdfData().
Rendimiento
Sección titulada «Rendimiento»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.
Notas de seguridad
Sección titulada «Notas de seguridad»- 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í.
Conformidad
Sección titulada «Conformidad»| Declaración | Especificación | Cláusula | reference_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.
Contexto comercial
Sección titulada «Contexto comercial»No aplica. El núcleo cubre la ruta de migración de mPDF descrita aquí.
Consulta también
Sección titulada «Consulta también»Detalle de migración (secciones requeridas R6)
Sección titulada «Detalle de migración (secciones requeridas R6)»Para quién es esto
Sección titulada «Para quién es esto»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.
Alcance
Sección titulada «Alcance»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í).
Mapa de compatibilidad
Sección titulada «Mapa de compatibilidad»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 mPDF | NextPDF | Notas |
|---|---|---|
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. |
format | Config->pageSize (PageSize VO) | Los formatos con nombre pasan a ser dimensiones explícitas en puntos; los arrays [w,h] se asignan a un PageSize. |
orientation | intercambia PageSize width/height | No hay indicador de orientación; horizontal = ancho > alto. |
default_font_size | font-size base de CSS | Se define mediante tu hoja de estilos base, no mediante una clave del constructor. |
default_font | CSS font-family / fuente registrada | Define la familia predeterminada mediante CSS / registro de fuentes. |
margin_left / margin_right / margin_top / margin_bottom | Config->margins (Margin VO) en puntos | Un 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_footer | desplazamiento de header/footer mediante la API de Layout | Asígnalo a la configuración de header/footer de NextPDF, no a claves del constructor. |
Diferencia en el manejo de fuentes
Sección titulada «Diferencia en el manejo de fuentes»- Un único directorio de fuentes. La lista de directorios de fuentes de mPDF + el mapa
fontdata+ el respaldo de core-font se condensan enConfig->fontsDirectorymás la coincidencia defont-familyde 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-faceexplí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.
Diferencias de comportamiento
Sección titulada «Diferencias de comportamiento»- Sustitución de fuentes (ver arriba): la principal diferencia visible.
- Sin
$modeenWriteHTML: 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.
Sin soporte / sin equivalente directo
Sección titulada «Sin soporte / sin equivalente directo»mode: cadena del constructor — no se modela (siempre Unicode).- Los argumentos de format/orientation/margen por
AddPage(): no son argumentos en NextPDF. - El mapa
fontdatade mPDF: reemplazado por el directorio de fuentes + la coincidencia de CSS. - Los caracteres de destino
'I'/'D'/'F'/'S'de mPDF: reemplazados por el enumOutputDestination+save()/getPdfData().
Secuencia de migración segura
Sección titulada «Secuencia de migración segura»- Añade
nextpdf/corejunto ampdf/mpdf(conserva mPDF por ahora). - Elige un documento de bajo riesgo. Convierte
new Mpdf([...])mediante el mapa de configuración yWriteHTML/Outputmediante el mapa de verbos. - Registra las fuentes que usa el documento en
Config->fontsDirectoryy añade declaraciones explícitas de@font-face/family para cualquier alias de mPDF. - 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.
- Asigna cualquier HTML de header/footer al mecanismo de header/footer de NextPDF.
- Repite por documento, primero el de menor riesgo; mantén mPDF instalado hasta el último cambio.
- Elimina
mpdf/mpdfdecomposer.jsontras el cambio final.
Probar la migración
Sección titulada «Probar la migración»- 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.phpyexamples/08-html-basic.phpmás las suites de Html/Font detests/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.
Evidencia / trazabilidad
Sección titulada «Evidencia / trazabilidad»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 NextPDF | Evidencia 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. |
Reversión
Sección titulada «Reversión»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.
Consideraciones de rendimiento
Sección titulada «Consideraciones de rendimiento»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.
Errores comunes
Sección titulada «Errores comunes»- Mantener la clave
modey 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.