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

在PHP laravel中,我们有这样的代码

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

我不是在讨论如何使用方法,我是在为何使用静态方法?静态方法的使用难道不应该使方法难以测试吗?find

如果他们使用单例进行设计会更好吗?

例如:

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

答案 1

事实上,你的例子与Laravel在幕后所做的非常相似。当您这样做时,您实际上是在请求一个新实例,即 Collection 的实例或 QueryBuilder 的实例。User::find()

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);
}

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

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

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

您可以在以下位置阅读有关Larave's Facades的更多信息:http://laravel.com/docs/facades


答案 2

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);

推荐