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:
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:
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:
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:
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
:
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:
Another things we can do here is to choose a name according to our route:
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:
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.
You can ignore it now with following command:
php artisan r:l --except-vendor
Here we go!
Wait wait! This is also feasible to filter this list with --name
flag by the name we defined for our route:
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 :
"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
:
"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:
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! 🤯
> 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!
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!
Top comments (3)
Where you use __invoke() method? I don't see. This post is bit confusing.
Hey there!
As I mentioned in the post you need only rename your function into __invoke
Btw, I recently made a few tweaks to make it more clear!
Thanks for updating the post, let me check this again.