Ir al contenido

Fundamentos de PHP 8.4

Spec: ISO 32000-2, §7.5.2 Evidence: Code-backed Restricción de PHP: ≥8.4 <9.0

NextPDF requiere PHP 8.4. Esta página explica en qué características del lenguaje de 8.4 se apoya realmente el motor, por qué esa versión es un mínimo estricto y no una simple recomendación, y cómo una compilación de degradación independiente mantiene abierta la opción de ejecutarse en un runtime más antiguo, sin debilitar el código base que se lee.

Un motor de PDF convierte una entrada ambigua en un formato de archivo exacto a nivel de bytes. PDF es un formato maduro, con reglas estrictas y estables, y exige suficiente precisión como para que una suposición errónea resulte costosa. El lenguaje en el que está escrito el motor es el primer lugar donde esas suposiciones se detectan o se dejan pasar sin verificar. Un mínimo de versión no es una restricción arbitraria. Es la línea por debajo de la cual el motor ya no puede ofrecer las garantías de tipos de las que depende el resto de su diseño.

Si ese mínimo queda difuso, aparecen dos costos. El código base se llena de capas de compatibilidad que oscurecen la lógica real. Además, el sistema de tipos pierde su carácter estructural, que es justamente la propiedad que una canalización de documentos no puede permitirse perder.

  • El paquete principal declara "php": ">=8.4 <9.0". Esa es la restricción real, verificada en composer.json, no una aspiración de la documentación.
  • 8.4 es el mínimo porque el motor utiliza características del lenguaje de 8.4 (y de versiones 8.x recientes) como garantías estructurales: visibilidad asimétrica, enumeraciones respaldadas con comportamiento, constantes de clase tipadas, estado de solo lectura y argumentos con nombre de primer nivel en la API pública.
  • Ejecutar sobre PHP 8.1–8.3 sigue siendo posible mediante una compilación de degradación independiente (el backport). Es una herramienta de compilación, no una dependencia de runtime. No cambia el código que se lee en el repositorio principal.
  • El límite superior <9.0 es deliberado: una nueva versión mayor de PHP se trata como algo que debe validarse, no darse por supuesto.

El mínimo lo determina lo que hace el código. Por eso, la manera más clara de explicarlo es mostrar las características en el código en lugar de enumerarlas en abstracto.

La visibilidad asimétrica permite que el estado sea legible públicamente pero solo escribible de forma privada, sin un getter escrito a mano para cada campo. El contexto de representación la usa directamente:

declare(strict_types=1);
final class RenderingContext
{
// Readable everywhere, writable only inside the class.
public private(set) float $x = 0.0;
public private(set) float $y = 0.0;
public private(set) int $currentPageIndex = -1;
public private(set) string $currentContentStream = '';
}

Esa única característica del lenguaje elimina toda una categoría de mutación externa accidental. El cursor no se puede mover desde fuera del motor. La garantía la impone el runtime, no una convención que los revisores deban recordar.

Las enumeraciones respaldadas con comportamiento sustituyen banderas booleanas dispersas y constantes de cadena por un único valor tipado que además responde preguntas sobre sí mismo. El discriminador de conformidad del documento es una enumeración respaldada cuyos métodos determinan resultados a nivel de especificación:

declare(strict_types=1);
enum ConformanceMode: string
{
case Plain = 'plain';
case PdfUa2 = 'pdfua2';
case PdfA4 = 'pdfa4';
case PdfA4f = 'pdfa4f';
public function isTagged(): bool
{
return match ($this) {
self::Plain => false,
default => true,
};
}
/** @return 2|3|4|null */
public function pdfaPart(): ?int
{
return match ($this) {
self::PdfA4, self::PdfA4f => 4,
default => null,
};
}
}

La enumeración es la única fuente de verdad para «¿está este documento etiquetado según la especificación?» y «¿qué parte de la norma ISO se aplica?». Cuando esas preguntas se expresaban como booleanos sueltos, varios lugares podían responderlas de forma inconsistente.

Las constantes de clase tipadas hacen que incluso las constantes formen parte del contrato de tipos. Los límites estrictos del motor HTML se declaran como constantes tipadas:

private const int MAX_NESTING_DEPTH = 100;
private const int MAX_ELEMENT_COUNT = 50_000;

Los argumentos con nombre forman parte de la superficie de la API pública; no son un truco interno. Los programas de ejemplo los usan en llamadas pensadas para copiarse tal cual:

$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);

Estos no son usos decorativos de una nueva sintaxis. Cada uno convierte en una propiedad impuesta por el runtime una convención que, de otro modo, habría que imponer manualmente en revisión.

