Pular para o conteúdo

Fundamentos do PHP 8.4

Spec: ISO 32000-2, §7.5.2 Evidence: Code-backed Restrição de PHP: ≥8.4 <9.0

O NextPDF requer PHP 8.4. Esta página explica de quais recursos de linguagem do 8.4 o motor depende, por que essa versão é um piso rígido e não apenas uma recomendação, e como um build de downgrade separado mantém aberta a opção de execução em um runtime mais antigo sem enfraquecer a base de código que você lê.

Um motor de PDF transforma entradas ambíguas em um formato de arquivo exato byte a byte. O PDF é um formato consolidado há muito tempo, com regras firmes e fixas, e rigoroso o bastante para que um palpite errado custe caro. A linguagem em que o motor é escrito é o primeiro lugar onde esses palpites são detectados ou seguem adiante sem verificação. Um piso de versão não é uma restrição por si só. É a linha abaixo da qual o motor deixa de oferecer as garantias de tipo das quais o restante do design depende.

Se esse piso for vago, surgem dois custos. A base de código se enche de remendos de compatibilidade que obscurecem a lógica real. O sistema de tipos também deixa de ser estrutural, exatamente a propriedade que um pipeline de documentos não pode se dar ao luxo de perder.

  • O pacote core declara "php": ">=8.4 <9.0". Essa é a restrição real, verificável em composer.json, não uma aspiração da documentação.
  • 8.4 é o piso porque o motor usa recursos de linguagem do 8.4 (e do 8.x recente) como garantias estruturais: visibilidade assimétrica, enums com valor associado e comportamento, constantes de classe tipadas, estado readonly e argumentos nomeados como cidadãos de primeira classe na API pública.
  • Executar em PHP 8.1–8.3 ainda é possível por meio de um build de downgrade separado (o backport). É ferramental de build, não uma dependência de runtime. Ele não altera o código que você lê no repositório core.
  • O limite superior <9.0 é deliberado: um novo lançamento major do PHP é tratado como algo a validar, não a presumir.

O piso é definido pelo que o código faz. Portanto, a maneira mais honesta de explicá-lo é mostrar os recursos no código, em vez de listá-los de forma abstrata.

A visibilidade assimétrica permite que o estado seja legível publicamente, mas gravável apenas de forma privada, sem exigir um getter escrito à mão para cada campo. O contexto de renderização a usa diretamente:

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

Esse único recurso de linguagem elimina toda uma categoria de mutação externa acidental. O cursor não pode ser movido de fora do motor. A garantia é imposta pelo runtime, não por uma convenção que revisores precisam lembrar.

Enums com valor associado e comportamento substituem flags booleanas e constantes de string espalhadas por um único valor tipado, que também responde a perguntas sobre si mesmo. O discriminador de conformidade do documento é um enum com valor associado cujos métodos decidem resultados no nível da especificação:

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

O enum é a fonte única da verdade para “este documento está marcado conforme a especificação?” e “qual parte da ISO se aplica?”. Quando essas perguntas eram expressas como booleanos soltos, vários pontos do código podiam respondê-las de forma inconsistente.

As constantes de classe tipadas tornam até mesmo as constantes parte do contrato de tipos. Os limites rígidos do motor de HTML são declarados como constantes tipadas:

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

Os argumentos nomeados fazem parte da superfície pública da API; não são um truque interno. Os programas de exemplo os passam em pontos de chamada que o leitor deve copiar:

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

Esses não são usos decorativos de uma sintaxe nova. Cada um transforma uma convenção que, de outra forma, um revisor teria de impor manualmente em uma propriedade que o runtime impõe.

