翻阅Laravel的代码,我探索了我不完全了解的代码。
public function applyScopes()
{
if (! $this->scopes) {
return $this;
}
$builder = clone $this;
foreach ($this->scopes as $identifier => $scope) {
if (! isset($builder->scopes[$identifier])) {
continue;
}
$builder->callScope(function (Builder $builder) use ($scope) {
// If the scope is a Closure we will just go ahead and call the scope with the
// builder instance. The "callScope" method will properly group the clauses
// that are added to this query so "where" clauses maintain proper logic.
if ($scope instanceof Closure) {
$scope($builder);
}
// If the scope is a scope object, we will call the apply method on this scope
// passing in the builder and the model instance. After we run all of these
// scopes we will return back the builder instance to the outside caller.
if ($scope instanceof Scope) {
$scope->apply($builder, $this->getModel());
}
});
}
return $builder;
}
this
对象被克隆。该文档说,每个属性都是浅层克隆的,这意味着对其他对象的所有引用仍然存在。神奇的__clone
只是query
属性的例外,此处未使用。
为什么需要进行此检查:
if (! isset($builder->scopes[$identifier])) {
continue;
}
this
和builder
是否应该定义相同的范围(甚至对它们的引用相同)?为什么还要麻烦检查呢?
为什么调用this->getModel()
而不是builder.getModel()
?只是因为它更短?