Salta ai contenuti

Le basi di PHP 8.4

Spec: ISO 32000-2, §7.5.2 Evidence: Code-backed Vincolo PHP: ≥8.4 <9.0

NextPDF richiede PHP 8.4. Questa pagina spiega su quali funzionalità del linguaggio 8.4 il motore fa davvero affidamento, perché quella versione è un limite minimo rigido e non un semplice suggerimento, e in che modo una build di downgrade separata mantiene aperta la possibilità di eseguire il codice su runtime meno recenti senza indebolire il codice che si legge.

Un motore PDF trasforma input ambiguo in un formato di file definito byte per byte. PDF è un formato consolidato da tempo, con regole solide e fisse, ed è abbastanza rigido da rendere costosa qualsiasi ipotesi errata. Il linguaggio in cui è scritto il motore è il primo punto in cui quelle ipotesi vengono intercettate oppure lasciate passare senza controllo. Un limite minimo di versione non è una restrizione fine a sé stessa. È la linea sotto la quale il motore non può più offrire le garanzie di tipo da cui dipende il resto della sua progettazione.

Se quel limite minimo è vago, i costi sono due. Il codice si riempie di adattatori di compatibilità che oscurano la logica reale. Anche il sistema di tipi smette di essere portante, ed è esattamente la proprietà che un flusso documentale non può permettersi di perdere.

  • Il pacchetto core dichiara "php": ">=8.4 <9.0". Questo è il vincolo reale, verificato in composer.json, non un’aspirazione documentale.
  • 8.4 è il limite minimo perché il motore usa le funzionalità del linguaggio 8.4 (e delle 8.x recenti) come garanzie strutturali: visibilità asimmetrica, enum con valore di base dotati di comportamento, costanti di classe tipizzate, stato readonly e argomenti con nome di prima classe nell’API pubblica.
  • L’esecuzione su PHP 8.1–8.3 è comunque possibile tramite una build di downgrade separata (il backport). È strumentazione di build, non una dipendenza di runtime. Non modifica il codice che si legge nel repository core.
  • Il limite superiore <9.0 è deliberato: una nuova release major di PHP è trattata come qualcosa da convalidare, non da dare per scontato.

Il limite minimo è stabilito da ciò che il codice fa. Per questo il modo più trasparente per spiegarlo è mostrare le funzionalità nel codice anziché elencarle in astratto.

La visibilità asimmetrica consente di rendere lo stato leggibile pubblicamente ma scrivibile solo privatamente, senza dover scrivere un getter a mano per ogni campo. Il contesto di rendering la usa direttamente:

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 = '';
}

Da sola, questa funzionalità del linguaggio elimina un’intera categoria di mutazioni esterne accidentali. Il cursore non può essere spostato dall’esterno del motore. La garanzia è imposta dal runtime, non da una convenzione che i revisori devono ricordarsi di applicare.

Gli enum con valore di base dotati di comportamento sostituiscono flag booleani sparsi e costanti stringa con un unico valore tipizzato che risponde anche a domande su sé stesso. Il discriminatore di conformità del documento è un enum con valore di base i cui metodi guidano decisioni a livello di specifica:

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,
};
}
}

L’enum è l’unica fonte di verità per stabilire «questo documento è etichettato secondo la specifica?» e «quale parte ISO si applica?». Quando quelle domande erano espresse come booleani slegati, più punti potevano rispondervi in modo incoerente.

Le costanti di classe tipizzate rendono anche le costanti parte del contratto di tipo. I limiti rigidi del motore HTML sono dichiarati come costanti tipizzate:

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

Gli argomenti con nome fanno parte della superficie dell’API pubblica, non sono un espediente interno. I programmi di esempio li usano in punti di chiamata che il lettore è invitato a copiare:

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

Non si tratta di usi decorativi della nuova sintassi. Ciascuno trasforma una convenzione che un revisore dovrebbe altrimenti imporre a mano in una proprietà imposta dal runtime.

