跳转到内容

recipe(示例)惯例

整合 cookbook(范例指南)中的每个可执行 recipe 都遵循同一份契约。本页说明这份契约,让读者知道一个 recipe 应包含哪些内容,也让作者知道一个 recipe 必须满足哪些条件。本页属于描述性说明:它记录这项惯例。实际的强制检查由 repository 工具与样式覆写表(style override sheet)负责,不在这里。

每个整合都会在各自的源代码 repository 中将 recipe 放在 docs/public/ 下,再由负责 aggregate(聚合)的 aggregator(文档聚合器)将其拉入本站。以下惯例适用于 recipe 所在的任何位置。

1. 范例是真实代码,不是手打的片段

标题为“1. 范例是真实代码,不是手打的片段”的章节

一个 recipe 的代码是 repository 中实际存在的真实代码,而不是直接写进正文的片段。

  • 任何超过五行的 PHP 代码区块,都来自对应 repository 中的 examples/ 目录,或来自 tests/Cookbook/ 目录。
  • 区块会在 fenced-block 信息字符串中声明来源,例如 title="examples/standalone.php"
  • 对应的测试会断言该范例仍可编译,且仍会产生文档所记载的输出,因此渲染出来的页面不会与其展示的代码不一致。

这项惯例对应文档样式覆写表(style override sheet)§3.4(「范例必须可执行」)。一个只展示代码、却没有对应范例或测试支撑的 recipe,并不符合这项惯例。

2. 一个区块一种语言,错误处理要看得到

标题为“2. 一个区块一种语言,错误处理要看得到”的章节
  • 一个 fenced 代码区块只包含一种语言,并明确声明( ```php, ```bash, ```yaml, ```json)。不使用没有标示语言的裸 fence。
  • 标记为生产环境可用 how-to 的 recipe 会明确写出 try / catch,捕获最具体、最适用的异常类型,而不是直接捕获 \Exception,并且 catch 区块会给出读者可以照抄的处理方式(记录、重新抛出,或返回一个已定义的错误对象)。不使用空的 catch 区块。
  • 对于以 HTTP 传输的整合,recipe 会把传输失败与非成功的 HTTP 状态视为两种不同情况来处理。PSR-18 客户端只有在请求根本发不出去时,才抛出带类型的客户端异常。4xx5xx 响应是 recipe 会检查的正常返回值,而不是它要捕获的异常。

每个 recipe 都会声明其输出可重现到什么程度,并遵循由本站内容 schema 强制执行的 §5.1 front-matter 契约。相关字段如下:

  • reproducibility_profile — 为 bitwisestructuralsemantic 其中之一。bitwise 表示在输入已固定(pinned)的前提下,每次运行所输出的字节完全相同。structural 表示文档结构完全相同,但附带字节(时间戳、对象顺序)可能不同。semantic 表示渲染结果等价,但不保证字节或结构相同。一个 recipe 应声明它能够诚实达到的最强 profile,而不是声明理论上存在的最强 profile。
  • output_hash — 当 profile 为 bitwise 时,记录预期输出的 SHA-256,让读者可以验证文档所记载的结果。当 profile 不支持稳定哈希时,此字段留空。
  • runnable_example — 产生此 recipe 输出的 examples/… 路径,把页面绑定到 §1 中那个由源代码支撑的范例。
  • performance_budget — recipe 的可选上限,包含实际时间(wall-clock)与峰值内存,让同时也是性能宣称的 recipe 保持在可界定、可测试的范围内。
  • compatibility — recipe 宣称能运行的 PHP 版本。recipe 默认以 PHP 8.4 为准;若 recipe 用到仅 8.4 才有的功能,会在它的 front-matter 中列出 backport,并在代码区块中特别标出该功能。

可重现性 profile 就是 §8.4 的可重现性契约。读者用它来判断「输出」指的是完全相同的字节,还是一份等价的文档。

本 cookbook 中的每一页在通过 Writing Gate 之前,都带有 publish: false。默认拒绝发布:合并一个页面并不会将其发布;只有在 front-matter 中记录一个明确的 gate 决定,才会发布。若某个 recipe 的规范性引用因为 compliance-engine 确实发生中断而无法固定(pinned),它还会额外带有一个 resolve(解析)尚未完成的引用标记(unresolved-citation)。它会维持 publish: false,直到该引用重新固定为止。该标记由 repository 的 RAG 基础设施中断回退协议管控;recipe 作者应遵循该协议,而不是自行编造引用或舍弃这项宣称。

5. aggregator 写入 provenance(来源信息)字段

标题为“5. aggregator 写入 provenance(来源信息)字段”的章节

recipe 作者不会手写那四个由 aggregator 拥有的来源 provenance 字段:source_reposource_refsource_hashmanifest_hash。aggregator 从源代码 repository 拉取 recipe 时会填入这些字段,因此发布后的页面会精确记录它由哪个 repository 版本产生。如果作者在这些字段中的任何一个留下占位内容,aggregator 会将其覆写;该占位内容永远不会出现在发布后的页面上。

本 cookbook 中的一个 recipe 是:有测试支撑、来自源代码的代码,一个区块一种语言,生产环境 how-to 具备明确的错误处理,一份诚实的可重现性 profile,在通过 Writing Gate 之前默认 publish: false,以及由 aggregator 注入的 provenance。同时满足全部六项的页面是一个 recipe;只满足较少项的页面则是一份草稿。