跳转到内容

SPI 稳定性规则

NextPDF 的服务提供者接口遵循语义化版本(Semantic Versioning)。每个公开合约都带有一个 @stability 标记和一份向后兼容承诺。本页说明这些规则,帮助你判断应依赖哪些内容。

Terminal window
composer require nextpdf/core:^3

服务提供者接口由 NextPDF\ContractsNextPDF\Event 命名空间中的一组公开合约组成。只有当类型的源代码 PHPDoc 带有 @stability 标记时,它才属于该接口。这个标记就是边界。没有这个标记的类型属于内部用途,即使它在 PHP 中从技术上看是 public

NextPDF 遵循语义化版本(Semantic Versioning)2.0.0。对 stable 合约的破坏性变更会提升主版本。新增合约或非破坏性的新增内容会提升次版本。错误修正会提升补丁版本。

每个合约都会宣告以下三种稳定性值之一:

标记意义变更规则
stable可用于生产环境。可以放心依赖。在次版本或补丁版本中不会出现破坏性变更。新方法只会以带默认行为的方式加入,或添加到新的合约上。
experimental可以使用,但尚未冻结。此接口可能在次版本中变更,但会先发出弃用通知。
deprecated已计划移除。合约会载明替代方案与移除的版本。

各合约的承诺记录在生成的合约映射表(contracts map)中,并在每次发布时从源代码重新生成。承诺文本会说明该合约的确切规则。请以合约源代码中的 PHPDoc 作为唯一事实来源。

合约映射表记录这些承诺。承诺分为四类:

  1. 接口承诺。 「在次版本或补丁版本中不会出现破坏性变更。新增方法只会随默认实现一起加入。」 适用于大多数 stable 接口,包括 FontRegistryInterfaceSignerInterfaceHsmSignerInterfaceHtmlSecurityPolicyInterface
  2. 枚举承诺。 「不移除任何 case。次版本中可能会新增 case。」 适用于 stable 的枚举,例如 AlignmentOrientationOutputDestination
  3. 冻结值对象承诺。 「构造函数签名与公开属性都已冻结。可能会新增方法。」 适用于值对象,例如 TextPreprocessResultTextSegment,以及与其绑定的事件载荷。
  4. 实验性承诺。 「此接口可能在次版本中变更,但会先发出弃用通知。」 适用于 experimental 合约,例如 DeferredSignerInterfaceTimestampProviderInterfaceCursorInterfaceStreamingWriterInterface

EventDispatcherListenerProvider 这类 final 类会冻结其公开方法的签名。请通过组合(composition)扩展 final 类。不要为它创建子类。

CursorInterfaceStreamingWriterInterfaceexperimental(自 3.1.0 起)。NextPDF 为这两个合约都提供了最终且经过测试的引擎实现;这些实现类属于内部,不属于公开接口的一部分。你通过公开的 experimental 合约使用流式行为。通常情况下,你不需要自行实现这份合约。

因为这份合约是 experimental,其签名可能在次版本中变更,但会先发出弃用通知(即实验性承诺)。在生产环境依赖它之前,请收紧版本约束,或用自己的适配器(adapter)把它包起来。请把这类流式合约视为正在稳定过程中的扩展点,而不是已经冻结的扩展点。

本页没有运行时 API。相关接口是每个公开合约上的 @stability PHPDoc 标记,以及汇总各合约承诺并重新生成的合约映射表。

在你依赖某个合约之前,请先从其源代码读取它的稳定性。

<?php
declare(strict_types=1);
use ReflectionClass;
$doc = (new ReflectionClass(\NextPDF\Contracts\FontRegistryInterface::class))
->getDocComment();
// Look for the "@stability stable" line in the contract PHPDoc.
\assert(\is_string($doc) && \str_contains($doc, '@stability stable'));

Composer 的版本约束会锁定主版本,而主版本正是 stable 合约发生破坏性变更的单位。

{
"require": {
"nextpdf/core": "^3.0"
}
}

将版本约束锁定到 ^3.0 后,即可接收次版本和补丁版本更新,并且不会遇到任何 stable 合约的破坏性变更。依赖 experimental 合约时,请使用更严格的版本约束,因为 experimental 合约可能在次版本中变更。

  • 是标记,不是可见性。 一个 public PHP 方法,除非其所属的声明类型带有 @stability 标记,否则并不属于服务提供者接口。
  • 实验性变动。 一个 experimental 合约可能在次版本中变更。请收紧版本约束,或用自己的适配器把它包起来。即使流式合约已随附实现,这一点仍然适用于它们。
  • 新增的默认方法。 一个 stable 接口可能会新增一个带有默认行为的方法。升级时请实现这个新方法,让自己的实现保持明确。
  • 版本一致性。 NextPDF Pro 与 NextPDF Enterprise 遵循相同的规则。你在 Core 中面向的合约,对同一合约的 Premium 实现仍然有效。

合约会经历一套明确定义的生命周期:

  1. 标注。 维护者在源代码 PHPDoc 中设置 @stability deprecated,并记录替代方案与移除的版本。
  2. 通知。 弃用会在标注它的那次发布中通过变更日志(changelog)公告。
  3. 共存。 已弃用的合约与其替代方案会至少共存一个次版本。
  4. 移除。 合约会在所载明的主版本中移除。移除绝不会在次版本或补丁版本中发生。

一旦某个合约被标注为 deprecated,就请尽早规划升级。替代方案都会明确列出。

本页定义的是策略。它没有运行时成本。

签署合约为 stable,并遵循接口承诺。签署合约上的新方法只会随默认行为一起加入,或添加到新合约上,因此以硬件为后盾的实现不会因为次版本升级而中断。在进行主版本升级前,请审阅变更日志,因为主版本可能会变更 stable 合约。

此版本规则符合语义化版本(Semantic Versioning)2.0.0。变更日志的生成遵循约定式提交(Conventional Commits)1.0.0。

NextPDF Pro 与 NextPDF Enterprise 遵循与 Core 相同的服务提供者接口稳定性规则。你在 Core 中面向的合约,对该合约的 Premium 实现仍然有效,因此你的扩展代码可在不同版本之间移植。

词汇表定义了 stability tag(稳定性标记)backward-compatibility promise(向后兼容承诺);各项规范定义请参阅已发布的词汇表。