Pular para o conteúdo

Support: utilitários compartilhados, Clock e Sleeper

O módulo Support contém utilitários compartilhados que o engine usa internamente. Ele também expõe uma pequena superfície pública: o relógio do sistema da PHP Standards Recommendation 20 (PSR-20), o pipeline de coleta de avisos e as primitivas de serialização do Portable Document Format (PDF). A maior parte do namespace é infraestrutura interna. Esta página documenta as partes em que você pode confiar e identifica as partes destinadas apenas a uso interno.

Terminal window
composer require nextpdf/core:^3

Relógio (PSR-20). SystemClock implementa Psr\Clock\ClockInterface. O método now() retorna o horário atual como um DateTimeImmutable. O modelo PSR-20 define uma interface de relógio com uma operação de leitura que retorna o horário atual como um valor de data-hora imutável (PSR-20 psr_20_clock#2.1). SystemClock é o padrão; o engine o usa quando você não injeta um relógio. Para usar um horário fixo em testes, injete um relógio congelado que implemente a mesma interface. Combine o relógio com Config::deterministic quando precisar de uma saída idêntica byte a byte.

Pipeline de avisos. WarningCollector é o principal mecanismo em memória para problemas de renderização não fatais. O engine anexa um Warning para cada degradação determinística, como uma coluna de tabela comprimida, uma fonte não resolvida ou um glifo ausente. Após a geração, você lê os avisos por meio de Document::getWarnings(). Um Warning é um value object imutável. Ele carrega um WarningCode, um WarningSeverity (warning ou degraded), a página, o tipo de elemento, o id do recurso, uma flag de paridade degradada, uma mensagem, um DegradationImpact e um id de capacidade opcional. WarningCode é um enum baseado em string com identificadores estáveis. Os identificadores usam o prefixo NEXTPDF_W_, como NEXTPDF_W_FONT_UNRESOLVED, para que você possa compará-los com segurança em testes. addWithPolicy() aplica a DegradationPolicy ativa. Com uma política estrita, um impacto de conformidade, semântico ou de bloqueio lança DegradedException. Com uma política equilibrada, apenas um impacto de bloqueio lança. Uma política permissiva nunca lança.

Primitivas de PDF. PdfStringEscaper é a fonte única da verdade para o escape de strings e nomes em PDF. escapeLiteral() faz o escape dos caracteres exigidos em uma string literal de PDF: barra invertida, parênteses, retorno de carro (CR), avanço de linha (LF), tabulação horizontal (HT), backspace (BS) e avanço de formulário (FF). Ele também remove o byte NUL. escapeName() codifica em hexadecimal os bytes fora da faixa imprimível do American Standard Code for Information Interchange (ASCII) e os bytes do conjunto de delimitadores do PDF para um objeto de nome. BinaryBuffer é um acumulador binário otimizado para escrita, destinado a objetos e streams de PDF. No modo de streaming, ele descarrega para um handle php://temp em documentos grandes. Ele também dá suporte às operações de byte-range exigidas pela incorporação de assinatura. PdfOperators contém as strings de formato dos operadores de content-stream para paths, texto, estado gráfico e fontes. As camadas de desenho e de parser compartilham essas strings.

BinaryBuffer, PdfOperators e a maior parte do restante de NextPDF\Support\ são infraestrutura interna. As camadas de writer e de desenho os usam. Esta página os documenta por completude e para fins de auditoria. Eles não fazem parte da application programming interface (API) pública suportada. Em vez disso, dependa da façade Document e do namespace Contracts. SystemClock, WarningCollector, Warning, WarningCode, WarningSeverity e DegradationImpact são membros públicos.

SímboloTipoVisibilidadeMembros principais
NextPDF\Support\SystemClockfinal classpublicnow(): DateTimeImmutable (PSR-20 ClockInterface)
NextPDF\Support\WarningCollectorfinal classpublicadd(), emit(), addWithPolicy(), getWarnings(), hasWarnings(), hasDegradedParity(), clear()
NextPDF\Support\Warningfinal readonly classpublic$code, $severity, $page, $elementType, $featureId, $degradedParity, $message, $impact, $capabilityId
NextPDF\Support\WarningCodestring enumpublicidentificadores NEXTPDF_W_* estáveis
NextPDF\Support\WarningSeveritystring enumpublicWarning, Degraded
NextPDF\Support\DegradationImpactstring enumpublicCosmetic, LayoutRisk, SemanticLoss, ComplianceRisk, Blocking
NextPDF\Support\PdfStringEscaperfinal readonly classinternalescapeLiteral(), escapeName() (static)
NextPDF\Support\BinaryBufferfinal classinternalwrite(), writeStream(), replaceAt(), extract(), enableStreaming(), getContents()
NextPDF\Support\PdfOperatorsfinal classinternalconstantes de strings de formato dos operadores de content-stream

Leia os avisos coletados após a geração.

<?php
declare(strict_types=1);
use NextPDF\Support\WarningCollector;
$collector = new WarningCollector();
// The engine appends warnings during rendering. After generation:
if ($collector->hasWarnings()) {
foreach ($collector->getWarnings() as $warning) {
\printf(
"[%s] page %d: %s\n",
$warning->code->value,
$warning->page,
$warning->message,
);
}
}

Injete um relógio para tornar o tempo determinístico e trate um aviso de paridade degradada como falha de build.

<?php
declare(strict_types=1);
use NextPDF\Support\SystemClock;
use NextPDF\Support\WarningCollector;
use Psr\Clock\ClockInterface;
// Production uses the real system clock.
$clock = new SystemClock();
$now = $clock->now(); // DateTimeImmutable
$epoch = $now->getTimestamp(); // int
// In tests, swap in any ClockInterface that returns a fixed instant
// (the parameter is typed to the PSR-20 interface, not SystemClock).
function buildReport(ClockInterface $clock): \DateTimeImmutable
{
return $clock->now();
}
$collector = new WarningCollector();
// ... run generation ...
if ($collector->hasDegradedParity()) {
throw new \RuntimeException('Output parity degraded; failing the build.');
}
  • SystemClock::now() retorna um novo DateTimeImmutable a cada chamada. Não presuma que duas chamadas retornem o mesmo instante. Para um horário fixo, injete um relógio congelado.
  • WarningCollector é em memória e por instância. Ele é o canal principal de avisos. O sidecar em JavaScript Object Notation (JSON) e a saída de erro padrão (STDERR) da command-line interface (CLI) são emitidos no limite de saída, não pelo próprio coletor.
  • addWithPolicy() pode lançar DegradedException durante a renderização com uma política estrita. Capture-a no limite de geração se você precisar de saída parcial.
  • WarningCode tem valores que são strings estáveis. Compare pelo case do enum, não pelo texto da mensagem, que é legível para humanos e pode mudar.
  • BinaryBuffer::getLength() é um alias intencional de getOffset() para paridade com a interface de stream. Ambos retornam a mesma contagem de bytes.
  • Trate PdfStringEscaper, BinaryBuffer e PdfOperators como infraestrutura interna. Eles não são cobertos pela promessa de estabilidade da API pública.

SystemClock::now() constrói um objeto e executa em O(1). As inserções de WarningCollector são pushes de lista O(1) amortizado. getWarnings() retorna a lista subjacente. No modo de streaming, BinaryBuffer mantém os dados em memória até o limite maxmemory (padrão 2 MB) antes de descarregar para o disco, o que mantém o pico de memória estável em documentos grandes. O performance_budget padrão desta página de referência é wall_ms: 1500, peak_mb: 64.

Use a superfície do relógio para remover o não determinismo do wall-clock da saída assinada e com timestamp, injetando um relógio fixo junto com Config::deterministic. PdfStringEscaper é o único escaper auditável para a saída de strings e nomes em PDF. Roteie toda emissão de strings por meio dele para evitar injeção de conteúdo causada por parênteses ou delimitadores sem escape em texto fornecido pelo usuário. Os avisos podem carregar detalhes derivados do documento, como tipos de elemento e ids de recurso. Higienize a saída de avisos antes de encaminhá-la para um destino de log de baixa confiança.

EspecificaçãoCláusulaTópico
PSR-20 (PHP-FIG)psr_20_clock#2.1A operação de leitura do relógio retorna uma data-hora imutável
ISO 32000-2:2020§7.3.4.2 / §7.3.5Escape de string literal e de objeto de nome (parafraseado; texto da ISO não citado, nenhum chunk fixado)

SystemClock implementa a ClockInterface da PSR-20. O escaper segue as regras de caracteres de string literal e de objeto de nome do PDF. O texto da ISO é parafraseado conforme a política de citação do site; nenhum chunk literal é fixado.

  • /modules/core/exception/DegradedException lançada por addWithPolicy()
  • /modules/core/contracts/DegradationPolicy, Capability
  • /modules/core/observability/ — encaminhamento de avisos e métricas
  • /modules/core/config/Config::deterministic combina com o relógio
  • /modules/core/writer/ — consumidor interno de BinaryBuffer e PdfOperators

Glossário: PSR-20 · política de degradação · value object