Pro edição
Diff
Visão geral
Seção intitulada “Visão geral”NextPDF\Pro\Diff compara dois documentos PDF e relata o que mudou. O
caminho rápido produz um diff de texto alinhado por página; o caminho estruturado
adiciona detecção de alterações de imagem e metadados e formata o resultado como
JSON ou HTML.
Disponibilidade e licenciamento
Seção intitulada “Disponibilidade e licenciamento”Este recurso vem no NextPDF Pro (nextpdf/pro) e é ativado com um
envelope de licença de nível Pro. Uma implantação sem esse direito de uso não carrega
as classes do recurso. Compare edições e
obtenha uma licença.
Nenhum sinalizador de capacidade em tempo de execução restringe as classes do Diff; elas estão presentes sempre que o pacote Pro está instalado.
Instalação
Seção intitulada “Instalação”composer require nextpdf/pro:^3Visão conceitual
Seção intitulada “Visão conceitual”PdfDiffer::compare() extrai o texto por página de cada documento, divide-o
em linhas e executa um diff de linhas de Myers por par de páginas, produzindo
regiões adicionadas, removidas e modificadas. A extração de texto analisa os
operadores de exibição de texto da ISO 32000-2:2020 §9.4 (Tj, TJ, ').
StructuredDiffer se baseia nisso: ele agrupa regiões de texto em alterações
no nível de parágrafo, compara imagens incorporadas, compara metadados e produz um
StructuredDiffResult com um resumo agregado. DiffFormatter serializa
esse resultado em uma string JSON ou em um fragmento de relatório HTML.
Quando o leitor de PDF opcional do Artisan está instalado, a extração de texto o utiliza para conteúdo preciso por página; caso contrário, um fallback limitado em nível de byte varre os streams de conteúdo diretamente.
Por que funciona assim
Seção intitulada “Por que funciona assim”O diferenciador compara texto e estrutura extraídos, não pixels renderizados. Uma
comparação estrutural é determinística, barata e mapeia para as alterações editoriais
que um revisor considera importantes. Um diff de pixels, em vez disso, sinalizaria ruído
de antialiasing e font-hinting como conteúdo. Como um PDF armazena glifos e posicionamento,
e não caracteres prontos para leitura, cada comparação primeiro reconstrói o texto a partir do
stream de conteúdo. Essa etapa de extração é o motivo pelo qual o leitor do Artisan aprimora
a precisão, pelo qual o fallback limitado de FlateDecode troca cobertura por segurança e
pelo qual páginas digitalizadas mal geram diff. O alinhamento de páginas permanece baseado em
índice para previsibilidade, então uma página inserida é lida como um deslocamento claro a jusante.
Contexto de design: Por que o texto em um PDF não é realmente texto.
Contrato de comportamento
Seção intitulada “Contrato de comportamento”- Entrada. Bytes brutos do PDF para origem e destino. Um buffer que não comece com
%PDFgeraInvalidArgumentException. - Saída (caminho rápido).
DiffResultcom as listas de regiõesadded,removedemodified, maisisIdentical(),hasDifferences(),totalChanges(). - Saída (caminho estruturado).
StructuredDiffResultcom diffs de parágrafo, diffs de imagem, alterações de metadados e umDiffSummary. - Saída de relatório.
DiffFormatteremite uma string JSON ou um fragmento HTML. Ele não produz um PDF visual de redlining lado a lado. - Limites de recursos. O tamanho do stream de conteúdo descomprimido é limitado para proteger contra bombas de descompressão; o scanner em nível de byte evita backtracking catastrófico de regex em entradas elaboradas.
- Determinismo. Para entradas idênticas, as regiões de diff e a saída formatada são estáveis.
Superfície pública da API
Seção intitulada “Superfície pública da API”| Type | Kind | Key members |
|---|---|---|
NextPDF\Pro\Diff\PdfDiffer | final class | static compare(string $sourcePdf, string $targetPdf): DiffResult, static compareTexts(array $sourcePages, array $targetPages): DiffResult, static extractText(string $contentStream): string |
NextPDF\Pro\Diff\StructuredDiffer | final class | __construct(?ImageDiffer $imageDiffer = null, ?MetadataDiffer $metadataDiffer = null), compare(string $sourcePdf, string $targetPdf): StructuredDiffResult |
NextPDF\Pro\Diff\DiffFormatter | final class | toJson(StructuredDiffResult $result): string, toHtml(StructuredDiffResult $result): string |
NextPDF\Pro\Diff\DiffResult | final readonly class | array $added, array $removed, array $modified, isIdentical(): bool, hasDifferences(): bool, totalChanges(): int |
NextPDF\Pro\Diff\StructuredDiffResult | final readonly class | text diff, paragraphs, images, metadata changes, summary |
NextPDF\Pro\Diff\DiffType | enum | Added, Removed, Modified, Unchanged |
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”<?php
declare(strict_types=1);
use NextPDF\Pro\Diff\PdfDiffer;
$diff = PdfDiffer::compare( file_get_contents('v1.pdf'), file_get_contents('v2.pdf'),);
if ($diff->hasDifferences()) { echo $diff->totalChanges(), " text changes detected\n";}Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”<?php
declare(strict_types=1);
use NextPDF\Pro\Diff\DiffFormatter;use NextPDF\Pro\Diff\StructuredDiffer;
function reviewReport(string $oldPdf, string $newPdf): string{ $result = (new StructuredDiffer())->compare($oldPdf, $newPdf);
// JSON for machine consumption; toHtml() for a review UI fragment. return (new DiffFormatter())->toJson($result);}Casos extremos e armadilhas
Seção intitulada “Casos extremos e armadilhas”- O diff é alinhado por índice de página. Inserir uma página no início desloca todas as páginas posteriores e relata grandes alterações subsequentes — isso é esperado para uma comparação alinhada por índice.
- A comparação de imagens detecta imagens incorporadas adicionadas, removidas e modificadas; ela não é um diff visual perceptual e não renderiza páginas em pixels.
- PDFs digitalizados apenas com imagens produzem pouco ou nenhum diff de texto porque nenhum OCR é executado.
- Sem o leitor opcional do Artisan, a extração usa o fallback limitado; documentos muito comprimidos podem gerar cobertura de texto reduzida.
Desempenho
Seção intitulada “Desempenho”A extração de texto é linear nos bytes do documento; o diff de Myers é
quase linear para documentos semelhantes e quadrático no pior caso por par de
páginas. O limite de descompressão limita a memória. Consulte performance_budget.
Notas de segurança
Seção intitulada “Notas de segurança”O fallback em nível de byte usa varredura baseada em strpos em vez de regex
ilimitada para evitar backtracking catastrófico em PDFs elaborados, e limita
a saída de descompressão. O diff não executa scripts incorporados. Consulte o
modelo de segurança do Core.
Conformidade
Seção intitulada “Conformidade”| Claim | Spec clause | Status |
|---|---|---|
Operador de texto Tj analisado para extração | ISO 32000-2:2020 §9.4 | Verificado (conjunto de testes unitários) |
Operador de texto em array TJ analisado para extração | ISO 32000-2:2020 §9.4 | Verificado (conjunto de testes unitários) |
| Saída de PDF visual de redlining lado a lado | — | Não suportado (apenas JSON/HTML) |
Fallback / alternativa do Core
Seção intitulada “Fallback / alternativa do Core”Não existe equivalente no Core para comparação de documentos. O leitor opcional do Artisan melhora a precisão da extração quando instalado, mas não é obrigatório.
Nota sobre o limite do Enterprise
Seção intitulada “Nota sobre o limite do Enterprise”Este é um detector de alterações de conteúdo. Ele não é um analisador forense de diferenças e não produz relatórios probatórios ou de atribuição de adulteração; essas preocupações estão fora do escopo deste módulo.
Limite de publicação
Seção intitulada “Limite de publicação”Esta página documenta apenas o comportamento observável externamente e a superfície pública de API suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismos, nomes de arquivos de runbook e prefixos de tickets estão fora do escopo.