为什么在 PHP 的 Laravel 模型类中使用静态方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24879567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why use static method in PHP's laravel model class?
提问by Ryan
In PHP laravel, we have codes like
在 PHP laravel 中,我们有类似的代码
$user = User::find(1);
var_dump($user->name);
I am not concerning how to use the find
method, I am concerning why laravel use a static method? Shouldn't the use of static method make the method hard to test?
我不关心如何使用该find
方法,我关心的是为什么 laravel 使用静态方法?使用静态方法不应该使方法难以测试吗?
Will it be better if they designed using singleton?
如果他们使用单例设计会更好吗?
e.g.
例如
$user = User::getInstance()->find(1);
var_dump($user->name);
回答by Unnawut
In fact, your example is very similar to what Laravel does behind the scene. When you do User::find()
, you are actually asking for a new instance, either an instance of Collection or a QueryBuilder.
事实上,您的示例与 Laravel 在幕后所做的非常相似。当您这样做时User::find()
,您实际上是在请求一个新实例,一个 Collection 实例或一个 QueryBuilder。
Illuminate\Database\Eloquent\Model (reference):
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);
}
As a side note, you'll also see another way of using static methods in Laravel e.g. Input::get()
. These are called Facades.
作为旁注,您还将看到在 Laravel 中使用静态方法的另一种方式,例如Input::get()
. 这些被称为门面。
Facades provide a "static" interface to classes that are available in the application's IoC container ... Laravel "facades" serve as "static proxies" to underlying classes in the IoC container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.
When a user references any static method on the ... facade, Laravel resolves the cache binding from the IoC container and runs the requested method (in this case, get) against that object.
Facades 为应用程序的 IoC 容器中可用的类提供了一个“静态”接口...... Laravel“facades”充当 IoC 容器中底层类的“静态代理”,提供简洁、富有表现力的语法的好处,同时保持更多比传统静态方法的可测试性和灵活性。
当用户在 ... Facade 上引用任何静态方法时,Laravel 会解析来自 IoC 容器的缓存绑定,并针对该对象运行请求的方法(在本例中为 get)。
You can read more about Larave's Facades at: http://laravel.com/docs/facades
您可以在以下位置阅读有关 Larave 的 Facades 的更多信息:http://laravel.com/docs/facades
回答by user1669496
Unnawut has a very good answer, however I felt it necessary to add in further explanation.
Unnawut 有一个很好的答案,但是我觉得有必要添加进一步的解释。
In your example
在你的例子中
$user = User::find(1);
var_dump($user->name);
Laravel isn't using a static method, you are. Another way to do this which you are probably looking for is to use dependency injection, which Laravel makes very easy because it can be done automatically. So in whatever class you are using your User
model in, you should be setting up something like this in the constructor...
Laravel 没有使用静态方法,你是。您可能正在寻找的另一种方法是使用依赖注入,Laravel 使这变得非常容易,因为它可以自动完成。因此,在您使用User
模型的任何类中,您都应该在构造函数中设置类似的内容......
public function __construct(User $user)
{
$this->user = $user;
}
And then you can modify your code to not use the static bindings.
然后您可以修改您的代码以不使用静态绑定。
$user = $this->user->find(1);
var_dump($user->name);
回答by Alex
This would restrict the system from only having one User. Whilst the find
method may be static, the User class will have other methods and properties that aren't, a likely example is in your example: $user->name
这将限制系统只有一个用户。虽然该find
方法可能是静态的,但 User 类将具有其他不是静态的方法和属性,一个可能的示例在您的示例中:$user->name
A method that does not rely upon any instance variables, I.e variables who's value is specific to the particular object instance, but instead provides generic functionality that applies to all instances, can, and probably should, be static. This is why the $this
operator is illegal within static methods, as it can make no reference to a particular object instance.
不依赖任何实例变量的方法,即其值特定于特定对象实例的变量,而是提供适用于所有实例的通用功能,可以并且可能应该是静态的。这就是为什么$this
操作符在静态方法中是非法的,因为它不能引用特定的对象实例。
回答by Maxi Capodacqua
Following the GRASP patterns, User object doesn't have the knowledge to able to search a User.
遵循GRASP 模式,用户对象不具备能够搜索用户的知识。
You need a kind of Filter or Collection object, the ::find()
method helps you to create that Collection filter and cast the result in a useful entity.
您需要一种 Filter 或 Collection 对象,该::find()
方法可帮助您创建该 Collection 过滤器并将结果转换为有用的实体。
For the uses of the User
entity, you will just change the value of the properties and retrieve the values. The entity doesn't have the responsibility to search instances based on conditions.
对于User
实体的使用,您只需更改属性的值并检索值。实体没有责任根据条件搜索实例。
With this logic you will be able to decouple logic in the code in atomic pieces.
使用此逻辑,您将能够以原子片段的形式解耦代码中的逻辑。