Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use static method in PHP's laravel model class?

In PHP laravel, we have codes like

$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?

Will it be better if they designed using singleton?

e.g.

$user = User::getInstance()->find(1);
var_dump($user->name);
like image 242
Ryan Avatar asked Jul 22 '14 05:07

Ryan


3 Answers

Unnawut has a very good answer, however I felt it necessary to add in further explanation.

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...

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);
like image 100
user1669496 Avatar answered Oct 30 '22 00:10

user1669496


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.

Illuminate\Database\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);
}

As a side note, you'll also see another way of using static methods in Laravel e.g. Input::get(). These are called Facades.

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.

You can read more about Larave's Facades at: http://laravel.com/docs/facades

like image 29
Unnawut Avatar answered Oct 30 '22 01:10

Unnawut


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

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.

like image 41
Alex Avatar answered Oct 30 '22 00:10

Alex