Aller au contenu

Les fondations PHP 8.4

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

NextPDF requiert PHP 8.4. Cette page explique les fonctionnalités de PHP 8.4 sur lesquelles le moteur s’appuie réellement, pourquoi cette version sert de plancher strict plutôt que de simple recommandation, et comment un build de rétrogradation distinct garde ouverte la possibilité de fonctionner sur un runtime plus ancien, sans affaiblir le code que tu lis.

Un moteur PDF transforme une entrée ambiguë en un format de fichier exact au byte près. Le PDF est un format établi de longue date, régi par des règles strictes et stables, et assez exigeant pour qu’une hypothèse erronée coûte cher. Le langage dans lequel le moteur est écrit est le premier niveau où ces hypothèses sont soit interceptées, soit laissées passer sans contrôle. Un plancher de version n’est pas une restriction gratuite. C’est le seuil en dessous duquel le moteur ne peut plus offrir les garanties de typage dont dépend le reste de sa conception.

Si ce plancher est flou, deux coûts apparaissent. Le code se remplit de couches de compatibilité qui masquent la logique réelle. Le système de types cesse aussi de porter le raisonnement, ce qui est précisément la propriété qu’un pipeline de documents ne peut pas se permettre de perdre.

  • Le paquet core déclare "php": ">=8.4 <9.0". Il s’agit de la contrainte effective, vérifiable dans composer.json, pas d’une ambition formulée dans la documentation.
  • PHP 8.4 est le plancher parce que le moteur utilise les fonctionnalités du langage 8.4 (et des versions 8.x récentes) comme garanties structurelles : visibilité asymétrique, enums adossés dotés de comportement, constantes de classe typées, état readonly et arguments nommés de première classe dans l’API publique.
  • L’exécution sur PHP 8.1–8.3 reste possible grâce à un build de rétrogradation distinct (le rétroportage). C’est de l’outillage de build, pas une dépendance de runtime. Il ne modifie pas le code que tu lis dans le dépôt core.
  • La borne supérieure <9.0 est délibérée : une nouvelle version majeure de PHP est traitée comme un changement à valider, et non comme une compatibilité à présumer.

Le plancher est fixé par ce que fait le code. La manière la plus directe de l’expliquer consiste donc à montrer les fonctionnalités dans le code, plutôt qu’à les énumérer de façon abstraite.

La visibilité asymétrique permet de rendre un état lisible publiquement mais modifiable uniquement en privé, sans écrire d’accesseur à la main pour chaque champ. Le contexte de rendu l’utilise directement :

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

À elle seule, cette fonctionnalité du langage élimine toute une catégorie de mutations externes accidentelles. Le curseur ne peut pas être déplacé depuis l’extérieur du moteur. La garantie est appliquée par le runtime, et non par une convention que les relecteurs devraient garder en mémoire.

Les enums adossés dotés de comportement remplacent des drapeaux booléens dispersés et des constantes de chaîne par une valeur typée unique, capable aussi de répondre à des questions sur elle-même. Le discriminant de conformité du document est un enum adossé dont les méthodes décident des résultats exigés par la spécification :

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 est l’unique source de vérité typée pour « ce document est-il balisé selon la spécification ? » et « quelle partie ISO s’applique ? ». Lorsque ces questions étaient exprimées sous forme de booléens peu contraints, plusieurs endroits pouvaient y répondre de manière incohérente.

Les constantes de classe typées intègrent même les constantes au contrat de typage. Les limites strictes du moteur HTML sont déclarées sous forme de constantes typées :

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

Les arguments nommés font partie de la surface de l’API publique, pas d’une astuce interne. Les programmes d’exemple les utilisent dans les appels qu’un lecteur est censé reprendre :

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

Il ne s’agit pas d’usages décoratifs d’une nouvelle syntaxe. Chacun convertit une convention qu’un relecteur devrait autrement faire respecter à la main en une propriété que le runtime applique.