Questa pagina è Evidence: Code-backed . Ogni affermazione precedente corrisponde a un file nel repository core, non a un elenco di funzionalità:

  • Il vincolo di versione è il valore ">=8.4 <9.0" di require.php nel composer.json del core.
  • L’esempio di visibilità asimmetrica è lo stile di dichiarazione reale in src/Core/RenderingContext.php (campi public private(set)).
  • L’esempio di enum rispecchia src/Conformance/ConformanceMode.php, un enum … : string con valore di base i cui metodi basati su match guidano le decisioni di conformità.
  • Le costanti tipizzate sono src/Html/HtmlParser.php (private const int MAX_NESTING_DEPTH, MAX_ELEMENT_COUNT).
  • La chiamata con argomento con nome proviene dai programmi examples/ distribuiti.

Il limite minimo ha anche una dimensione legata agli standard. Il compito del motore è emettere file conformi a Spec: ISO 32000-2, §7.5.2 . Un writer PDF 2.0 conforme deve dichiarare la versione del documento come 2.0 nell’header del file o nel catalogo. Soddisfare un obbligo così preciso è molto più semplice quando il linguaggio sottostante al writer rende difficile costruire uno stato incoerente fin dall’inizio. Il limite minimo di versione e il rigore del formato sono allineati.

Il più piccolo programma corretto mette già alla prova il limite minimo. Funziona su PHP 8.4, usa un argomento con nome e produce un file 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');

Qui non c’è nulla di esotico. Il punto è che le stesse scelte di tipizzazione rigorosa, enum e visibilità asimmetrica che rendono affidabili gli interni del motore sono già attive alla base di questo programma di cinque righe. Non occorre attivarle esplicitamente.

L’interpretazione errata più comune è che «richiede PHP 8.4» significhi «non funzionerà se non si aggiorna a 8.4». Significa che il sorgente core ha come destinazione 8.4. Esiste una build di downgrade separata per i team vincolati a PHP 8.1–8.3.

È importante essere precisi su cosa sia quella build. È un flusso di downgrade basato su Rector che trasforma il sorgente 8.4 in output con sintassi più datata. È infrastruttura di build, non una libreria di runtime da aggiungere alle dipendenze della propria applicazione. Non introduce codice parallelo con tipizzazione più debole. Il codice esaminato in queste pagine e il codice distribuito sono lo stesso codice. Il backport è una trasformazione applicata a esso, non un’alternativa a esso.

Questa pagina spiega perché 8.4 è il limite minimo e cosa preserva il backport. Non documenta come eseguire il flusso di downgrade, le versioni di destinazione supportate o i suoi avvertimenti operativi. Questi aspetti appartengono alla documentazione specifica della build di backport. La struttura interna dei pacchetti di quella strumentazione è fuori dall’ambito di questa pagina. Gli usi delle funzionalità mostrati sono indicativi dello stile del motore. Non costituiscono l’inventario completo di ogni funzionalità 8.x che il codice utilizza. Le API esatte sono definite dal riferimento, non da questa spiegazione. Il vincolo di versione è accurato alla data di revisione di questa pagina. Il valore di riferimento è sempre il blocco require nel composer.json del core.

L’edizione non incide sul limite minimo del linguaggio. Ogni edizione è costruita dallo stesso sorgente PHP 8.4:

PHP 8.4 source floor — edition availability
Edition Availability
Core Il core è scritto per PHP 8.4.
Pro Pro usa lo stesso limite minimo del sorgente 8.4.
Enterprise Enterprise usa lo stesso limite minimo del sorgente 8.4.
  • Limite minimo di versione — la versione minima di PHP a cui punta il sorgente core (>=8.4). Sotto tale limite, le garanzie di tipo del motore non possono essere espresse.
  • Visibilità asimmetrica — una funzionalità di PHP 8.4 che consente a una proprietà di essere leggibile pubblicamente ma scrivibile solo da uno scope più ristretto (public private(set)).
  • Enum con valore di base — un enum PHP i cui casi hanno valori scalari e che può contenere comportamento (metodi), usato qui come unica fonte di verità tipizzata.
  • Backport — la build di downgrade separata basata su Rector che trasforma il sorgente 8.4 in output eseguibile su runtime PHP meno recenti. Strumentazione di build, non una dipendenza di runtime.
  • Modalità di conformità — il discriminatore tipizzato del motore per stabilire quale contratto di conformità ISO un documento deve soddisfare.