Analise e inspecione fatos estruturais de um PDF
Visão geral
Seção intitulada “Visão geral”Esta receita usa o fallback Quick do inspetor do Core para ler fatos estruturais de um arquivo Portable Document Format (PDF). Com ela, você obtém a versão, a contagem de páginas, o sinalizador de criptografia, o sinalizador de assinatura, o sinalizador de anexo, o tamanho do arquivo e os sinalizadores de risco. O Quick é executado integralmente dentro do processo, sem o sidecar Spectrum e sem acesso à rede. Use-o para triagem rápida, não como validador.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Visão conceitual
Seção intitulada “Visão conceitual”Um arquivo PDF registra a versão no cabeçalho do arquivo (ISO 32000-2 §7.5.2). O trailer contém um identificador de arquivo (/ID) como duas byte strings (ISO 32000-2 §7.5.5). Quando há uma assinatura, um dicionário de assinatura armazena Cryptographic Message Syntax (CMS) SignedData codificado em Distinguished Encoding Rules (DER) em Contents (ISO 32000-2 §12.8.1). O fallback Quick usa uma varredura limitada dos bytes do documento para derivar a versão, uma estimativa da contagem de páginas e os sinalizadores de presença de criptografia, assinatura e anexo.
Superfície da API
Seção intitulada “Superfície da API”Crie new Inspector() e depois chame ->inspect(string $pdfData, InspectConfig::quick()). Ele retorna um InspectResult com $pdfVersion, $pageCount, $isEncrypted, $hasSigned, $hasAttachments, $fileSizeBytes, $riskFlags e o auxiliar hasRisks().
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Inspect\InspectConfig;use NextPDF\Inspect\Inspector;
$pdf = file_get_contents(__DIR__ . '/document.pdf');$result = (new Inspector())->inspect($pdf, InspectConfig::quick());
printf( "v%s, %d page(s), encrypted=%s, signed=%s\n", $result->pdfVersion ?? '?', $result->pageCount, $result->isEncrypted ? 'yes' : 'no', $result->hasSigned ? 'yes' : 'no',);Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Este programa autossuficiente é executado no harness do cookbook. Ele espelha examples/39-parse-and-inspect-pdf.php: constrói um pequeno PDF de várias páginas na memória, lê os fatos estruturais com o fallback Quick e roteia com base nesses fatos, nunca em um veredito de confiança. O ramo de roteamento é ilustrativo. Substitua-o pelo seu próprio pipeline, fila de verificação e quarentena.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Inspect\InspectConfig;use NextPDF\Inspect\Inspector;
// A self-contained input so the program runs with no external file.$doc = Document::createStandalone();$doc->setTitle('Parse-and-inspect demo');$doc->setAuthor('NextPDF Cookbook');$doc->addPage();$doc->setFont('helvetica', '', 12);$doc->cell(0, 10, 'Page one of the parse-and-inspect demonstration.', newLine: true);$doc->addPage();$doc->cell(0, 10, 'Page two.', newLine: true);$pdf = $doc->getPdfData();
$result = (new Inspector())->inspect($pdf, InspectConfig::quick());
echo 'PDF version : ' . ($result->pdfVersion ?? 'unknown') . "\n";echo 'Pages : ' . $result->pageCount . "\n";echo 'Encrypted : ' . ($result->isEncrypted ? 'yes' : 'no') . "\n";echo 'Signed : ' . ($result->hasSigned ? 'yes' : 'no') . "\n";echo 'Attachments : ' . ($result->hasAttachments ? 'yes' : 'no') . "\n";echo 'File size : ' . $result->fileSizeBytes . " bytes\n";echo 'Risk flags : ' . ($result->hasRisks() ? count($result->riskFlags) : 0) . "\n";
// Route on structural facts, not trust verdicts. Replace these calls with// your own pipeline / verifier queue / quarantine.if ($result->isEncrypted) { // $pipeline->decryptThenContinue($pdf); echo "Route: decrypt-then-continue\n";} elseif ($result->hasSigned) { // $verifierQueue->enqueue($pdf); // see the signature-inspect recipe echo "Route: enqueue for cryptographic verification\n";} elseif ($result->hasRisks()) { // $quarantine->hold($pdf, $result->riskFlags); echo "Route: quarantine (risk flags present)\n";} else { // $pipeline->continue($pdf); echo "Route: continue (no risks, unsigned, unencrypted)\n";}
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script under the// semantic profile; emit the document to the side-channel.$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');file_put_contents($out !== false && $out !== '' ? $out : __DIR__ . '/inspected.pdf', $pdf);Saída padrão (STDOUT) esperada (a versão e o tamanho dependem do build; o PDF de demonstração não está criptografado nem assinado e está livre de riscos):
PDF version : <version>Pages : 2Encrypted : noSigned : noAttachments : noFile size : <n> bytesRisk flags : 0Route: continue (no risks, unsigned, unencrypted)Casos extremos e pegadinhas
Seção intitulada “Casos extremos e pegadinhas”- O Quick é triagem, não validação. Ele relata o que está presente e o que está ausente. Ele não verifica assinaturas, não descriptografa conteúdo nem afirma conformidade. Trate o resultado como entrada de roteamento.
- A contagem de páginas é uma estimativa. O fallback Quick conta os marcadores de objeto de página. Um grafo de objetos deliberadamente malformado pode distorcer a contagem. Use as profundidades com suporte do Spectrum quando precisar de uma contagem exata.
- Standard/Full precisam do sidecar.
new InspectConfig()(profundidadeStandard) eInspectConfig::full()exigem o sidecar Spectrum. Eles lançamINSPECT-SIDECAR-001quando ele está indisponível e não fazem downgrade silencioso para o Quick. - Entrada vazia. Passar uma string vazia lança uma exceção de inspeção com “PDF data must not be empty”.
- Escopo do sinalizador de criptografia. O sinalizador reflete uma entrada
/Encryptno trailer. Um arquivo com esse sinalizador não é descriptografado pelo inspetor.
Desempenho
Seção intitulada “Desempenho”O fallback Quick usa uma varredura limitada, não uma análise completa. Use-o para pré-rotear grandes volumes de arquivos recebidos antes de um processamento mais pesado.
Notas de segurança
Seção intitulada “Notas de segurança”O inspetor é executado dentro do processo e lê apenas marcadores estruturais. Nenhum byte do documento sai do host e nenhum texto do documento é extraído. Um sinalizador de risco, como JavaScript incorporado, é um sinal consultivo para roteamento. Não é uma afirmação de que o arquivo é seguro ou inseguro.
Conformidade
Seção intitulada “Conformidade”| Declaração | Especificação | Cláusula | reference_id |
|---|---|---|---|
| O cabeçalho do arquivo registra a versão do PDF. | ISO 32000-2 | §7.5.2 | |
O /ID do trailer é um identificador de arquivo composto por duas byte strings. | ISO 32000-2 | §7.5.5 | |
O Contents de um dicionário de assinatura contém CMS SignedData em DER. | ISO 32000-2 | §12.8.1 |
Esta receita relata apenas fatos estruturais. Ela não afirma que o arquivo é válido, seguro ou conforme.
Contexto comercial
Seção intitulada “Contexto comercial”As profundidades de inspeção Standard e Full são executadas pelo sidecar Spectrum. Elas adicionam uma análise mais rica de objetos, fontes e imagens. O fallback Quick documentado aqui faz parte do Core e funciona offline.