geo*_*310 4 php laravel laravel-5.1
我在Laravel中有一个模型,它定义了各种范围.我想在很多地方使用它们而不是将它们链接在一起我宁愿只能调用一个调用所有其他范围的范围,如下所示:
function scopeValid($query, $user_id) {
$query = $this->scopeDateValid($query);
$query = $this->scopeMaxUsesValid($query);
$query = $this->scopeCustomerMaxUsesValid($query, $user_id);
return $query;
}
Run Code Online (Sandbox Code Playgroud)
这似乎不起作用,有没有办法实现这一目标?
cee*_*yoz 16
如文档中所示,您将要对范围的魔术函数进行范围界定$query,$this而不是调用内部实现:
public function scopeTesting($query) {
return $query->testingTwo();
}
public function scopeTestingTwo($query) {
return $query->where('testing', true);
}
Run Code Online (Sandbox Code Playgroud)
作为演示,您可以在此处看到调用testing()范围应用范围中的逻辑testingTwo():
>>> App\User::testing()->toSql();
=> "select * from "users" where "testing" = ?"
>>>
Run Code Online (Sandbox Code Playgroud)
所以,对于你的代码,这应该做的伎俩:
function scopeValid($query, $user_id) {
$query = $query->dateValid();
$query = $query->maxUsesValid();
$query = $query->customerMaxUsesValid($user_id);
return $query;
// or just return $query->dateValid()
// ->maxUsesValid()
// ->customerMaxUsesValid($user_id);
}
Run Code Online (Sandbox Code Playgroud)
查询范围是静态调用的.
$users = Model::dateValid()->get()
Run Code Online (Sandbox Code Playgroud)
$this进行静态调用时没有.尝试更换$this->scopeDateValid与self::scopeDateValid
您的代码可能还有其他问题,因为$this实际上Model是调用范围时的实例.您应该能够直接使用$query参数调用类范围方法(就像您所做的那样),或者使用ceejayoz提出的另一个范围方法解析链.
就个人而言,当您知道要在类上调用范围方法时,我认为在完成整个查询范围解析过程中没有太大的优势,但无论哪种方式都有效.
让我们遍历调用堆栈以执行查询范围:
#0 [internal function]: App\User->scopeValid(Object(Illuminate\Database\Eloquent\Builder))
#1 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(829): call_user_func_array(Array, Array)
#2 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(940): Illuminate\Database\Eloquent\Builder->callScope('scopeOff', Array)
#3 [internal function]: Illuminate\Database\Eloquent\Builder->__call('valid', Array)
#4 [internal function]: Illuminate\Database\Eloquent\Builder->valid()
#5 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(3482): call_user_func_array(Array, Array)
#6 [internal function]: Illuminate\Database\Eloquent\Model->__call('valid', Array)
#7 [internal function]: App\User->valid()
#8 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(3496): call_user_func_array(Array, Array)
#9 /app/Http/Controllers/UserController.php(22): Illuminate\Database\Eloquent\Model::__callStatic('valid', Array)
#10 /app/Http/Controllers/UserController.php(22): App\User::valid()
Run Code Online (Sandbox Code Playgroud)
User::scopeValid()电话__callStatic()处理程序Modelpublic static mixed __callStatic(string $ name,array $ arguments)
在静态上下文中调用不可访问的方法时会触发__callStatic().
的注释的代码Model.php的__callStatic()方法(行3492-3497):
public static function __callStatic($method, $parameters)
{
// Uses PHP's late static binding to create a new instance of the
// model class (User in this case)
$instance = new static;
// Call the $method (valid()) on $instance (empty User) with $parameters
return call_user_func_array([$instance, $method], $parameters);
}
Run Code Online (Sandbox Code Playgroud)
User->valid()(不存在)__call处理程序Modelpublic mixed __call(string $ name,array $ arguments)
在对象上下文中调用不可访问的方法时会触发__call().
注释Model.php的__call()方法代码(第3474-3483行):
public function __call($method, $parameters)
{
// increment() and decrement() methods are called on the Model
// instance apparently. I don't know what they do.
if (in_array($method, ['increment', 'decrement'])) {
return call_user_func_array([$this, $method], $parameters);
}
// Create a new \Illuminate\Database\Eloquent\Builder query builder
// initialized with this model (User)
$query = $this->newQuery();
// Call the $method (valid()) on $query with $parameters
return call_user_func_array([$query, $method], $parameters);
}
Run Code Online (Sandbox Code Playgroud)
__call处理程序的查询Builder的注释的代码Builder.php的__call()方法(线933-946):
public function __call($method, $parameters)
{
if (isset($this->macros[$method])) {
// Handle query builder macros (I don't know about them)
array_unshift($parameters, $this);
return call_user_func_array($this->macros[$method], $parameters);
} elseif (method_exists($this->model, $scope = 'scope'.ucfirst($method))) {
// Now we're getting somewhere! Builds the 'scopeValid' string from
// the original 'valid()' method call. If that method exists on the
// model, use it as a scope.
return $this->callScope($scope, $parameters);
}
// Other stuff for fallback
$result = call_user_func_array([$this->query, $method], $parameters);
return in_array($method, $this->passthru) ? $result : $this;
}
Run Code Online (Sandbox Code Playgroud)
callScope()查询方法Builder的注释的代码Builder.php的__call()方法(线825-830):
protected function callScope($scope, $parameters)
{
// Add $this (the query) as the first parameter
array_unshift($parameters, $this);
// Call the query $scope method (scopeValid) in the context of an
// empty User model instance with the $parameters.
return call_user_func_array([$this->model, $scope], $parameters) ?: $this;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4799 次 |
| 最近记录: |