Agregar enlaces y anotaciones de texto
De un vistazo
Sección titulada «De un vistazo»Esta receta agrega tres elementos interactivos: un enlace interno para saltar a otra página, un enlace externo que abre una URL y una anotación de texto, también llamada nota adhesiva. Se basa en examples/17-links.php y examples/29-annotations.php.
Un enlace en el que se puede hacer clic es una anotación de enlace de ISO 32000-2, un hipervínculo a un destino o a una acción. Una nota adhesiva es una anotación de texto: muestra un icono cuando está cerrada y una ventana emergente cuando está abierta.
Instalación
Sección titulada «Instalación»composer require nextpdf/core:^3No se requiere ninguna extensión opcional. La API de enlaces y anotaciones es estable desde la versión 1.0.0 y funciona sobre la matriz de backport 8.1–8.4.
Panorama conceptual
Sección titulada «Panorama conceptual»Los enlaces internos siguen un patrón de tres llamadas que admite referencias anticipadas:
addLink()reserva un identificador de enlace (un int).link($x, $y, $w, $h, $id)coloca un rectángulo en el que se puede hacer clic, asociado a ese id.setLink($id, $pageIndex, $y)asocia el id a una página de destino (de base cero) y a una coordenada Y.
Llamar al paso 3 después del paso 2 permite enlazar a una página que aún no existe. El destino usa una forma de destino explícito. ISO 32000-2 §12.3.2.2 define [page /XYZ left top zoom], donde un componente nulo conserva el valor actual del lector.
Para un enlace externo, se pasa una cadena de URL a link() en lugar de un int. NextPDF emite entonces una acción URI cuyo URI es una cadena ASCII UTF-8 obligatoria. Como atajo, write($height, $text, $link) dibuja texto en línea con una URL adjunta, y annotation($x, $y, $w, $h, $text) coloca una nota adhesiva de subtipo Text. ISO 32000-2 requiere SubtypeLink para una anotación de enlace y define el comportamiento del icono y de la ventana emergente de la anotación de texto.
Superficie de la API
Sección titulada «Superficie de la API»La superficie de la API se genera automáticamente a partir de PHPDoc. Esta receta se apoya en estos métodos:
addLink(): int— reserva un identificador de enlace interno.setLink(int $linkId, int $pageIndex = -1, float $y = 0): static— asocia un id a una página de destino (de base cero) y a una coordenada Y.link(float $x, float $y, float $w, float $h, string|int $link): static— rectángulo en el que se puede hacer clic; un id int es interno, una cadena es una URL externa.write(float $height, string $text, string $link = ''): static— texto en línea con una URL opcional.annotation(float $x, float $y, float $w, float $h, string $text, string $subtype = 'Text'): static— anotación de tipo nota adhesiva.
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;
$doc = Document::createStandalone();$jump = $doc->addLink(); // 1. reserve an id (forward reference)
$doc->addPage();$doc->setFont('helvetica', 'B', 12);$x = $doc->getX();$y = $doc->getY();$doc->cell(60, 10, 'Go to page 2', newLine: true);$doc->link($x, $y, 60, 10, $jump); // 2. clickable rectangle -> id
$doc->link($doc->getX(), $doc->getY(), 80, 10, 'https://nextpdf.dev'); // external
$doc->addPage();$doc->setLink($jump, pageIndex: 1, y: 0); // 3. bind id to page 2 (index 1)$doc->cell(0, 10, 'Destination (page 2).', newLine: true);$doc->annotation(x: 180, y: 20, w: 10, h: 10, text: 'A reviewer note.');
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/links.pdf');Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producción»Este es el ejemplo completo, listo para el arnés de pruebas. Respeta NEXTPDF_COOKBOOK_OUTPUT y no añade entropía por su cuenta.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Links and Annotations');
// Reserve the internal-link id before its destination page exists.$linkToPage3 = $doc->addLink();
// Page 1 — source of the internal and external links.$doc->addPage();$doc->setFont('helvetica', 'B', 20);$doc->cell(0, 14, 'Links and Annotations', newLine: true);$doc->ln(6);
$doc->setFont('helvetica', 'B', 12);$doc->setTextColor(0, 51, 153);$linkX = $doc->getX();$linkY = $doc->getY();$doc->cell(60, 10, 'Go to Page 3', newLine: true);$doc->link($linkX, $linkY, 60, 10, $linkToPage3); // internal: int id$doc->setTextColor(0);$doc->ln(6);
$doc->setFont('helvetica', 'B', 12);$doc->setTextColor(0, 102, 204);$doc->write(10, 'Visit https://nextpdf.dev', link: 'https://nextpdf.dev');$doc->setTextColor(0);$doc->ln(6);
$urlX = $doc->getX();$urlY = $doc->getY();$doc->cell(80, 10, 'NextPDF on GitHub', newLine: true);$doc->link($urlX, $urlY, 80, 10, 'https://github.com/nextpdf-labs/nextpdf');
// Page 2 — intermediate.$doc->addPage();$doc->setFont('helvetica', '', 11);$doc->multiCell(0, 7, 'Internal links can jump across pages; this page is ' . 'skipped by the link on page 1.');
// Page 3 — destination + a sticky note.$doc->addPage();$doc->setLink($linkToPage3, pageIndex: 2, y: 0); // bind id to page 3 (index 2)$doc->setFont('helvetica', 'B', 18);$doc->cell(0, 14, 'Page 3 — Link Target', newLine: true);$doc->ln(4);$doc->setFont('helvetica', '', 11);$doc->multiCell(0, 7, 'You arrived via the internal link on page 1.');$doc->annotation( x: 185, y: 40, w: 10, h: 10, text: 'Sticky note: appears as an icon; click to read this text.',);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/links.pdf';$doc->save($out);
echo "Created links.pdf\n";Casos límite y trampas
Sección titulada «Casos límite y trampas»pageIndexes de base cero.setLink($id, pageIndex: 2, …)apunta a la tercera página. Un error de desfase por uno aquí es el fallo más común.- Cadena frente a int en
link(). Un int es un id de destino interno deaddLink(). Una cadena es una URL externa. Pasar el tipo equivocado produce el tipo de enlace equivocado sin emitir ningún error. - Asociar cada id reservado. Un id de
addLink()que nunca se asocia consetLink()no tiene destino. El rectángulo permite hacer clic, pero es inerte. Debe asociarse antes desave(). - El área en la que se puede hacer clic es el rectángulo, no el texto.
link()tomax, y, w, hexplícitos. Debe dimensionarse para cubrir el texto visible. El motor no mide los glifos automáticamente. - Los enlaces externos no se validan. NextPDF almacena el URI textualmente. No verifica que el destino se resuelva ni que sea seguro. El lector lo resuelve.
Rendimiento
Sección titulada «Rendimiento»Cada enlace o anotación agrega un diccionario de anotación a la página. El costo es O(1) por elemento. Cientos por página se mantienen holgadamente dentro del presupuesto de 2000 ms / 64 MB.
Notas de seguridad
Sección titulada «Notas de seguridad»Los destinos de los enlaces externos se almacenan textualmente y los resuelve el lector, no la biblioteca. Las URL proporcionadas por el usuario deben tratarse como no confiables. Usar una lista de permitidos para el esquema, que normalmente es https. Rechazar javascript: y file: antes de pasarlos a link(). El texto de la anotación se muestra en la interfaz del lector, así que conviene limitar su longitud y sanear el contenido de las notas cuando esté controlado por el usuario. En esta receta no se realiza ningún análisis de entrada ni acceso a la red.
Conformidad
Sección titulada «Conformidad»| Declaración | Especificación | Cláusula | reference_id |
|---|---|---|---|
| Una anotación de enlace es un hipervínculo a un destino o a una acción. | ISO 32000-2 | §12.5.6.5 | |
Subtype es Link para una anotación de enlace. | ISO 32000-2 | §12.5.6.5 | |
El URI de una acción URI es una cadena ASCII UTF-8 obligatoria. | ISO 32000-2 | §12.6.4.8 | |
| Una anotación de texto es una nota adhesiva (cerrada = icono, abierta = ventana emergente). | ISO 32000-2 | §12.5.6.4 | |
Destino explícito [page /XYZ left top zoom]; null conserva el valor actual. | ISO 32000-2 | §12.3.2.2 |
Perfil de reproducibilidad — estructural. El /ID del tráiler y los átomos de fecha varían en cada guardado. El arnés de pruebas elimina esos átomos y después compara la estructura normalizada por qpdf. Esta receta describe cómo NextPDF produce la estructura. No constituye una declaración general de conformidad con ISO 32000-2.
Contexto comercial
Sección titulada «Contexto comercial»No aplica. Los enlaces y las anotaciones de texto son capacidades de Core sin restricción de Premium.