
How to Create and Use Controllers in Laravel
Controllers are the heart of any Laravel application. They act as intermediaries between your routes and your models/views, handling the logic that processes incoming requests and returns responses. In this comprehensive guide, you'll learn everything you need to know about creating and using controllers in Laravel.
What are Controllers?
Controllers are PHP classes that handle HTTP requests and return responses. They organize your application's logic into methods that correspond to different routes. Following the MVC (Model-View-Controller) pattern, controllers:
- Receive input from HTTP requests
- Process the input and interact with models
- Return appropriate responses (views, JSON, redirects, etc.)
Creating Your First Controller
Using Artisan Command
Laravel provides a convenient Artisan command to create controllers:
// Create a basic controller
php artisan make:controller UserController
// Create a controller with resourceful methods
php artisan make:controller UserController --resource
// Create a controller with API methods
php artisan make:controller UserController --api
// Create a controller in a specific namespace
php artisan make:controller Admin/UserController
// Create a controller with model binding
php artisan make:controller UserController --model=User
Basic Controller Structure
Simple Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
// Method to show all users
public function index()
{
return view('users.index');
}
// Method to show a single user
public function show($id)
{
return view('users.show', ['id' => $id]);
}
// Method to create a new user
public function create()
{
return view('users.create');
}
// Method to store a new user
public function store(Request $request)
{
// Handle user creation logic
return redirect()->route('users.index');
}
}
Controller Methods and Routes
Basic Route-Controller Connection
routes/web.php
// Basic route-controller mapping
Route::get('/users', 'UserController@index');
Route::get('/users/{id}', 'UserController@show');
Route::get('/users/create', 'UserController@create');
Route::post('/users', 'UserController@store');
// Or using the controller method (Laravel 8+)
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
Resource Controllers
Creating Resource Controllers
Resource controllers provide a full set of RESTful endpoints for your resources:
// Create a resource controller
php artisan make:controller PostController --resource
// This creates all these methods in your controller:
// index() - Display a listing of the resource
// create() - Show the form for creating a new resource
// store() - Store a newly created resource in storage
// show() - Display the specified resource
// edit() - Show the form for editing the specified resource
// update() - Update the specified resource in storage
// destroy() - Remove the specified resource from storage
Resource Routes
Instead of defining all routes manually, use resource routes:
// Define resource routes
Route::resource('posts', PostController::class);
// This creates all the standard RESTful routes automatically
Controller Constructor and Dependency Injection
Constructor Injection
You can inject dependencies directly into your controller constructor:
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
protected $user;
// Inject User model via constructor
public function __construct(User $user)
{
$this->user = $user;
}
public function index()
{
$users = $this->user->all();
return view('users.index', compact('users'));
}
}
Handling Requests in Controllers
Accessing Request Data
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request)
{
// Get all input data
$allData = $request->all();
// Get specific input data
$name = $request->input('name');
$email = $request->email; // property access
// Check if input exists
if ($request->has('name')) {
// Handle name input
}
// Get input with default value
$age = $request->input('age', 18);
// Get only specific fields
$validatedData = $request->only(['name', 'email']);
// Exclude specific fields
$data = $request->except(['password', '_token']);
return response()->json(['message' => 'Success']);
}
}
Validation in Controllers
Basic Validation
public function store(Request $request)
{
$validatedData = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8|confirmed',
'age' => 'required|integer|min:18'
]);
// If validation passes, create the user
User::create($validatedData);
return redirect()->route('users.index')->with('success', 'User created successfully!');
}
Form Request Validation
For more complex validation, create form requests:
php artisan make:request StoreUserRequest
// In StoreUserRequest.php
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8|confirmed'
];
}
// In Controller
public function store(StoreUserRequest $request)
{
// Validation is automatically handled
$validatedData = $request->validated();
User::create($validatedData);
return redirect()->route('users.index');
}
Returning Responses
View Responses
public function index()
{
$users = User::all();
return view('users.index', compact('users'));
// Or with data
return view('users.index')->with('users', $users);
}
JSON Responses
public function apiUsers()
{
$users = User::all();
// Basic JSON response
return response()->json($users);
// JSON with status code
return response()->json($users, 200);
// JSON with headers
return response()->json($users, 200, ['X-Header' => 'Value']);
}
Redirect Responses
public function store(Request $request)
{
// Basic redirect
return redirect('/users');
// Redirect to named route
return redirect()->route('users.index');
// Redirect with flash data
return redirect()->route('users.index')->with('success', 'User created!');
// Redirect back
return redirect()->back();
// Redirect with input
return redirect()->route('users.create')->withInput();
}
Controller Middleware
Applying Middleware to Controllers
namespace App\Http\Controllers;
class UserController extends Controller
{
// Apply middleware to constructor
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only(['index', 'show']);
$this->middleware('subscribed')->except(['index', 'show']);
}
public function index()
{
// auth middleware is applied here
}
public function store(Request $request)
{
// auth and subscribed middleware are applied here
}
}
Resource Controllers vs. RESTful Controllers
Full Resource Controller Example
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
$users = User::latest()->paginate(10);
return view('users.index', compact('users'));
}
public function create()
{
return view('users.create');
}
public function store(Request $request)
{
$validatedData = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|string|min:8|confirmed'
]);
User::create($validatedData);
return redirect()->route('users.index')
->with('success', 'User created successfully!');
}
public function show(User $user)
{
return view('users.show', compact('user'));
}
public function edit(User $user)
{
return view('users.edit', compact('user'));
}
public function update(Request $request, User $user)
{
$validatedData = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email,' . $user->id,
]);
$user->update($validatedData);
return redirect()->route('users.index')
->with('success', 'User updated successfully!');
}
public function destroy(User $user)
{
$user->delete();
return redirect()->route('users.index')
->with('success', 'User deleted successfully!');
}
}
Conclusion
Controllers are essential for organizing your Laravel application logic. By following best practices like proper validation, dependency injection, and appropriate response types, you can build clean, maintainable, and scalable applications.
Key takeaways:
- Use Artisan commands to generate controllers
- Implement proper validation in your controllers
- Use dependency injection for better testability
- Return appropriate response types (views, JSON, redirects)
- Apply middleware to protect your controller methods
- Follow RESTful principles with resource controllers
Mastering Laravel controllers will help you build more professional and maintainable web applications!
Happy coding! 🚀