Pro edición
Document — Referencia detallada
De un vistazo
Sección titulada «De un vistazo»El módulo Document ofrece tres primitivas de ensamblaje de Pro: división por rangos de páginas, fusión de varios documentos y construcción del diccionario PDF Portfolio (Collection). PdfSplitter extrae rangos de páginas en PDF autónomos y estructuralmente conformes, y fusiona documentos enteros en un único archivo renumerado. PdfPortfolio construye el diccionario Collection que presenta los archivos incrustados con columnas de esquema ordenables. Cada punto de entrada acota el tamaño de la entrada y el número de objetos frente a entradas hostiles.
Disponibilidad y licencias
Sección titulada «Disponibilidad y licencias»Esta capacidad se incluye en NextPDF Pro (nextpdf/pro) y se activa con un envoltorio de licencia de nivel Pro. Un despliegue sin ese derecho no carga las clases de la capacidad. Comparar ediciones y obtener una licencia.
Superficie de la API pública
Sección titulada «Superficie de la API pública»Todos los tipos del módulo residen en el espacio de nombres NextPDF\Pro\Document. PageRange y MergeResult son objetos de valor de Core de NextPDF\Document.
| Símbolo | Parámetros | Comportamiento por defecto | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
PdfSplitter::split() | string $pdfData, list<PageRange> $ranges, int $maxBytes = 100_000_000, int $maxRanges = 1000 | Construye un segmento PDF autónomo por rango | SplitResult | InvalidArgumentException si falta la cabecera %PDF; OverflowException en la guarda de tamaño, recuento de rangos o clausura | Las guardas se ejecutan antes de cualquier análisis |
PdfSplitter::splitEvery() | string $pdfData, int $pagesPerSegment | Deriva rangos contiguos de N páginas; el último segmento puede ser más corto | SplitResult | InvalidArgumentException cuando $pagesPerSegment < 1 o falta la cabecera | Delega en split() con los topes por defecto |
PdfSplitter::extractPages() | string $pdfData, PageRange $range | Devuelve un rango como bytes de PDF autónomo | string | InvalidArgumentException si falta la cabecera; OverflowException en la guarda de clausura | Esta ruta no tiene parámetros de tope |
PdfSplitter::mergeDocuments() | list<string> $pdfs, int $maxInputs = 100, int $maxBytesEach = 100_000_000 | Fusiona las entradas en orden en un único PDF renumerado | MergeResult | InvalidArgumentException si la lista está vacía o hay una entrada que no es PDF; OverflowException en la guarda de recuento, tamaño por entrada o clausura | Desde 3.1.0; la versión de entrada más alta fija la cabecera de salida |
SplitResult | readonly $segments, $ranges, $totalPages | Transporta los bytes de segmento en bruto más metadatos de origen | — | — | Objeto de valor final readonly |
SplitResult::count() | — | Cuenta los segmentos producidos | int | — | — |
SplitResult::segment() | int $index | Devuelve los bytes de un segmento | string | OutOfRangeException si el índice está fuera de límites | Índice de base cero |
PdfPortfolio::__construct() | string $viewMode = 'tile' | Valida el modo de vista en la construcción | — | InvalidArgumentException si el modo no es tile, detail, hidden | — |
PdfPortfolio::addSchema() | PortfolioField $field | Añade una columna de esquema | self | — | Fluida |
PdfPortfolio::addEntry() | PortfolioEntry $entry | Añade una entrada de archivo | self | — | Fluida |
PdfPortfolio::getSchema() | — | Devuelve los campos de esquema acumulados | list<PortfolioField> | — | — |
PdfPortfolio::getEntries() | — | Devuelve las entradas de archivo acumuladas | list<PortfolioEntry> | — | — |
PdfPortfolio::count() | — | Cuenta las entradas de archivo | int | — | — |
PdfPortfolio::generateCollectionDictionary() | — | Emite la cadena del diccionario Collection | string | — | Los bloques de esquema y de orden aparecen solo cuando hay campos |
PortfolioEntry | $filename, $data, $description = '', $mimeType = 'application/octet-stream', $customFields = [] | Objeto de valor inmutable de entrada de archivo | — | — | size() devuelve la longitud en bytes de los datos |
PortfolioField | $name, PortfolioFieldType $type, $displayName = '', $order = 0, $visible = true | Objeto de valor inmutable de columna de esquema | — | — | effectiveDisplayName() recurre a $name |
PortfolioFieldType | Enum de cadena: Text, Date, Number, FileName, Description, Size, ModDate, CreationDate | Asigna cada caso a un /Subtype de PDF mediante pdfSubtype() | string (S, D, N, F, Desc) | — | Los casos de tipo fecha comparten el subtipo D; los numéricos comparten N |
Firmas de los puntos de entrada:
public function split(string $pdfData, array $ranges, int $maxBytes = 100_000_000, int $maxRanges = 1000): SplitResult
public function mergeDocuments( array $pdfs, int $maxInputs = 100, int $maxBytesEach = 100_000_000,): MergeResultpublic function __construct( private readonly string $viewMode = 'tile',)
public function generateCollectionDictionary(): stringContrato de comportamiento
Sección titulada «Contrato de comportamiento»La división y la fusión comparten una única canalización de grafo de objetos:
- La entrada debe comenzar con la cabecera
%PDF. Las guardas de tamaño y recuento se ejecutan antes del análisis y lanzanOverflowExceptionen caso de incumplimiento. - Las páginas hoja se detectan buscando marcadores de objeto de página; los nodos del árbol de páginas se excluyen del recuento.
- El analizador indexa cada objeto indirecto sin comprimir con un escaneo de terminador consciente de los flujos. Gana la primera aparición de un id de objeto, por lo que no se aplican las sobrescrituras de actualización incremental.
- Los atributos heredables del árbol de páginas (
/Resources,/MediaBox,/CropBox,/Rotate) se materializan en cada página extraída recorriendo su cadena/Parent, de modo que los segmentos son autocontenidos. - Se recopila la clausura transitiva de referencias indirectas de cada página, excluyendo la arista de retorno
/Parent, y se renumera en un espacio de id contiguo nuevo. - El serializador emite la cabecera, el Catalog, el árbol Pages, los objetos de página y los objetos de clausura, y a continuación una tabla de referencias cruzadas con desplazamientos de bytes exactos y un
startxrefque apunta a la palabra clavexref. mergeDocumentsrepite la canalización por cada entrada en un único espacio de id compartido. La versión de PDF de entrada más alta fija la cabecera de salida. Es el reemplazo conforme del fusionador de Core deshabilitado, que permanece con fallo cerrado.- La salida es determinista. No se emiten marcas de tiempo ni identificadores aleatorios, por lo que una entrada idéntica produce bytes idénticos.
Ensamblaje del Portfolio:
- El constructor valida el modo de vista. El token
/Viewemitido es/T,/Do/Hpara tile, detail y hidden respectivamente. generateCollectionDictionary()emite/Type /Collection, el token/View, un bloque/Schemacuando hay campos, y una directiva/Sortsobre el primer campo de esquema, ascendente.- Cada campo de esquema emite
/Subtype(depdfSubtype()),/N(nombre de visualización escapado),/O(orden) y/V(visibilidad). - Los nombres de campo se sanean a tokens de nombre PDF válidos; los caracteres que no son de palabra se convierten en guiones bajos. Los valores de cadena se escapan como cadenas literales de PDF.
- Las entradas de archivo se exponen a través de
getEntries()para su incrustación por la capa de escritura. El propio diccionario Collection solo transporta vista, esquema y orden.
Casos límite y modos de fallo
Sección titulada «Casos límite y modos de fallo»- Un rango que no coincide con ninguna página produce un segmento mínimo de una página (MediaBox de 612 x 792), no un error.
- Un documento sin marcadores de página detectables se cuenta como una página.
- Las páginas almacenadas dentro de flujos de objetos no se detectan; solo participan en la extracción los objetos indirectos sin comprimir.
- Cuando existen ids de objeto duplicados, se usa la revisión de menor desplazamiento; las revisiones de actualización incremental posteriores se ignoran.
- La clausura de referencias por segmento se limita a 50.000 objetos; un grafo maliciosamente autorreferencial o con expansión masiva lanza
OverflowException. - Topes por defecto: 100 MB de entrada, 1.000 rangos, 100 entradas de fusión. Todos son ajustables por el llamador en cada llamada.
splitEvery()rechaza un tamaño de segmento inferior a 1 conInvalidArgumentException.SplitResult::segment()rechaza un índice fuera de límites conOutOfRangeException.- Dos nombres de campo de esquema que difieren solo en la puntuación se sanean a la misma clave de diccionario; el campo posterior eclipsa silenciosamente al anterior en el esquema emitido.
- Este módulo no realiza operaciones criptográficas; el modo FIPS no altera su comportamiento.
Conformidad
Sección titulada «Conformidad»La salida de segmentos y de fusión sigue el modelo de objeto de página de ISO 32000-2; la fuente anota las cláusulas pertinentes. Afirmaciones verificables externamente:
- La disposición del tráiler, el desplazamiento de bytes de
startxrefy el terminador%%EOFsiguen ISO 32000-2:2020, §7.5.5 — referenciaef0f2a4b563b84f81b3e6428612bc47c510d94fc8096849d339abf0f3247d845. - Los valores
/Viewdel diccionario Collection (/T,/D,/H) siguen ISO 32000-2:2020, §12.3.5 — referencia5cefaaeb40f3ff98e3aba135ac57c9424a05c43144c1b9b5156bfd4295e08ddd. - Las entradas
/Subtype,/N,/Oy/Vdel campo Collection siguen ISO 32000-2:2020, §12.3.5 (diccionario de campo de colección) — referencia6300fbfdc8a913a8dc6f6ae34eff99f2bd03c4313a77777cdd5a8dd856d9537a.
Estas afirmaciones describen capacidad implementada verificada por las pruebas del módulo. El soporte de una construcción no es una afirmación de conformidad, y la conformidad no es certificación; NextPDF no posee ninguna certificación de terceros para este módulo.
Notas de desarrollo
Sección titulada «Notas de desarrollo»- Todas las clases del módulo son
final; los tipos de resultado y de objeto de valor sonreadonly. Los tipos del splitter y del Portfolio datan de 1.9.0;mergeDocuments()se añadió en 3.1.0. PageRangeyMergeResultson tipos de Core, por lo que los puntos de llamada siguen siendo portables entre ediciones.- Los tráileres de segmento solo llevan
/Sizey/Root; no se emite ningún identificador de archivo/IDni diccionario/Info. - Para flujos de actualización incremental o de firma, entregue los bytes de segmento al módulo Writer en lugar de posteditarlos en su sitio.
- El módulo no registra ningún contenido de documento.
Límite de publicación
Sección titulada «Límite de publicación»Esta página documenta únicamente el comportamiento observable externamente y la superficie de la API pública admitida. Las rutas de espacio de nombres internas, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbook y los prefijos de tickets quedan fuera del alcance.