Laravel 13.x — Controller

Membuat Controller

Default controller

<?php
 
namespace App\Http\Controllers;
 
use App\Models\User;
use Illuminate\View\View;
 
class UserController extends Controller
{
    /**
     * Tampilkan profil untuk pengguna tertentu.
     */
    public function show(string $id): View
    {
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}

Controller di atas dapat digunakan untuk route:

use App\Http\Controllers\UserController;
 
Route::get('/user/{id}', [UserController::class, 'show']);

Single action controller

<?php

namespace App\Http\Controllers;

class ProvisionServer extends Controller
{
    /**
     * Provision a new web server.
     */
    public function __invoke()
    {
        // ...
    }
}

Single action controller di atas dapat digunakan untuk route tanpa menyebutkan method:

use App\Http\Controllers\ProvisionServer;

Route::post('/server', ProvisionServer::class);

Menggunakan Middleware pada Controller

Di route

Route::get('/profile', [UserController::class, 'show'])->middleware('auth');

Di controller pakai middleware() method

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;

class UserController implements HasMiddleware
{
    /**
     * Get the middleware that should be assigned to the controller.
     */
    public static function middleware(): array
    {
        return [
            'auth',
            new Middleware('log', only: ['index']),
            new Middleware('subscribed', except: ['store']),
        ];
    }

    // ...
}

Di controller pakai atribut Middleware

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Attributes\Controllers\Middleware;

#[Middleware('auth')]
#[Middleware('log', only: ['index'])]
#[Middleware('subscribed', except: ['store'])]
class UserController
{
    // ...
}

Di controller method pakai atribut Middleware

<?php

namespace App\Http\Controllers;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Routing\Attributes\Controllers\Middleware;

#[Middleware('auth')]
class UserController
{
    #[Middleware('log')]
    #[Middleware('subscribed')]
    public function index()
    {
        // ...
    }

    #[Middleware(static function (Request $request, Closure $next) {
        // ...

        return $next($request);
    })]
    public function store()
    {
        // ...
    }
}

Di controller method pakai atribut Authorize untuk auth

Apabila otorisasi action controller melalui policies, attribute Authorize dapat digunakan sebagai shortcut untuk middleware can:

<?php

namespace App\Http\Controllers;

use App\Models\Comment;
use App\Models\Post;
use Illuminate\Routing\Attributes\Controllers\Authorize;

class CommentController
{
    #[Authorize('create', [Comment::class, 'post'])]
    public function store(Post $post)
    {
        // ...
    }

    #[Authorize('delete', 'comment')]
    public function destroy(Comment $comment)
    {
        // ...
    }
}

Argumen pertama adalah ability yang ingin diotorisasi. Argumen kedua adalah model, parameter route, atau sekumpulan parameter yang harus diteruskan ke policy.

Resource controller

Routing ke resource controller

use App\Http\Controllers\PhotoController;
 
// Hanya untuk 1 resource
Route::resource('photos', PhotoController::class);

// Beberapa resource sekaligus
Route::resources([
    'photos' => PhotoController::class,
    'posts' => PostController::class,
]);

Deklarasi route ini otomatis membuat banyak route untuk menangani berbagai tindakan pada setiap resource.

Routing ke resource controller untuk beberapa action saja

use App\Http\Controllers\PhotoController;
 
Route::resource('photos', PhotoController::class)->only([
    'index', 'show'
]);
 
Route::resource('photos', PhotoController::class)->except([
    'create', 'store', 'update', 'destroy'
]);

Routing ke resource controller untuk API

use App\Http\Controllers\PhotoController;
 
Route::apiResource('photos', PhotoController::class);
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\PostController;
 
Route::apiResources([
    'photos' => PhotoController::class,
    'posts' => PostController::class,
]);
Apa bedanya resource controller untuk API?

Resource route yang dikonsumsi oleh API biasanya mengecualikan route yang menyajikan template HTML seperti create dan edit.

Routing ke resource controller yang bisa soft delete

Route::softDeletableResources([
    'photos' => PhotoController::class,
    'posts' => PostController::class,
]);

Handle missing model

Kalau tidak di-handle misalnya seperti di bawah ini, secara default, missing model akan di-redirect ke 404 error page.

use App\Http\Controllers\PhotoController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;

Route::resource('photos', PhotoController::class)
    ->missing(function (Request $request) {
        return Redirect::route('photos.index');
    });

Handle missing model (soft deleted)

Mengizinkan soft deleted models untuk rute resource show, edit, dan update:

use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class)->withTrashed();

Hanya untuk rute show:

Route::resource('photos', PhotoController::class)->withTrashed(['show']);

Perintah PHP Artisan

Membuat controller

php artisan make:controller UserController

Membuat single action controller / invokable controller

php artisan make:controller ProvisionServer --invokable

Membuat resource controller

# Tanpa menyebutkan model
php artisan make:controller PhotoController --resource

# Dengan menyebutkan model
php artisan make:controller PhotoController --model=Photo --resource

# Menghasilkan form request classes untuk method store dan update
php artisan make:controller PhotoController --model=Photo --resource --requests
Verb URI Action Route Name
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

Membuat resource controller untuk API

php artisan make:controller PhotoController --api.................................