Laravel Controller Dependency Injection

Welcome to the dubious magic of Laravel. The basic idea with these dependency injections is that, depending on how you define your routes & controllers, Laravel can perform some automagical parsing of urls, identification of ids in those urls, and database fetching of objects.

My problem is I don't understand where the $user is coming from.

You should probably read the docs on the service container. You can also get a better idea of how your route definitions translate into parameter-laden urls with this command:

php artisan route:list

On one of my projects, this results in this output:

+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+
| Domain | Method    | URI                        | Name               | Action                                          | Middleware   |
+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+
|        | GET|HEAD  | /                          |                    | Closure                                         | web          |
|        | GET|HEAD  | api/user                   |                    | Closure                                         | api,auth:api |
|        | GET|HEAD  | categories                 | categories.index   | App\Http\Controllers\CategoryController@index   | web          |
|        | POST      | categories                 | categories.store   | App\Http\Controllers\CategoryController@store   | web          |
|        | GET|HEAD  | categories/create          | categories.create  | App\Http\Controllers\CategoryController@create  | web          |
|        | GET|HEAD  | categories/{category}      | categories.show    | App\Http\Controllers\CategoryController@show    | web          |
|        | PUT|PATCH | categories/{category}      | categories.update  | App\Http\Controllers\CategoryController@update  | web          |
|        | DELETE    | categories/{category}      | categories.destroy | App\Http\Controllers\CategoryController@destroy | web          |
|        | GET|HEAD  | categories/{category}/edit | categories.edit    | App\Http\Controllers\CategoryController@edit    | web          |
|        | GET|HEAD  | products                   | products.index     | App\Http\Controllers\ProductController@index    | web          |
|        | POST      | products                   | products.store     | App\Http\Controllers\ProductController@store    | web          |
|        | GET|HEAD  | products/create            | products.create    | App\Http\Controllers\ProductController@create   | web          |
|        | GET|HEAD  | products/{product}         | products.show      | App\Http\Controllers\ProductController@show     | web          |
|        | PUT|PATCH | products/{product}         | products.update    | App\Http\Controllers\ProductController@update   | web          |
|        | DELETE    | products/{product}         | products.destroy   | App\Http\Controllers\ProductController@destroy  | web          |
|        | GET|HEAD  | products/{product}/edit    | products.edit      | App\Http\Controllers\ProductController@edit     | web          |
+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+

And all those routes and their uris and parameters are generated from only a couple of very simple routes definitions. Here's my routes file:

$ cat routes/web.php
<?php

Route::get('/', function () {
    return view('master');
});

Route::resource('products', 'ProductController');
Route::resource('categories', 'CategoryController');

If you look at the list of URIs in the routes output above, you'll see parameters named in the URIs like {category} and {product}. These correspond to ids/keys in the URI which Laravel identifies. Laravel is "smart" enough to look at my Controller files, see the type-hinting in the various functions and detect that my function is expecting a depedency to be injected.

For instance, the Category controller's show method looks like this:

public function show(Tree $category)
{
    var_dump($category);
}

My controller might seem a little unusual because I'm type hinting that I want an object of type Tree, but Laravel is smart enough to recognize that I do in fact want a Model of type Tree, so it parses out the url and finds the id in it and automatically fetches the record in my db table trees with id matching the {category} fragment of my url and injects that into my function.

Note that I had some trouble when I tried to name the input parameter $tree instead of $category. That other thread may help answer your question a bit too.

The bottom line is that Laravel does a lot of "magic" to hopefully free you up from the tedious of manually defining your own code and queries to retrieve the objects you want.


In Laravel dependency injection is handled by the Container. I'm simplifying, but you can think of the container as a source of objects. If there is a singleton, its stored in the container. Otherwise the container knows how to instantiate objects for you. Whenever Laravel calls a method (like in a controller) or instantiates an object for you it will inspect the constructor and look for type hinted dependencies. If it sees a dependency it knows how to retrieve or create it will do so and pass it in for you.

So when Laravel instantiates the controller it looks at the constructor

public function __construct(UserRepository $user)
{
    $this->user = $user;
}

The container uses Type Hinting to see that it requires a UserRepository so it will instantiate a new one for you. It also does this recursively. So when it creates a new UserRepository it looks at that constructor and sees that it requires a RoleRepository so it will instantiate that as well.

TLDR: The service container inspects your dependencies and will instantiate them for you.