Pro 에디션
Merge — 심층 참조
한눈에 보기
섹션 제목: “한눈에 보기”이 페이지는 NextPDF Pro Merge 모듈 NextPDF\Pro\Merge의 계약 수준 참조입니다. SmartMerger는 여러 입력 문서를 하나로 조립하고 Pro 향상 기능을 적용합니다: 입력별 레이블에서 만들어진 통합 북마크 트리, 전체 문서 중복 제거, 입력별 페이지 범위 선택, 그리고 내부 링크 감지입니다. SemanticSplitter는 이를 보완하는 구조 인식 분할 진입점입니다. 이 페이지는 공개 API, 관찰 가능한 동작 계약, 리소스 한계, 그리고 실패 모드를 기술합니다. 작업 중심의 설정과 예제는 Merge 기능 페이지에 있습니다.
가용성 및 라이선싱
섹션 제목: “가용성 및 라이선싱”이 기능은 NextPDF Pro(nextpdf/pro)로 제공되며 Pro 등급 라이선스 엔벨로프로 활성화됩니다. 해당 권한이 없는 배포 환경에서는 이 기능의 클래스가 로드되지 않습니다. 에디션 비교 및 라이선스 받기.
이 모듈을 게이트하는 런타임 기능 플래그는 없습니다. Merge 클래스는 nextpdf/pro가 설치되고 라이선스가 있으면 언제든지 사용할 수 있습니다.
공개 API 표면
섹션 제목: “공개 API 표면”| 기호 | 매개변수 | 기본 동작 | 반환값 | 예외 또는 실패 조건 | 참고 |
|---|---|---|---|---|---|
SmartMerger::__construct() | ?PdfMerger $coreMerger = null, ?PdfSplitter $splitter = null | 레거시 core merger를 받아들이되 무시합니다; null splitter는 기본 Pro splitter를 생성합니다 | — | — | $coreMerger는 하위 호환 생성만을 위해 유지됩니다 |
SmartMerger::merge() | list<MergeInput> $inputs, SmartMergeConfig $config = new SmartMergeConfig() | 페이지 범위를 축소하고, 전체 입력을 중복 제거하고, 기본 조립을 위임한 다음, 구성에 따라 북마크를 주입하고 링크를 셉니다 | SmartMergeResult | 빈 입력 목록에서 InvalidArgumentException; 입력 개수가 maxInputs를 초과하거나 입력이 maxBytesPerInput을 초과하면 OverflowException | 유일한 병합 진입점 |
MergeInput::__construct() | string $pdfData, list<PageRange> $pageRanges = [], string $label = '' | 값 객체; 빈 $pageRanges는 모든 페이지를 선택합니다 | — | — | Readonly |
MergeInput::hasPageRanges() | — | 입력이 페이지 범위를 하나 이상 가지면 True | bool | — | — |
SmartMergeConfig::__construct() | bool $consolidateBookmarks = true, bool $deduplicatePages = false, bool $rewriteLinks = true, int $maxInputs = 100, int $maxBytesPerInput = 100_000_000 | 향상 기능 토글과 리소스 한계를 담는 값 객체 | — | — | Readonly; 중복 제거는 선택적으로 활성화됩니다 |
SmartMergeConfig::default() | — | 북마크와 링크 스캔은 켜짐, 중복 제거는 꺼짐 | self | — | 정적 팩토리 |
SmartMergeConfig::basic() | — | 모든 향상 기능 꺼짐; 기본 연결만 | self | — | 정적 팩토리 |
SmartMergeResult::__construct() | string $pdfData, int $totalPages, int $sourceCount, int $mergedSize, int $bookmarksAdded = 0, int $duplicatesRemoved = 0, int $linksRewritten = 0, list<string> $inputLabels = [] | 병합된 바이트와 통합 통계를 담는 Readonly 캐리어 | — | — | Readonly |
SmartMergeResult::isValid() | — | 출력이 %PDF 헤더로 시작하면 True | bool | — | 헤더 검사만 |
SmartMergeResult::hasOptimizations() | — | 중복이 제거되었거나 링크가 하나라도 집계되면 True | bool | — | — |
SemanticSplitter::__construct() | ?PdfSplitter $splitter = null | null 인수는 기본 Pro splitter를 생성합니다 | — | — | 테스트를 위한 생성자 주입 |
SemanticSplitter::splitByStructure() | string $pdfData, float $headingFontThreshold = 14.0 | 제목 크기의 Tf 연산자를 섹션 시작으로 감지하고 그 경계에서 분할합니다; 감지된 구조가 없으면 전체 문서를 하나의 섹션으로 반환합니다 | SplitResult | 버퍼가 비어 있거나 %PDF 헤더가 없으면 InvalidArgumentException; 입력이 100 MB를 초과하면 OverflowException | Core 페이지 범위 분할로 폴백합니다 |
진입점 시그니처
섹션 제목: “진입점 시그니처”public function __construct( ?PdfMerger $coreMerger = null, ?PdfSplitter $splitter = null,)
public function merge( array $inputs, SmartMergeConfig $config = new SmartMergeConfig(),): SmartMergeResultpublic function __construct( public string $pdfData, public array $pageRanges = [], public string $label = '',)
public function hasPageRanges(): boolpublic function __construct( public bool $consolidateBookmarks = true, public bool $deduplicatePages = false, public bool $rewriteLinks = true, public int $maxInputs = 100, public int $maxBytesPerInput = 100_000_000,)
public static function default(): self
public static function basic(): selfpublic function isValid(): bool
public function hasOptimizations(): boolpublic function __construct(?PdfSplitter $splitter = null)
public function splitByStructure( string $pdfData, float $headingFontThreshold = 14.0,): SplitResult동작 계약
섹션 제목: “동작 계약”병합 파이프라인
섹션 제목: “병합 파이프라인”SmartMerger::merge()는 고정된 파이프라인을 실행하며, 외부에서 다음과 같이 관찰됩니다.
- 빈 입력 목록은
InvalidArgumentException을 발생시킵니다. 그런 다음 입력 개수는maxInputs로 제한됩니다; 초과 시OverflowException을 발생시킵니다. - 각 입력은 사용 전에
maxBytesPerInput에 대해 크기가 검사됩니다. 입력이 페이지 범위를 선언하면, 먼저 Pro splitter를 통해 선택된 페이지로 축소된 다음, 해당 페이지만 기여합니다. deduplicatePages가 활성화되면, 각 입력 문서의 전체 바이트 문자열이 비암호화xxh128함수로 지문화됩니다. 바이트가 이전 입력과 정확히 일치하는 입력은 제거됩니다. 중복 제거는 전체 문서 단위이며 바이트 단위로 정확합니다.- 기본 조립은 Pro
PdfSplitter::mergeDocuments()엔진에 위임되며, 이 엔진은 모든 입력을 하나의 연속된 객체 공간으로 다시 번호를 매기고 실제 상호 참조 테이블을 방출합니다. - 북마크 통합은
consolidateBookmarks가 활성화되고 최소 하나의 입력이 비어 있지 않은 레이블을 가질 때 적용됩니다. 최소한의/Outlines딕셔너리가 삽입되어 문서 카탈로그에서 연결되며, 병합 순서로 입력마다 하나의 outline 항목을 갖습니다. rewriteLinks가 활성화되면, 병합된 출력에서/S /GoTo액션을 스캔하고 그 개수를 보고합니다.
결과 통계
섹션 제목: “결과 통계”SmartMergeResult는 병합된 바이트와 통계를 보고합니다. totalPages는 기본 병합에서 나옵니다. sourceCount는 중복 제거 이전에 취해진 원본 입력 개수입니다. mergedSize는 출력 바이트 길이입니다. bookmarksAdded는 비어 있지 않은 레이블을 제공한 입력만 셉니다. duplicatesRemoved는 제거된 전체 입력을 셉니다. linksRewritten은 감지된 GoTo 개수입니다. inputLabels는 병합 순서로 해석된 레이블을 나열합니다. isValid()는 %PDF 헤더를 확인합니다; hasOptimizations()는 중복이 제거되었거나 링크가 집계되면 true입니다.
북마크 제목
섹션 제목: “북마크 제목”각 outline 항목은 입력 레이블을 /Title로 담으며, ISO 32000-2:2020 §7.3.4.2에 따라 PDF 리터럴 문자열로 이스케이프됩니다. 역 솔리더스(reverse solidus)가 먼저 이중화되고, 괄호가 이스케이프되며, 명명된 제어 바이트는 정의된 시퀀스를 사용하고, 남은 비인쇄 바이트는 3자리 8진수 이스케이프가 됩니다. 따라서 악의적인 레이블은 리터럴 문자열 구분자를 어긋나게 하거나 객체 구조를 주입할 수 없습니다. 레이블이 비어 있는 입력은 1부터 인덱싱되는 Document N 자리표시자 제목을 받습니다.
기본 어셈블리
섹션 제목: “기본 어셈블리”레거시 Core PdfMerger::merge()는 이 릴리스에서 의도적인 fail-closed 스텁입니다; SmartMerger가 이를 호출하는 일은 없습니다. 기본 병합은 대신 Pro PdfSplitter::mergeDocuments()를 통해 실행되므로, 병합된 파일은 ISO 32000-2:2020 §7.5.4에 따라 간접 객체마다 하나의 항목을 갖는 바이트 단위로 정확한 상호 참조 테이블을 담습니다. 결정성은 Pro splitter의 문서화된 프로파일을 따릅니다: 동일한 입력과 구성은 안정적인 바이트 스트림을 산출합니다.
구조 인식 분할
섹션 제목: “구조 인식 분할”SemanticSplitter::splitByStructure()는 페이지 콘텐츠 스트림에서 headingFontThreshold(기본 14.0) 이상인 Tf 글꼴 설정 연산자를 스캔하고, 그러한 각 페이지를 섹션 시작으로 취급합니다. 경계는 페이지 범위로 변환되어 Pro PdfSplitter::split()에 위임됩니다. 감지된 경계가 없으면, 전체 문서가 단일 섹션으로 반환됩니다. 입력은 %PDF로 시작해야 하며 100 MB 한계 이내에 있어야 합니다.
엣지 케이스 및 실패 모드
섹션 제목: “엣지 케이스 및 실패 모드”- 빈 입력 목록은 어떠한 조립 이전에
InvalidArgumentException으로 실패합니다. maxInputs(기본 100)를 초과하는 입력 개수, 또는maxBytesPerInput(기본 100 MB)을 초과하는 입력은OverflowException으로 실패합니다. 두 한계 모두 일시적 오류가 아니라 의도적인 fail-closed 거부입니다.- 중복 제거는 전체 문서 단위이며 바이트 단위로 정확합니다. 동일하게 렌더링되지만 어떤 바이트라도 다른 두 입력은 모두 유지되며,
duplicatesRemoved는 페이지 지향적인deduplicatePages라는 이름에도 불구하고 제거된 전체 입력을 셉니다. sourceCount는 중복 제거 이후 문서 개수가 아니라 원본 입력 개수를 반영합니다.- 북마크 통합은 최소 하나의 입력이 비어 있지 않은 레이블을 가질 때만 발동합니다.
consolidateBookmarks가 true이지만 모든 레이블이 비어 있으면,/Outlines객체가 작성되지 않습니다. - 주입된 outline 항목은 제목과
/Parent,/Prev,/Next트리 링크를 담습니다; 이 릴리스에서는 명시적인/Dest대상을 포함하지 않습니다. - 링크 재작성은
/S /GoTo액션만 셉니다; 번호가 다시 매겨진 객체 전반에 걸쳐 대상을 다시 가리키지는 않습니다.linksRewritten은 감지 개수로 취급하십시오. SemanticSplitter감지는 어휘적입니다.Tf글꼴 크기 연산자를 기준으로 하므로, 이미지 전용이거나 비정상적으로 인코딩된 페이지는 경계를 만들지 않고 단일 전체 문서 섹션을 반환합니다.
FIPS 모드 동작
섹션 제목: “FIPS 모드 동작”이 모듈에서는 어떠한 암호화 연산도 발생하지 않으므로, FIPS 모드 특정 동작은 없습니다. 중복 제거에 사용되는 xxh128 콘텐츠 지문은 비암호화 변경 감지 해시이며 무결성이나 증거로서의 가치를 갖지 않습니다.
적합성
섹션 제목: “적합성”| 주장 | 표준 | 절 |
|---|---|---|
문서 카탈로그에서 연결된 /Outlines 딕셔너리로 작성된 통합 북마크 | ISO 32000-2:2020 | §7.7.2 |
| 기본 병합은 모든 간접 객체에 대해 바이트 단위로 정확한 상호 참조 테이블을 방출합니다 | ISO 32000-2:2020 | §7.5.4 |
| 백슬래시와 괄호 처리를 포함하여 PDF 리터럴 문자열로 이스케이프된 outline 항목 제목 | ISO 32000-2:2020 | §7.3.4.2 |
| 완전한 문서 간 링크 재해석 | — | 지원되지 않음 (GoTo 감지만) |
| 명시적 섹션별 outline 대상 | — | 이 릴리스에서는 방출되지 않음 |
모든 절은 의역되었습니다; NextPDF는 규범 텍스트를 재현하지 않습니다. 이는 인증이 아니라 기능 진술입니다; NextPDF는 어떠한 인증도 보유하지 않으며 어떠한 인증도 부여하지 않습니다.
개발 노트
섹션 제목: “개발 노트”- Pro 패키지 내 제공 여부:
SmartMerger,MergeInput,SmartMergeConfig,SmartMergeResult, 그리고SemanticSplitter는 2.2.0부터 제공됩니다. 모두nextpdf/pro3.1.0에서 최신입니다. - 기본 병합은 Pro
PdfSplitter::mergeDocuments()에 위임합니다. 레거시 CorePdfMerger::merge()는 이 릴리스에서 fail-closed 스텁이며 호출되지 않습니다. - 입력이 바이트 단위로 동일한 전체 문서일 수 있을 때만
deduplicatePages를 활성화하십시오; 유사 중복이나 다시 인코딩된 사본은 병합하지 않습니다. - 순수 연결에는
SmartMergeConfig::basic()을, 북마크와 링크 스캔에는::default()를 사용하십시오. - 신뢰할 수 없는 입력을 병합할 때는
OverflowException을 처리하십시오; 개수와 크기 한계는 의도적인 거부입니다. - 단순한 페이지 범위 분할에는 Pro
PdfSplitter를 직접 사용하는 것을 선호하십시오; 제목 기반 섹션화가 필요할 때만SemanticSplitter를 사용하십시오.
게시 경계
섹션 제목: “게시 경계”이 페이지는 외부에서 관찰 가능한 동작과 지원되는 공개 API 표면만을 문서화합니다. 내부 네임스페이스 경로, 헬퍼 클래스, 메커니즘 테이블, 런북 파일 이름, 그리고 티켓 접두사는 범위를 벗어납니다.
함께 보기
섹션 제목: “함께 보기”- Merge (기능) — 설치, 빠른 시작, 그리고 프로덕션 예제.
- Toc — 심층 참조
- Diff — 심층 참조
- Document — 심층 참조 — Pro splitter 및 기본 병합 엔진.