All skills
asyrafhussin avatar

/laravel-best-practices

@ef59186

Laravel 13 conventions and best practices. Use when creating controllers, models, migrations, validation, services, or structuring Laravel applications. Triggers on tasks involving Laravel architecture, Eloquent, database, API development, or PHP patterns.

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/laravel-best-practices

This session only. Nothing lands on disk.

rulescontroller-middleware.md

≈1.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Controller Middleware

Impact: MEDIUM (Reusable request filtering and modification)

Use middleware to handle cross-cutting concerns like authentication, rate limiting, and request modification.

Bad Example

// Authentication and authorization checks in every method
class AdminController extends Controller
{
    public function index()
    {
        if (!auth()->check()) {
            return redirect()->route('login');
        }

        if (!auth()->user()->isAdmin()) {
            abort(403);
        }

        return view('admin.dashboard');
    }

    public function users()
    {
        if (!auth()->check()) {
            return redirect()->route('login');
        }

        if (!auth()->user()->isAdmin()) {
            abort(403);
        }

        return view('admin.users');
    }

    public function settings()
    {
        if (!auth()->check()) {
            return redirect()->route('login');
        }

        if (!auth()->user()->isAdmin()) {
            abort(403);
        }

        return view('admin.settings');
    }
}

Good Example

// PHP Attributes (Laravel 13+) — preferred declarative approach
use App\Models\Comment;
use App\Models\Post;
use Illuminate\Routing\Attributes\Controllers\Authorize;
use Illuminate\Routing\Attributes\Controllers\Middleware;

#[Middleware('auth')]
#[Middleware('admin')]
class AdminController extends Controller
{
    public function index()
    {
        return view('admin.dashboard');
    }

    #[Middleware('verified')]
    #[Authorize('manage', [Post::class])]
    public function posts()
    {
        return view('admin.posts');
    }

    #[Middleware('subscribed')]
    #[Authorize('create', [Comment::class, 'post'])]
    public function store(Post $post)
    {
        // ...
    }
}
// HasMiddleware interface (Laravel 11+) — still supported
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;

class AdminController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            'auth',
            'admin',
            new Middleware('verified', only: ['store', 'update']),
            new Middleware('throttle:10,1', only: ['store']),
        ];
    }

    public function index()
    {
        return view('admin.dashboard');
    }

    public function users()
    {
        return view('admin.users');
    }
}
// Using middleware in routes
Route::middleware(['auth', 'admin'])->group(function () {
    Route::get('/admin', [AdminController::class, 'index']);
    Route::resource('admin/users', AdminUserController::class);
});
// Custom middleware
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureUserIsAdmin
{
    public function handle(Request $request, Closure $next): Response
    {
        if (!$request->user()?->isAdmin()) {
            abort(403, 'Unauthorized. Admin access required.');
        }

        return $next($request);
    }
}
// Register middleware alias in bootstrap/app.php (Laravel 11+)
// Note: The $middleware parameter here is Illuminate\Foundation\Configuration\Middleware,
// not Illuminate\Routing\Controllers\Middleware used above in the controller.
return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias([
            'admin' => EnsureUserIsAdmin::class,
            'subscribed' => EnsureUserIsSubscribed::class,
        ]);
    })
    ->create();
// Middleware with parameters
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class CheckRole
{
    public function handle(Request $request, Closure $next, string ...$roles): Response
    {
        if (!$request->user()?->hasAnyRole($roles)) {
            abort(403);
        }

        return $next($request);
    }
}
// Usage with parameters
Route::get('/reports', [ReportController::class, 'index'])
    ->middleware('role:admin,manager');

// Middleware for API rate limiting
Route::middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::apiResource('posts', PostController::class);
});
// Conditional middleware using HasMiddleware
class ApiController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            'auth:sanctum',
        ];
    }
}
// Middleware groups for common patterns
// bootstrap/app.php
$middleware->group('api', [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
]);

Why

  • DRY: Authentication/authorization logic in one place
  • Reusability: Same middleware used across multiple controllers
  • Separation of concerns: Controllers focus on business logic
  • Composability: Stack multiple middleware for complex requirements
  • Testability: Middleware tested independently
  • Declarative: PHP attributes (Laravel 13+) make middleware and authorization visible at the class/method level
  • Colocated: #[Authorize] keeps policy checks next to the method they protect

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a comprehensive guide to Laravel 13 best practices, providing safe and standard architectural, database, and security patterns for PHP development. No malicious behavior or security risks were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    1/37 files flagged

  • ZeroLeaks5mo

    2 findings · Score: 80/100

Signed by skilld at ef59186. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 7 months ago
Other metadata
metadata
{
  "author": "Laravel Community",
  "version": "2.1.0",
  "laravelVersion": "13.x",
  "phpVersion": "8.3+"
}

README badge

README badge for asyrafhussin/agent-skills/laravel-best-practices