滚动
访问检查 + 可缓存性
路由访问检查器、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();
}