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

Rya*_*yan 10 php singleton static-methods design-patterns laravel

在PHP laravel中,我们有类似的代码

$user = User::find(1);
var_dump($user->name);
Run Code Online (Sandbox Code Playgroud)

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

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

例如

$user = User::getInstance()->find(1);
var_dump($user->name);
Run Code Online (Sandbox Code Playgroud)

Unn*_*wut 17

事实上,你的例子与Laravel在幕后的表现非常相似.当你这样做时User::find(),你实际上是在要求一个新的实例,一个是Collection的实例,一个是QueryBuilder.

Illuminate\Database\Eloquent\Model(参考):

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

您可以在http://laravel.com/docs/facades上阅读有关Larave外墙的更多信息


use*_*496 14

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

在你的例子中

$user = User::find(1);
var_dump($user->name);
Run Code Online (Sandbox Code Playgroud)

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

public function __construct(User $user)
{
    $this->user = $user;
}
Run Code Online (Sandbox Code Playgroud)

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

$user = $this->user->find(1);
var_dump($user->name);
Run Code Online (Sandbox Code Playgroud)

  • Whaaaat !! 我们可以在每个立面上做到这一点吗?我可以注入Mail facade然后执行$ this-> mail-> send吗?*0* (3认同)

Ale*_*lex 2

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

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