Laravel101: Exploring Laravel Controllers and Namespace Loading
Tags: laravel, php, tutorial
Published: 2023-07-29 12:24:38

Hey there!

In our last tutorial, we talked about how sending and processing data in routes. but it can get super messy, especially when we’ve got a lot of information to deal with. Lucky for us, Laravel has got our back with a solution — controllers!

---

What we need to know about controllers in Laravel is that controllers are classes that prepare data to be sent to the view.

Creating a controller is a piece of cake — just use the `artisan` command! You might remember using the `php artisan serve` command to create a local server. Well, if you enter the `php artisan` command in the main path of your Laravel project, you’ll see all the amazing things you can do with it.

Every artisan command comes with a handy description to guide you through it. For example, if you want to learn more about the controller, just type in your terminal following command and you’ll get all the juicy details:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6n5tpgvea28ynwcrfhyj.png)

Alright, let’s keep this train rolling! So, when it comes to creating a controller in Laravel, the main argument of the command is simply the name of the controller. Easy peasy, right? As for the other features, don’t worry, we’ll dive into those in future tutorials. But for now, let’s focus on the task at hand!

So, for our project example from the previous article, we want to create a controller that sends data to the view through the controller instead of the route. To make this happen, we just need to create the controller using the following command:
```shell
php artisan make:controller UserController
```
Now let’s open it and move our function inside the route into here and choose a name for that like friends:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dm9hyqs58n4m0l9b0gi0.png)


Finally, it is enough to go back to the web route and give the name of the class and the function that returns this output as an array instead our function like bellow:
```php
Route::get('/friends', [
    App\Http\Controllers\UserController::class, 
    'friends'
]);
```
A super neat trick that I really like it is when you have only one function in a controllers! There is a magic method called the `__invoke()`, and believe me it's pretty cool. It’s exactly like anonymous callback function we used it directly in route. So the only thing you need is just rename your function in controller to `__invoke` :


```php
class UserController extends Controller 
{
    public function __invoke()
    {
        $users = ['John', 'Mike', 'Susan', 'Jimmy', 'Kazem'];
        return view('me.friends', compact('users'));
    }
}

```

Then the friends route is going to like this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pljq5jtpesga8th0541g.png)


Another things we can do here is to choose a name according to our route:
```php
Route::get('/friends', UserController::class)->name('user.friends');
```
Now if you run following command in your terminal you’ll see all the route exist currently in your app:
```sh
php artisan route:list 

// or

php artisan r:l
```
But as you see in your terminal there also some other routes which are not specified with us! These are related to packages which comes with laravel as default.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctj9ba36fwu9v9pj39p1.png)

You can ignore it now with following command:
```sh
php artisan r:l --except-vendor
```
Here we go!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qwpzwympls1yd66wf02x.png)

Wait wait! This is also feasible to filter this list with `--name` flag by the name we defined for our route:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nj8mxs2f70dtde76w2o.png)


It’s always a good idea to give meaningful names to your routes in Laravel. This makes it easier to group and filter them, which can be really helpful when you have a lot of routes in your application.

---

### What’s a Namespace?

If you’re new to PHP and you see the keyword “namespace” inside a controller, don’t worry! It’s actually a really helpful feature.

Namespaces are a way to organize your code and avoid naming conflicts with other classes that might have the same name. They help you load classes into different groups so that you can use them more efficiently.

Let’s say you want to create a new `UserController` but you already have it! to do that you have create another directory like Profile , Then, when you want to use your new user controller in your routes, you can simply specify its namespace location, like this: `use App\Http\Controllers\Profile\UserController.`

This separates it from the original `UserControllerand` avoids any naming conflicts. Pretty cool, right?

### What? PSR-4? did you heard that one too?!

It’s a fancy name for a PHP standard, but don’t worry, it’s not some strange creature! Basically, PSR-4 helps you organize your code by mapping your namespaces to directories on your, is it clear? let me explain it with an example.

Suppose we want instead of writing out `use App\Http\Controllers\UserController` just use `use Controllers\UserController`

To make this magic happen, you’ll need to do a little editing in your composer.json file. It’s kind of like the package.json file in a Node.js project and contains some basic configuration. Inside, you’ll find a section called autoload :
```json
"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Database\\Factories\\": "database/factories/",
        "Database\\Seeders\\": "database/seeders/"
    }
},
"autoload-dev": {
    "psr-4": {
        "Tests\\": "tests/"
    }
},
```
`autoload-dev` used for dev environment so for now we just need to define our new loading rule like bellow inside `autoload`:
```json
"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Controllers": "app/Http/Controolers/",
        "Database\\Factories\\": "database/factories/",
        "Database\\Seeders\\": "database/seeders/"
    }
},
```
And change namespace for every controller inside app/Http/Controllers to namespace Controllers .

Then we can point out to our controller simply like this:
```php
Route::get('/friends', Controllers\UserController::class)
  ->name('user.friends');

// or 

use Controllers\UserController;
Route::get('/friends', UserController::class)->name('user.friends');
```

If you do that you’ll get the following error! 🤯


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mjm0mqxbi24tu70kprii.png)

_> **Here is the deal**: If you make any changes to your composer.json file, you’ll need to run the following command to set up those changes in your project!_
```sh
composer dump-autoload
```
---

And voila! In this tutorial, you have learned how to send data through the controller class in Laravel, both in routes and views. You’ve also learned a bit about namespaces and loading classes in Laravel. In the next article, we’ll delve deeper into the blade structure and show you how to create a more suitable layout for your current project. It’s going to be awesome!