为什么在PHP的laravel模型类中使用静态方法?

时间:2014-07-22 05:28:34

标签: php design-patterns laravel singleton static-methods

在PHP laravel中,我们有像

这样的代码
$user = User::find(1);
var_dump($user->name);

我不关心如何使用find方法,我担心为什么laravel使用静态方法?不应该使用静态方法使该方法难以测试吗?

如果他们使用单身人士设计会更好吗?

e.g。

$user = User::getInstance()->find(1);
var_dump($user->name);

4 个答案:

答案 0 :(得分:16)

事实上,你的例子与Laravel在场景背后的表现非常相似。当你执行User::find()时,实际上是在要求一个新实例,可以是Collection的实例,也可以是QueryBuilder。

照亮\数据库\ Eloquent \ Model(reference):

public static function find($id, $columns = array('*'))
{
    if (is_array($id) && empty($id)) return new Collection;

    $instance = new static;

    return $instance->newQuery()->find($id, $columns);
}

作为旁注,您还会看到另一种在Laravel中使用静态方法的方法,例如: Input::get()。这些被称为外墙。

  

外墙提供静电"与应用程序的IoC容器中可用的类的接口... Laravel" facades"作为"静态代理"到IoC容器中的底层类,提供简洁,富有表现力的语法,同时保持比传统静态方法更多的可测试性和灵活性。

     

当用户引用... facade上的任何静态方法时,Laravel会解析来自IoC容器的缓存绑定,并针对该对象运行所请求的方法(在本例中为get)。

您可以在http://laravel.com/docs/facades

了解有关Larave外墙的更多信息

答案 1 :(得分:14)

Unnawut有一个非常好的答案,但我觉得有必要加上进一步的解释。

在你的例子中

$user = User::find(1);
var_dump($user->name);

Laravel没有使用静态方法,你是。你可能正在寻找的另一种方法是使用依赖注入,Laravel非常容易,因为它可以自动完成。所以在你使用User模型的任何类中,都应该在构造函数中设置类似的东西......

public function __construct(User $user)
{
    $this->user = $user;
}

然后您可以修改代码以不使用静态绑定。

$user = $this->user->find(1);
var_dump($user->name);

答案 2 :(得分:2)

这会限制系统只有一个用户。虽然find方法可能是静态的,但User类将具有其他方法和属性,例如:$user->name

不依赖于任何实例变量的方法,即,变量的值是特定于特定对象实例的,但是提供适用于所有实例的通用功能,可以并且可能应该是静态的。这就是$this运算符在静态方法中是非法的原因,因为它不能引用特定的对象实例。

答案 3 :(得分:-2)

GRASP patterns之后,用户对象无法搜索用户。

您需要一种Filter或Collection对象,::find()方法可帮助您创建Collection过滤器并将结果转换为有用的实体。

对于User实体的使用,您只需更改属性的值并检索值。该实体没有责任根据条件搜索实例。

通过这种逻辑,您将能够以原子碎片的形式解耦代码中的逻辑。