Esta página es Evidence: Code-backed . Cada afirmación anterior corresponde a un archivo del repositorio principal, no a una lista de características:

  • La restricción de versión corresponde al valor de require.php ">=8.4 <9.0" en el composer.json principal.
  • El ejemplo de visibilidad asimétrica es el estilo de declaración real en src/Core/RenderingContext.php (campos public private(set)).
  • El ejemplo de la enumeración refleja src/Conformance/ConformanceMode.php, una enum … : string respaldada cuyos métodos basados en match dirigen las decisiones de conformidad.
  • Las constantes tipadas son src/Html/HtmlParser.php (private const int MAX_NESTING_DEPTH, MAX_ELEMENT_COUNT).
  • La llamada con argumento con nombre proviene de los programas de examples/ que se distribuyen.

El mínimo también tiene una dimensión de estándares. La función del motor es emitir archivos que cumplan con Spec: ISO 32000-2, §7.5.2 . Un escritor de PDF 2.0 conforme debe declarar la versión del documento como 2.0 en la cabecera del archivo o en el catálogo. Cumplir una obligación tan precisa es mucho más fácil cuando el lenguaje en el que se apoya el escritor dificulta construir desde el principio un estado incoherente. El mínimo de versión y la estrictez del formato están alineados.

El programa correcto mínimo ya pone en juego ese mínimo. Se ejecuta en PHP 8.4, usa un argumento con nombre y produce un archivo conforme:

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Hello World');
$doc->addPage();
$doc->setFont('helvetica', '', 24);
$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);
$doc->save(__DIR__ . '/hello.pdf');

Nada de esto es exótico. Lo importante es que la misma maquinaria de tipado estricto, enumeraciones y visibilidad asimétrica que hace fiable la lógica interna del motor ya está activa en este programa de cinco líneas. No se opta por activarla.

La interpretación errónea más habitual es que «requiere PHP 8.4» significa «no funcionará a menos que se actualice a 8.4». Significa que el código fuente principal apunta a 8.4. Existe una compilación de degradación independiente para los equipos anclados a PHP 8.1–8.3.

Es importante ser preciso sobre qué es esa compilación. Se trata de una canalización de degradación basada en Rector que transforma el código fuente de 8.4 en una salida con sintaxis más antigua. Es infraestructura de compilación, no una biblioteca de runtime que se añade a las dependencias de la aplicación. No introduce un código base paralelo con tipado más débil. El código revisado en estas páginas y el que se distribuye son el mismo. El backport es una transformación que se le aplica, no una alternativa a él.

Esta página explica por qué 8.4 es el mínimo y qué preserva el backport. No documenta cómo ejecutar la canalización de degradación, sus versiones de destino admitidas ni sus salvedades operativas. Eso corresponde a la documentación propia de la compilación de backport. La organización interna de los paquetes de esa herramienta queda fuera del alcance de esta página. Los ejemplos de características que se muestran son ilustrativos del estilo del motor. No son el inventario completo de todas las características 8.x que utiliza el código base. La referencia define las API exactas, no esta explicación. La restricción de versión es exacta a la fecha de revisión de esta página. El valor de referencia siempre es el bloque require del composer.json principal.

La edición no cambia el mínimo del lenguaje. Cada edición se compila a partir del mismo código fuente de PHP 8.4:

PHP 8.4 source floor — edition availability
Edition Availability
Core El núcleo está escrito sobre PHP 8.4.
Pro Pro se construye sobre el mismo mínimo de código fuente de 8.4.
Enterprise Enterprise se construye sobre el mismo mínimo de código fuente de 8.4.
  • Mínimo de versión — la versión mínima de PHP a la que apunta el código fuente principal (>=8.4). Por debajo de ese mínimo, las garantías de tipos del motor no pueden expresarse.
  • Visibilidad asimétrica — una característica de PHP 8.4 que permite que una propiedad sea legible públicamente y solo pueda escribirse desde un ámbito más restringido (public private(set)).
  • Enumeración respaldada — una enumeración de PHP cuyos casos tienen valores escalares y que puede incluir comportamiento (métodos), usada aquí como una única fuente de verdad tipada.
  • Backport — la compilación de degradación independiente, basada en Rector, que transforma el código fuente de 8.4 en salida ejecutable en versiones de PHP más antiguas. Herramienta de compilación, no una dependencia de runtime.
  • Modo de conformidad — el discriminador tipado del motor para indicar qué contrato de conformidad ISO debe satisfacer un documento.