【发布时间】:2014-05-14 15:05:07
【问题描述】:
每当我向 Eloquent 模型添加额外的逻辑时,我最终不得不将其设为 static 方法(即不太理想)以便从模型的外观调用它。我已经尝试了很多关于如何以正确的方式执行此操作的方法,并且几乎所有结果都讨论了创建返回部分查询生成器接口的方法。我试图弄清楚如何添加可以返回任何内容并使用模型外观调用的方法。
例如,假设我有一个名为 Car 的模型并想要全部获取:
$cars = Car::all();
很好,除了现在,假设我想通过 make 将结果排序为一个多维数组,所以我的结果可能如下所示:
$cars = array(
'Ford' => array(
'F-150' => '...',
'Escape' => '...',
),
'Honda' => array(
'Accord' => '...',
'Civic' => '...',
),
);
以这个理论示例为例,我很想创建一个可以像这样调用的方法:
$cars = Car::getAllSortedByMake();
暂时,让我们忘记可怕的方法名称以及它与数据结构紧密耦合的事实。如果我在模型中创建这样的方法:
public function getAllSortedByMake()
{
// Process and return resulting array
return array('...');
}
最后在我的控制器中调用它,我会抛出这个异常:
不应静态调用非静态方法 Car::getAllSortedByMake(),假设 $this 来自不兼容的上下文
TL;DR:如何在不使其成为静态方法并使用模型外观调用的情况下添加对模型有意义的自定义功能?
编辑:
这是一个理论上的例子。也许改写这个问题会更有意义。为什么在 Eloquent 模型的外观上可以使用某些非静态方法,例如 all() 或 which(),但没有添加到模型中的其他方法?这意味着正在使用__call魔术方法,但是我怎样才能让它识别我自己在模型中的功能呢?
可能比“排序”更好的例子是如果我需要对一条数据运行计算或算法:
$validSPG = Chemical::isValidSpecificGravity(-1.43);
对我来说,将类似的东西放在模型中是有意义的,因为它是特定于领域的。
【问题讨论】:
-
首先有两个数据表:
manufacturers和models,所以manufacturers包含“Ford”、“Honda”等,models与manufacturer_id链接model到manufacturer并包含“F-150”、“Escape”、“Accord”、“Civic”等 -
@MarkBaker 这是一个理论上的例子。我的问题更多的是基本层面,例如为什么
all()可以通过外观访问?它不是静态方法,这意味着正在使用__call魔术方法。因此,为什么arbitraryMethodICreate()无法访问? -
见
Illuminate\Database\Eloquent\Model,all是静态方法 -
cilosis:原因很简单:
all()实际上是Model上的静态方法,在这种情况下不会调用__call。Model类上有更多的静态方法,其他可以使用的方法Model::method()由__callStatic然后__call魔术方法处理并传递给Eloquent Builder类。
标签: php laravel laravel-4 eloquent facade