logo

额外区块类型 (EBT) - 全新的布局构建器体验❗

额外区块类型 (EBT) - 样式化、可定制的区块类型:幻灯片、标签页、卡片、手风琴等更多类型。内置背景、DOM Box、JavaScript 插件的设置。立即体验布局构建的未来。

演示 EBT 模块 下载 EBT 模块

❗额外段落类型 (EPT) - 全新的 Paragraphs 体验

额外段落类型 (EPT) - 类似的基于 Paragraph 的模块集合。

演示 EPT 模块 滚动

滚动

访问检查 + 可缓存性

03/10/2025, by Ivan

路由访问检查器、hook_entity_access() 以及所有需要返回 AccessResultInterface 对象的地方,都必须添加相应的 可缓存性元数据

如果你还没有阅读,请先了解 缓存标签 (cache tags)缓存上下文 (cache contexts)最大寿命 (max-age)

访问检查参数

访问检查器会接收各种参数 —— 至少包括用户账号 (AccountInterface),并且通常还会接收一个对象。然后它会根据这些参数的属性来做出访问决定。

如果访问结果依赖于某个参数的属性,并且该属性的更改会影响访问结果,就必须将这个参数添加为可缓存依赖。

例如:

$access_result = AccessResult::allowedIf($node->isPublished())
  // 访问结果依赖于对象的一个可能发生变化的属性:这是一个可缓存依赖。
  ->addCacheableDependency($node);

另一个常见场景是:访问结果依赖于一个不会变化的属性(通常是 ID 或 UUID)。例如,如果某个用户账号是对象的所有者,则允许访问:

$access_result = AccessResult::allowedIf($node->getOwnerId() === $account->id())
  // 访问结果依赖于节点的所有者,而所有者可能会发生变化。
  ->addCacheableDependency($node);

// 访问结果同样依赖于用户账号,但用户账号的 ID 永远不会改变。因此我们不需要将 $account 添加为可缓存依赖。

// 但是,如果 $account 是当前用户,而不是某个硬编码的用户,我们还需要确保结果根据当前用户而变化。
// 否则,这次访问检查的结果会被所有用户重复使用。
if ($account->id() === \Drupal::currentUser()->id()) {
  $access_result->cachePerUser();
}