patrickmaciel's avatar

Why use app(Model::class) instead of Model::class directly ?

Today I found some videos about Laravel and they call Models different than I did from my entire life. For me, when I need to call all the registers I do:

$users = User::all();

But I see some guys doing:

$users = app(User::class)->all();

Work the same way but. What's the difference? Why use app( )?

0 likes
8 replies
tykus's avatar

In the latter, the User class is resolved out of the Service Container giving you an instantiated instance to work with. So, theoretically you could bind a different User::class implementation into the Container. Why; no idea... pretentious nonsense 🤷‍♂️

jlrdw's avatar

:: clas Returns the fully qualified name of the class.

Also I would recommend looking up classes in the PHP manual.

kokoshneta's avatar

@jlrdw The question isn’t about what a class is, but what (if any) possible benefit there can be to instantiating the class through the service container in order to run a method that’s already available.

These three all result in the exact same method being eventually called:

$users = User::all();
$users = (new User)->all();
$users = app(User::class)->all();

The only difference is the number of function calls invoked before ->all() gets called, and whether or not an object is created in memory first.

  • The first creates no object in memory and calls just one method: the static method on the class.
  • The second creates an object in memory and calls two methods: the class’s constructor, and then the static all() on the class derived from the instance.
  • The third creates an object in memory and calls about a dozen different methods before finally returning an instance and calling static all() on the class derived from the instance.

Number 3 in particular seems uselessly wasteful. It called a dozen methods from various classes just to return an object that’s used for absolutely nothing other than to retrieve the class name – which was provided as a parameter to the app() helper to begin with!

So as far as I can tell, the answer to the question asked is that there is absolutely no point or benefit to using app() here, unless (as @tykus says) you bind a different implementation into the service container… but that would be an utterly idiotic thing to do.

4 likes
jonlink's avatar

@kokoshneta If the user class is a singleton defined in a service provider there's a benefit. Also testing. It's easy to mock the user class if needed when done with app(User::class). The same can't be said of options 1 and 2, can it?

kokoshneta's avatar

@jonlink That is true – those are two use cases where the trade-off of the extra function calls would be worth it. But I can’t say I’ve ever come across a situation where a user model would need to be defined as a singleton in a service provider; mocking seems like a more likely scenario, but personally I’ve never been in a situation where I’ve had to mock a user model either, so it didn’t occur to me.

kokoshneta's avatar

Using a service container to resolve a class into an instance just so you can call what’s already a static class method on that instance seems like some kind of bizarre antipattern to me. Don’t know what kind, but some kind, surely.

The method is static; calling it statically directly on the class seems the logical way to use it.

renzocastillo's avatar

I have also seen this app(class name) usage at some cases.

Could it be because they want to bind an specific class to service container for maybe mocking its behavior later while testing?

1 like
Snapey's avatar

@renzocastillo might be useful in the context of a package incase the app has named their users by some other model.

Please or to participate in this conversation.