Esta página é Evidence: Code-backed . Cada afirmação acima corresponde a um arquivo no repositório core, não a uma lista de recursos:

  • A restrição de versão é o valor de require.php ">=8.4 <9.0" no composer.json do core.
  • O exemplo de visibilidade assimétrica é o estilo de declaração real em src/Core/RenderingContext.php (campos public private(set)).
  • O exemplo de enum reflete src/Conformance/ConformanceMode.php, um enum … : string com valor associado, cujos métodos baseados em match conduzem as decisões de conformidade.
  • As constantes tipadas estão em src/Html/HtmlParser.php (private const int MAX_NESTING_DEPTH, MAX_ELEMENT_COUNT).
  • A chamada com argumento nomeado vem dos programas examples/ distribuídos.

O piso também tem uma dimensão normativa. A tarefa do motor é emitir arquivos que estejam em conformidade com a Spec: ISO 32000-2, §7.5.2 . Um gerador de PDF 2.0 em conformidade deve declarar a versão do documento como 2.0 no cabeçalho do arquivo ou no catálogo. Cumprir uma obrigação tão exata é muito mais fácil quando a linguagem por baixo do gerador dificulta a construção de um estado inconsistente desde o início. O piso de versão e o rigor do formato estão alinhados.

O menor programa correto já exercita o piso. Ele executa em PHP 8.4, usa um argumento nomeado e produz um arquivo 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 aqui é exótico. O ponto é que o mesmo maquinário de tipagem estrita, enums e visibilidade assimétrica que torna confiáveis as partes internas do motor já está ativo sob este programa de cinco linhas. Você não precisa optar por ele.

A leitura equivocada mais comum é que “requer PHP 8.4” significa “não vai funcionar a menos que você atualize para o 8.4.” Significa que o código-fonte do core tem o 8.4 como alvo. Existe um build de downgrade separado para equipes presas ao PHP 8.1–8.3.

É importante ser preciso sobre o que esse build é. É um pipeline de downgrade baseado em Rector que transforma o código-fonte do 8.4 em uma saída com sintaxe mais antiga. É infraestrutura de build, não uma biblioteca de runtime que você adiciona às dependências da aplicação. Ele não introduz uma base de código paralela, com tipagem mais fraca. O código revisado nestas páginas e o código distribuído são o mesmo código. O backport é uma transformação aplicada a ele, não uma alternativa.

Esta página explica por que 8.4 é o piso e o que o backport preserva. Ela não documenta como executar o pipeline de downgrade, suas versões de destino suportadas nem suas ressalvas operacionais. Isso pertence à documentação do próprio build de backport. A organização interna de pacotes desse ferramental está fora do escopo aqui. Os usos de recursos mostrados ilustram o estilo do motor. Eles não são o inventário completo de todos os recursos do 8.x que a base de código usa. As APIs exatas são definidas pela referência, não por esta explicação. A restrição de versão está correta na data de revisão desta página. O valor autoritativo é sempre o bloco require no composer.json do core.

A edição não influencia o piso de linguagem. Toda edição é construída a partir do mesmo código-fonte PHP 8.4:

PHP 8.4 source floor — edition availability
Edition Availability
Core O Core é escrito para o PHP 8.4.
Pro O Pro é construído sobre o mesmo piso de código-fonte 8.4.
Enterprise O Enterprise é construído sobre o mesmo piso de código-fonte 8.4.
  • Piso de versão — a versão mínima de PHP que o código-fonte do core tem como alvo (>=8.4). Abaixo dela, as garantias de tipo do motor não podem ser expressas.
  • Visibilidade assimétrica — um recurso do PHP 8.4 que permite que uma propriedade seja legível publicamente, mas gravável apenas a partir de um escopo mais restrito (public private(set)).
  • Enum com valor associado — um enum do PHP cujos casos têm valores escalares e que pode carregar comportamento (métodos), usado aqui como uma fonte única e tipada da verdade.
  • Backport — o build de downgrade separado, baseado em Rector, que transforma o código-fonte do 8.4 em uma saída executável em PHP mais antigo. Ferramental de build, não uma dependência de runtime.
  • Modo de conformidade — o discriminador tipado do motor para qual contrato de conformidade ISO um documento deve satisfazer.