Pro 版本
Compliance — 深度参考
Compliance 模块在 NextPDF\Pro\Compliance 下捆绑了三个相互独立的接口面:
- 语言标记报告 —— 一个严格的 PDF/UA-2
/Lang策略门面,外加一个结构化、PSR-3 形态的合规事件报告器。 - 电子发票处理 —— 对照 EN 16931 语义模型进行 Factur-X 1.08 / ZUGFeRD 2.4 校验,以及混合 PDF/A-3 产出。
- 溯源 —— 通过一个经对抗性加固的 JUMBF 解析器嵌入并提取调用方提供的 C2PA manifest store;声明合成仍处于预览门控之下。
本模块报告它所检查的内容。它不会认证文档,也不执行密码学签名。
可用性与授权
标题为“可用性与授权”的章节该能力随 NextPDF Pro(nextpdf/pro)提供,并通过 Pro 级授权信封激活。一个没有该授权的部署不会加载该能力的类。比较版本并获取授权。
不存在逐功能授权标记。这是一项 Pro 版本能力。实验性的 C2PA 声明构建器额外需要一个显式的环境启用(见边界情形与失败模式)。
公共 API 接口面
标题为“公共 API 接口面”的章节composer require nextpdf/pro:^3| 符号 | 参数 | 默认行为 | 返回 | 抛出或失败情形 | 备注 |
|---|---|---|---|---|---|
LangComplianceReporter::warn() / ::error() | string $tag, string $reason, ?string $clauseReference = null | 通过 PSR-3 logger 为每个语言标记事件发出一条结构化 JSON 记录 | void | 若记录 JSON 编码失败则抛出 JsonException | warn = 宽松模式拒绝;error = 严格模式拒绝 |
LangComplianceReporter::reportException() | InvalidBcp47TagException $exception, string $severity = 'error' | 从异常中提取标记与原因;委托给 warn() 或 error() | void | 同上 | 便捷路径 |
LangComplianceReporter::buildRecord() | string $severity, string $tag, string $reason, ?string $clauseReference = null | 构建记录数组而不记录日志 | array | 不抛出异常 | 用于自定义 sink,例如逐文件的 JSON 摘要 |
ConformancePolicy::default() | ?LoggerInterface $logger = null | 严格 UA-2 策略:格式不正确或未注册的 /Lang 标记会被拒绝 | self | 不抛出异常 | v5.0 的默认值为严格 |
ConformancePolicy::fromCore() | CoreConformancePolicy $core, ?LoggerInterface $logger = null | 原样包装一个既有的 Core 策略;不翻转任何轴 | self | 不抛出异常 | 若要严格姿态,优先使用 default() |
ConformancePolicy::withStrictUa2() | bool $enabled | 返回一个设置了严格轴的副本;禁用时会发出一条 PSR-3 notice | self | 不抛出异常 | 已弃用的退出方式;移除目标 6.0.0 |
ConformancePolicy::isStrictUa2() / ::mode() | — | 读取底层的 Core 策略 | bool / ConformanceMode | 不抛出异常 | — |
EInvoiceValidator::validate() | string $pdfPath | 完整流水线:PDF/A-3 包装器检查、附件提取、profile 检测、EN 16931 规则、Schematron | EInvoiceValidationResult | 在 I/O 失败、PDF 结构格式不正确或工具崩溃时抛出 EInvoiceException 子类 | 冻结的 SPI 接口;一个格式良好的非电子发票 PDF 会返回一个结果,绝不抛出异常 |
EInvoiceXmlValidator::validate() | string $xmlPayload, ValidatorContext $context | 对 CII 载荷进行结构预检加上 EN 16931 深度语义规则库 | 契约 ValidationResult | 对无效输入不抛出异常;拒绝以带有 findings 的失败结果呈现 | 具体的跨层校验器;输入经 XmlGuard 把关 |
EInvoiceValidationResult::isValid() | — | 仅当包装器、附件规范、profile、语法均成立且不存在 FATAL 违规时为 true | bool | 不抛出异常 | 仅有空的违规列表并不等于有效 |
EInvoiceValidationResult::notAnEInvoice() | — | 确定性的全 null、全 false 结果 | self | 不抛出异常 | 用于“不是混合发票”情形的工厂方法 |
EInvoiceProfile | 字符串支撑的枚举 | 枚举项 MINIMUM、BASIC_WL、BASIC、EN16931、EXTENDED,由 BT-24 URN 支撑 | — | — | 对 MINIMUM 与 BASIC_WL,isEn16931Conformant() 为 false |
EInvoiceSyntax | 字符串支撑的枚举 | 枚举项 UN_CEFACT_CII、UBL_INVOICE、UBL_CREDIT_NOTE | — | — | 只有 CII 满足 isFacturXEligible();UBL 仅用于校验 |
BusinessRuleViolation | string $ruleId, BusinessRuleSeverity $severity, string $message, ?string $xpath = null, ?string $ramPath = null | 不可变的违规 DTO | — | — | 规则 id 族 BR-、BR-CO-、BR-CL-、BR-DEC-、BR-FXEXT- |
BusinessRuleSeverity | 字符串支撑的枚举 | FATAL 使发票无效;WARNING 标记一个质量问题 | — | — | 镜像 EN 16931 Schematron 的等级 |
FacturXEmbedder::embed() | 见签名代码块 | 向 PDF/A 源追加内嵌文件流、filespec 与 XMP;重写 xref | void | 在 XML 格式不正确、源不可读、缺少 catalog、对象流或 xref 流的源,或输出写入失败时抛出 EInvoiceException | 源文件保持不变 |
FacturXEmbedderOptions::default() | — | /AFRelationship /Alternative、文件名 factur-x.xml、类型 INVOICE、版本 1.0 | self | 不抛出异常 | 默认值满足德国的强制要求,并在法国仍被接受 |
FacturXEmbedderOptions::withRelationship() / ::withFilename() | string | 返回一个应用了覆盖值的副本 | self | 在接受集合之外抛出 InvalidArgumentException | 关系:Source、Data、Alternative;文件名包括 zugferd-invoice.xml 与 xrechnung.xml |
FacturXEmbedderOptions::withDocumentType() | string $documentType | 返回一个应用了 XMP 文档类型覆盖值的副本 | self | 不抛出异常 | 取值未做防御性枚举 |
FacturXContractEmbedder::embed() | string $pdfBytes, string $xmlPayload, EmbedderOptions $options | 在 FacturXEmbedder 之上、经由短生命周期临时文件的字节进字节出适配器 | string | EInvoiceException;XRECHNUNG profile 作为 Enterprise 专属被拒绝 | 跨层 EmbedderInterface 实现 |
C2paManifestEmbedder::embed() | string $pdfBytes, ManifestStore $store | 在 profile 位置嵌入该 store 的字节序列化 | string | 在任何嵌入失败时抛出 C2paException | 冻结的 SPI 接口;仅字节,无 I/O |
C2paManifestEmbedder::extract() | string $pdfBytes | 通过加固的 JUMBF 解析器解析一个内嵌 store | ManifestStore|null | 当存在 store 但违反某个加固上限时抛出 C2paException 子类 | null 表示不存在;不存在绝不抛出异常 |
ManifestStore::fromBoxes() / ::empty() | list<JumbfBox> / — | 构建不可变的 store 值对象 | self | 不抛出异常 | box 顺序对往返相等性至关重要 |
ManifestStore::toBytes() / ::isEmpty() / ::size() | — | 序列化根 box;空 store 序列化为空字符串 | string / bool / int | 不抛出异常 | — |
JumbfBoxParser::parse() | string $bytes | 在硬性上限下解析根级 JUMBF box | list<JumbfBox> | MalformedJumbfException、JumbfBombException、JumbfCycleDetectedException、JumbfDepthExceededException | 上限:深度 8、每个 box 64 MiB、总计 128 MiB、MAX_CHILDREN_PER_SUPERBOX 4096 |
JumbfBox::superbox() / ::leaf() | string $tbox, … | 构建一个经校验的 box;toBytes() 可经解析器往返 | self | 当 TBox 不恰好为 4 字节时抛出 MalformedJumbfException | — |
C2paCapabilityStatus::current() / ::summary() | — | 报告 C2PA 能力成熟度,当前为 preview-draft | self / string | 不抛出异常 | 机器可校验的预览标记 |
Feature::PREVIEW_C2PA_DRAFT->isEnabled() | — | 每次调用都读取进程环境;只有字面量 '1' 才启用 | bool | 不抛出异常 | 环境变量 NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT |
ExperimentalC2paEmbedder::buildManifestStore() | string $sourceBytes, string $producer | 构建一个锁定到草案的 manifest store,带一个 SHA-256 哈希绑定声明断言 | ManifestStore | 预览标记关闭时构造函数抛出 LogicException | 预览;线格式锁定到草案快照;不发出声明签名 |
入口点签名,逐字如下:
public static function default(?LoggerInterface $logger = null): selfpublic function withStrictUa2(bool $enabled): selfpublic function isStrictUa2(): boolpublic function validate(string $pdfPath): EInvoiceValidationResultpublic function embed( string $sourcePdfPath, string $xml, EInvoiceProfile $profile, string $outputPdfPath, ?FacturXEmbedderOptions $options = null,): voidpublic function embed(string $pdfBytes, ManifestStore $store): stringpublic function extract(string $pdfBytes): ?ManifestStore行为契约
标题为“行为契约”的章节语言标记报告。 LangComplianceReporter 为每个 PDF/UA-2 语言标记事件发出一条结构化 JSON 记录。每条记录携带固定的事件判别符、一个严重度(warn 表示宽松模式拒绝,error 表示严格模式拒绝)、逐字的违规标记、一个机器可读的原因、解析出的标记组件(当标记不通过 RFC 5646 形态文法时为 null)、一个 ISO 14289-2 §8.4.4 条款引用,以及一个带微秒的 UTC 时间戳。该 JSON 作为 PSR-3 消息体传递;下游 sink 直接解析 message 字段。ConformancePolicy 是 Core 符合性策略之上的 Premium 门面。它的默认值应用严格的 UA-2 语言处理,并拒绝到达 /Lang 的格式不正确或未注册的标记。退出辅助方法 withStrictUa2(false) 会回退到旧版的宽松行为,并在有效值确实改变时记录一条 PSR-3 notice。NextPDF 自 v5.0 起将该辅助方法标记为已弃用,移除目标为 6.0.0。迁移方法:用 composer pdfua2:audit-lang-tags <pdf-or-dir> 审计语料库中格式不正确的 /Lang 值,纠正它们,然后去掉那个退出调用。
电子发票处理。 EInvoiceValidator 是混合 PDF 校验的冻结 SPI 契约:PDF/A-3 包装器检查、/AF 附件提取、从 BT-24 规范标识符进行 profile 检测、EN 16931 业务规则引擎,以及一次 Schematron 处理。一个格式良好的非 Factur-X PDF 会返回 EInvoiceValidationResult::notAnEInvoice() 而非抛出异常;只有 I/O 失败、PDF 结构格式不正确或工具崩溃才会抛出 EInvoiceException 子类。EInvoiceXmlValidator 是具体的跨层 XML 校验器:它经 Core XmlGuard 把关输入,运行结构预检与深度 EN 16931 语义规则库,并失败即关闭 —— 引擎错误以 error findings 呈现,绝不作为静默通过。FacturXEmbedder 将一个 PDF/A 源修订为一个混合 PDF/A-3:它追加一个内嵌文件流、一个带可配置 /AFRelationship 的 filespec,以及一个 Factur-X XMP 扩展包,然后重写经典的交叉引用表。catalog 的 /AF 数组与 /Names /EmbeddedFiles 名树都引用该附件,因此旧版 ZUGFeRD 阅读器能解析它。
溯源。 C2paManifestEmbedder 将一个调用方提供的 C2PA manifest store 嵌入一个 PDF 字节串,或提取一个。ManifestStore 是跨越边界的不可变值对象。该接缝仅字节且供应商中立:它不会合成声明、不会摄取 URI 引用,也不会解析哈希绑定,并且不执行任何网络或文件系统 I/O。extract() 在未命中时返回 null,且在没有 store 的 PDF 上开销很低。每一次非 null 的提取都已经通过了 JumbfBoxParser 的加固上限。
本模块报告它所检查的内容。它不会认证一份文档、使其具有法律约束力,或保证任何输出满足某项法规。电子发票校验器不是税务机关校验器,并排除各国扩展(例如意大利 SDI、法国 Chorus Pro、德国 XRechnung)。正如 EN 16931-1 所述,发票开具方仍需负责满足相关立法的规则。对某项标准的支持并不等于符合它。请就监管层面是否充分咨询你的合规团队。
边界情形与失败模式
标题为“边界情形与失败模式”的章节- 一个格式良好的非 Factur-X PDF 会返回一个“不是电子发票”的结果;它不会抛出异常。
- 一个空的业务规则违规列表本身并不意味着该文档有效;包装器与附件检查也同样适用。
FacturXEmbedder对使用压缩对象流(/Type /ObjStm)或交叉引用流(/Type /XRef、混合/XRefStm)的源失败即关闭。请先用经典交叉引用表重新保存这些源。- XML 载荷经 Core
XmlGuard把关:DOCTYPE 或实体声明、超大输入以及无效 UTF-8,在嵌入路径上以EInvoiceException拒绝,在校验器路径上以失败结果拒绝。 FacturXContractEmbedder会显式拒绝XRECHNUNGprofile 而非静默降级它;XRechnung 产出是一项 Enterprise 能力。C2paManifestEmbedder::extract()区分不存在(null)与格式错误(C2paException子类,指明被违反的不变式:结构格式不正确、大小或计数炸弹、偏移循环、嵌套深度)。ExperimentalC2paEmbedder的构造会抛出LogicException,除非预览环境标记等于'1'。它的线格式锁定到一个 C2PA 草案快照,并可能在不通知的情况下改变;它不发出任何声明签名。在 C2PA PDF profile 冻结之前,该能力一直处于预览状态。- 严格 UA-2 的宽松退出已弃用;请迁移到严格默认(见行为契约)。
- 本模块不执行密码学签名。C2PA 声明签名与密钥保管不在范围内;关于 FIPS 模式的签名行为,请参阅 Security 模块。
符合性
标题为“符合性”的章节| 行为 | 参考 | 状态 |
|---|---|---|
自然语言声明(/Lang) | ISO 14289-2:2024 §8.4.4 | 已检查/已报告 |
| 核心发票语义模型 | EN 16931-1:2026 | 已检查(开具方仍负有责任) |
| 关联文件/内嵌文件流 | ISO 32000-2:2020 §14.13.2 | 已产出(/AF、/EF、/Params) |
| 附件关系与容器规则 | Factur-X 1.08 §3.1, §6.2 | 已产出/已检查(默认 /AFRelationship /Alternative) |
| C2PA manifest store / JUMBF | C2PA 2.1 §11.1 | 支持嵌入/提取;声明合成为预览 |
本表记录该模块所依循构建的规范以及它检查或产出什么。它不是一份关于认证或监管充分性的声明。NextPDF 未持有针对这些标准的任何认证。
开发说明
标题为“开发说明”的章节- 报告器的记录形态是一个稳定契约;下游告警规则可以针对固定的事件判别符进行锁定。
- 禁用严格 UA-2 只有在有效值改变时才发出遥测可见的弃用通知;重新断言当前值是静默的。
- Factur-X 嵌入器逐字保留源字节并追加新对象;它力求保留 PDF/A-3 符合性,但不会重新校验。若要硬性证明,请将输出经过一个外部 PDF/A 校验器。
- C2PA 接缝冻结了五个不变式:无第三方导入、仅字节契约、无 I/O、未命中返回 null 的提取,以及稳定层中不进行声明合成。
JumbfBoxParser的上限是公共常量;请据此确定你所接受输入的大小,而不要重新推导限制。
发布边界
标题为“发布边界”的章节本页仅记录外部可观测的行为以及受支持的公共 API 接口面。内部命名空间路径、辅助类、机制表、runbook 文件名以及工单前缀不在范围内。