コンテンツにスキップ

Cli: コマンドハンドラと外部バリデータアダプタ

Cli モジュールは、エンジンの診断ツールと適合性ツールを支えるコマンド層です。benchmark、diff、init、verify、capabilities の各コマンドハンドラで構成されています。また、外部 PDF バリデータ(veraPDF、Arlington PDF モデル)を 1 つのインタフェースの背後にラップするアダプタ群でもあります。単一の verify コマンドから、それらのバリデータを駆動できます。

Terminal window
composer require nextpdf/core:^3

各コマンドは、プロセス終了コードを返す execute() を持つハンドラクラスです。BenchmarkHandler はベンチマークシナリオを実行します。DiffHandler はドキュメントを比較します。InitHandler はプロジェクトのひな形を生成します。VerifyHandler は適合性検証を実行します。CapabilitiesHandler はランタイムがサポートする機能を報告します。CliOutput はハンドラ間で共有される軽量な stdout/stderr ライターであり、出力をグローバル状態に結合せず、テスト可能にします。BinaryFinder はホスト上の外部ツールのパスを解決します(@since 2.5.0)。

検証まわりが、アーキテクチャ上の要点です。AlternateValidatorAdapter は、外部バリデータ向けのアダプタが実装するインタフェースです。validate() は PDF パスと ComplianceFlavour を受け取り、ComplianceValidationResult を返します。isAvailable() は、背後のツールがインストールされているかどうかを報告します。toolIdentifier() はそのツール名を示します。VeraPdfCliAdapterArlingtonValidatorAdapterAsyncValidatorAdapter がこれを実装します。つまり、エンジンはサードパーティのバリデータを再実装せず、参照ツールを実行して、その判定を正規化します。インストールされていないバリデータは、実行を失敗させる代わりに isAvailable() === false を報告するため、検証は明示的に縮退します。アダプタは @since 3.0.0 で、コアハンドラは @since 2.3.0@since 2.5.0 です。

クラス主なメンバー役割
BenchmarkHandlerexecute(string $format = 'pretty', ?string $scenario = null): intベンチマークシナリオの実行(@since 2.4.0
VerifyHandlerexecute(): int適合性検証の駆動
DiffHandler / InitHandlerexecute(): intドキュメント差分 / プロジェクトのひな形
CapabilitiesHandlerexecute(string $format = 'pretty'): intランタイム機能の報告(@since 2.3.0
AlternateValidatorAdapter(インタフェース)validate(), isAvailable(), toolIdentifier()外部バリデータの契約(@since 3.0.0
VeraPdfCliAdapterアダプタを実装veraPDF CLI のラップ(@since 3.0.0
ArlingtonValidatorAdapterアダプタを実装Arlington PDF モデルのラップ(@since 3.0.0
AsyncValidatorAdapterアダプタを実装非同期対応のバリデータラッパー(@since 3.0.0
CliOutputwrite(), writeln(), error()テスト可能な stdout/stderr ライター(@since 2.3.0
BinaryFinder外部ツールのパス解決ホスト上のツールの検出(@since 2.5.0

完全な PHPDoc テーブルは、composer docs:generate-api-php -- --module=Cli を実行して確認してください。

ソース: examples/33-validate-conformance.php。バリデータアダプタを選択し、使用前に利用可否を確認します。

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Cli\VeraPdfCliAdapter;
use NextPDF\Compliance\ComplianceFlavour;
$validator = new VeraPdfCliAdapter(/* binary path / process factory */);
if (!$validator->isAvailable()) {
fwrite(STDERR, "veraPDF is not installed; conformance verification skipped.\n");
exit(2);
}
$result = $validator->validate('/srv/out/report.pdf', ComplianceFlavour::PdfA4);
echo $result->isCompliant() ? "PASS\n" : "FAIL\n";

利用可能なバリデータを通じて検証を実行し、存在しないツールは失敗ではなく、スキップされたチェックとして扱います。

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Cli\AlternateValidatorAdapter;
use NextPDF\Compliance\ComplianceFlavour;
use Psr\Log\LoggerInterface;
final readonly class ConformanceGate
{
/** @param list<AlternateValidatorAdapter> $validators */
public function __construct(
private array $validators,
private LoggerInterface $logger,
) {}
public function verify(string $pdfPath, ComplianceFlavour $flavour): bool
{
$ran = false;
foreach ($this->validators as $validator) {
if (!$validator->isAvailable()) {
$this->logger->info('Validator absent; skipped.', ['tool' => $validator->toolIdentifier()]);
continue;
}
$ran = true;
if (!$validator->validate($pdfPath, $flavour)->isCompliant()) {
$this->logger->error('Conformance failed.', ['tool' => $validator->toolIdentifier()]);
return false;
}
}
// No validator available is not a pass — surface it.
return $ran;
}
}
  • 利用できないバリデータは isAvailable() === false を返します。例外をスローしません。「バリデータが利用できない」状態は合格ではありません。本番サンプルと同様に、これを明確に区別して扱ってください。
  • アダプタは外部バイナリを実行します。その判定は外部ツールの判定を正規化したものであり、独自の再実装ではありません。ツールは最新の状態に保ってください。
  • ハンドラの execute() はプロセス終了コードを返します。ゼロ以外は失敗です。無視せず、ラッパーから伝播させてください。
  • BinaryFinder はホスト上のツールパスを解決します。ホストが異なると、異なるバージョンのツールが解決される場合があります。再現可能な検証のために、環境を固定してください。
  • 再現性プロファイルは structural です。検証レポートにはタイムスタンプとツールバージョンが含まれるため、2 回の実行ではこれらのフィールドが異なります。

ハンドラのオーバーヘッドはごくわずかです。コストの大半は外部バリデータのプロセスが占め、大きなドキュメントでは遅くなることがあります。AsyncValidatorAdapter は、そのレイテンシをオーバーラップさせるために存在します。1500 ms 実時間 / 64 MB ピークの performance_budget はエンジンの基準値であり、外部バリデータに対する上限ではありません。ベンチマーク出力は構造上は決定的ですが、その性質上、タイミングデータを含みます。

アダプタは PDF パスを指定して外部プロセスを起動します。PDF は信頼できない入力として扱ってください。検証は制約された環境で実行してください。外部バリデータは敵対的なデータを解析します。意図しないファイルへのパストラバーサルを避けるため、ファイルパスをハンドラに渡す前に検証し、正規化してください。サニタイズしていないユーザー入力を、コマンド引数として渡さないでください。アダプタはシェル文字列ではなく、プロセス引数を構築します。それでも入力ファイル自体は攻撃者の制御下にあります。エンジンの脅威モデルについては /modules/core/security/ を参照してください。

このモジュールは、PDF 仕様に関する独自の規範的主張を行いません。参照バリデータ(PDF/A と PDF/UA には veraPDF、ISO 32000-2 の構造規則には Arlington PDF モデル)に委譲することで、適合性検証を オーケストレーション します。正式な適合性判定は外部ツールによるものです。このモジュールはその結果を正規化して報告します。エンドツーエンドの適合性とゴールデンベースラインについては /modules/core/conformance/ で説明しています。