Cette page est étayée par Evidence: Code-backed . Chaque affirmation ci-dessus correspond à un fichier du dépôt core, pas à une simple liste de fonctionnalités :

  • La contrainte de version correspond à la valeur require.php ">=8.4 <9.0" dans le composer.json du core.
  • L’exemple de visibilité asymétrique reprend le style réel de déclaration de src/Core/RenderingContext.php (champs public private(set)).
  • L’exemple d’enum reflète src/Conformance/ConformanceMode.php, un enum … : string adossé dont les méthodes fondées sur match pilotent les décisions de conformité.
  • Les constantes typées se trouvent dans src/Html/HtmlParser.php (private const int MAX_NESTING_DEPTH, MAX_ELEMENT_COUNT).
  • L’appel à argument nommé provient des programmes livrés dans examples/.

Le plancher a aussi une dimension normative. Le rôle du moteur est d’émettre des fichiers conformes à Spec: ISO 32000-2, §7.5.2 . Un rédacteur PDF 2.0 conforme doit déclarer la version du document à 2.0, dans l’en-tête du fichier ou dans le catalogue. Respecter une obligation aussi précise est bien plus simple lorsque le langage sur lequel repose le rédacteur rend un état incohérent difficile à construire dès le départ. Le plancher de version et la rigueur du format vont dans le même sens.

Le plus petit programme correct sollicite déjà le plancher. Il fonctionne sur PHP 8.4, utilise un argument nommé et produit un fichier 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');

Rien ici n’est exotique. Le point essentiel est que la même mécanique de typage strict, d’enums et de visibilité asymétrique qui rend les rouages internes du moteur dignes de confiance est déjà active sous ce programme de cinq lignes. Tu n’as rien à activer explicitement.

Le contresens le plus fréquent consiste à croire que « requiert PHP 8.4 » signifie « ne fonctionnera pas tant que tu n’auras pas migré vers PHP 8.4 ». Cela signifie que le code source du core cible PHP 8.4. Un build de rétrogradation distinct existe pour les équipes figées sur PHP 8.1–8.3.

Il est important d’être précis sur ce qu’est ce build. C’est un pipeline de rétrogradation basé sur Rector qui transforme le code source 8.4 en une sortie à la syntaxe plus ancienne. C’est une infrastructure de build, pas une bibliothèque de runtime que tu ajoutes aux dépendances de ton application. Il n’introduit pas de code parallèle au typage affaibli. Le code relu dans ces pages et le code livré sont un seul et même code. Le rétroportage est une transformation qui lui est appliquée, et non une alternative.

Cette page explique pourquoi PHP 8.4 est le plancher et ce que le rétroportage préserve. Elle ne documente pas l’exécution du pipeline de rétrogradation, ses versions cibles prises en charge ni ses mises en garde opérationnelles. Cela relève de la documentation propre au build de rétroportage. L’organisation interne des paquets de cet outillage est hors de portée ici. Les usages de fonctionnalités présentés illustrent le style du moteur. Ils ne constituent pas l’inventaire complet de chaque fonctionnalité 8.x utilisée par le code. Les API exactes sont définies par la référence, pas par cette explication. La contrainte de version est exacte à la date de relecture de cette page. La valeur faisant autorité est toujours le bloc require du composer.json du core.

L’édition ne change rien au plancher du langage. Chaque édition est construite à partir du même code source PHP 8.4 :

PHP 8.4 source floor — edition availability
Edition Availability
Core Le core est écrit pour PHP 8.4.
Pro Pro s’appuie sur le même plancher de code source 8.4.
Enterprise Enterprise s’appuie sur le même plancher de code source 8.4.
  • Plancher de version — la version PHP minimale ciblée par le code source du core (>=8.4). En dessous, les garanties de typage du moteur ne peuvent pas être exprimées.
  • Visibilité asymétrique — une fonctionnalité de PHP 8.4 permettant à une propriété d’être lisible publiquement mais modifiable uniquement depuis une portée plus restreinte (public private(set)).
  • Enum adossé — un enum PHP dont les cas ont des valeurs scalaires et qui peut embarquer du comportement (méthodes), utilisé ici comme source de vérité typée unique.
  • Rétroportage — le build de rétrogradation distinct basé sur Rector qui transforme le code source 8.4 en une sortie exécutable sur des versions plus anciennes de PHP. De l’outillage de build, pas une dépendance de runtime.
  • Mode de conformité — le discriminant typé du moteur qui détermine quel contrat de conformité ISO un document doit satisfaire.