PHP logoPHPINTERMEDIATE

Laravel

Laravel cheat sheet with Eloquent ORM, routing, Blade templates, middleware, authentication, and Artisan commands with code examples.

20 min read
laravelphpframeworkeloquentbladeartisanmvcapi

Other PHP Sheets

Sign in to mark items as known and track your progress.

Sign in

Setup & Artisan

Installation and Artisan commands

Installation & Setup

Installing Laravel and initial setup

php
# Install Laravel via Composer
composer create-project laravel/laravel myapp
cd myapp

# Or using Laravel installer
composer global require laravel/installer
laravel new myapp

# Start development server
php artisan serve

# Environment setup
cp .env.example .env
php artisan key:generate

# Database setup
php artisan migrate
php artisan db:seed
💡 Use Laravel installer for quick project setup
⚡ Artisan serve is for development only, use proper web server in production
📌 Always run key:generate for new installations
🔥 Cache config, routes, and views in production for performance

Artisan Commands

Essential Artisan CLI commands

php
# Make commands
php artisan make:controller UserController
php artisan make:model User -m  # With migration
php artisan make:migration create_users_table
php artisan make:seeder UserSeeder
php artisan make:factory UserFactory
php artisan make:middleware AuthMiddleware
php artisan make:request StoreUserRequest

# List routes
php artisan route:list
php artisan route:list --path=api

# Tinker (REPL)
php artisan tinker
>>> User::all();
>>> User::find(1);
💡 Use flags like -mfsc to generate multiple related files at once
⚡ Tinker is great for testing queries and debugging
📌 Always clear caches after deployment
🔥 Use queue:work for production, queue:listen for development

Routing

Defining routes and route handling

Basic Routing

Defining routes and HTTP verbs

php
// routes/web.php
// Basic routes
Route::get('/', function () {
    return view('welcome');
});

Route::get('/users', [UserController::class, 'index']);
Route::post('/users', [UserController::class, 'store']);
Route::put('/users/{id}', [UserController::class, 'update']);
Route::delete('/users/{id}', [UserController::class, 'destroy']);

// Route parameters
Route::get('/users/{id}', function ($id) {
    return User::find($id);
});

// Optional parameters
Route::get('/posts/{id?}', function ($id = null) {
    return $id ?? 'All posts';
});
💡 Use route model binding for automatic model resolution
⚡ Group routes to apply common middleware, prefixes, or namespaces
📌 Named routes prevent hardcoding URLs in views
🔥 Use where() constraints to validate route parameters

Resource & API Routes

RESTful resource routing and API routes

php
// Resource routes (all CRUD operations)
Route::resource('posts', PostController::class);

// Partial resource routes
Route::resource('photos', PhotoController::class)->only([
    'index', 'show'
]);

Route::resource('photos', PhotoController::class)->except([
    'create', 'store', 'update', 'destroy'
]);

// API routes (routes/api.php)
Route::apiResource('posts', PostController::class);

// Nested resources
Route::resource('posts.comments', CommentController::class);
💡 Use apiResource for APIs (no create/edit routes)
⚡ Shallow nesting prevents deeply nested URLs
📌 Resource routes follow RESTful conventions
🔥 API routes are automatically prefixed with /api

Controllers

Controller patterns and request handling

Controllers & Requests

Controller structure and request handling

php
<?php
namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index()
    {
        $users = User::paginate(15);
        return view('users.index', compact('users'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:8|confirmed',
        ]);

        $user = User::create($validated);

        return redirect()->route('users.show', $user);
    }
}
💡 Use Form Requests for complex validation logic
⚡ Route model binding automatically injects models
📌 Authorize actions using policies in controllers
🔥 Use resources for consistent API responses

Middleware

Creating and using middleware

php
// Apply middleware to routes
Route::get('/admin', function () {
    //
})->middleware('auth', 'admin');

// Middleware groups
Route::middleware(['auth', 'verified'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
});

// Controller middleware
class UserController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('log')->only('index');
    }
}
💡 Middleware can run before and/or after request handling
⚡ Use terminable middleware for logging/cleanup after response
📌 Group middleware for applying to multiple routes
🔥 Rate limiting prevents abuse and protects APIs

Eloquent ORM

Database models and relationships

Models & Queries

Eloquent model basics and querying

php
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = ['title', 'body', 'user_id'];

    // Basic queries
    $posts = Post::all();
    $post = Post::find(1);
    $post = Post::where('status', 'published')->first();
    $posts = Post::where('views', '>', 100)->get();

    // Create, update, delete
    $post = Post::create(['title' => 'New Post']);
    $post->update(['title' => 'Updated']);
    $post->delete();
}
💡 Use fillable or guarded to protect against mass assignment
⚡ Casts automatically convert attributes to specified types
📌 Soft deletes keep records in database with deleted_at timestamp
🔥 Use chunking for processing large datasets efficiently

Relationships

Defining and using Eloquent relationships

php
// One to Many
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

// Usage
$user = User::find(1);
$posts = $user->posts;

$post = Post::find(1);
$author = $post->user;
💡 Use eager loading with() to prevent N+1 queries
⚡ Polymorphic relations allow a model to belong to multiple types
📌 Use withPivot() to access additional pivot table columns
🔥 whereHas() filters models based on relationship conditions

Scopes & Collections

Query scopes and collection methods

php
// Local scope
class Post extends Model
{
    public function scopePublished($query)
    {
        return $query->where('status', 'published');
    }

    public function scopePopular($query, $views = 100)
    {
        return $query->where('views', '>', $views);
    }
}

// Usage
$posts = Post::published()->get();
$posts = Post::popular(500)->published()->get();
💡 Scopes encapsulate common query constraints for reusability
⚡ Collections provide powerful array manipulation methods
📌 Use cursor() or chunk() for memory-efficient large datasets
🔥 Higher order messages simplify collection operations

Migrations & Schema

Database migrations and schema building

Migrations

Creating and managing database migrations

php
// Create migration
php artisan make:migration create_posts_table

// Migration structure
public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('body');
        $table->foreignId('user_id')->constrained();
        $table->timestamps();
    });
}

public function down()
{
    Schema::dropIfExists('posts');
}
💡 Use foreign key constraints for referential integrity
⚡ Add indexes to columns used in WHERE clauses
📌 Use softDeletes() for keeping deleted records
🔥 Always define down() method for rollbacks

Blade Templates

Blade templating engine and components

Blade Basics

Blade syntax and directives

php
{{-- Comment --}}

{{-- Output --}}
{{ $variable }}
{!! $html !!}  {{-- Unescaped --}}

{{-- Directives --}}
@if($user)
    <p>{{ $user->name }}</p>
@elseif($guest)
    <p>Guest</p>
@else
    <p>No user</p>
@endif

@foreach($users as $user)
    <p>{{ $user->name }}</p>
@endforeach
💡 {{ }} escapes output, {!! !!} displays raw HTML
⚡ @forelse handles empty collections elegantly
📌 $loop variable provides useful iteration information
🔥 @once ensures code runs only once in loops

Layouts & Components

Blade layouts, components, and slots

php
{{-- Layout file: layouts/app.blade.php --}}
<!DOCTYPE html>
<html>
<head>
    <title>@yield('title', 'Default Title')</title>
</head>
<body>
    @section('sidebar')
        Default sidebar
    @show

    <div class="container">
        @yield('content')
    </div>
</body>
</html>

{{-- Child view --}}
@extends('layouts.app')

@section('title', 'Page Title')

@section('content')
    <p>Page content</p>
@endsection
💡 Use @parent to include parent section content
⚡ Components promote reusability and clean templates
📌 Anonymous components are simpler for basic needs
🔥 x-slot allows multiple named slots in components

Authentication & Authorization

User authentication and authorization

Authentication

User authentication with Laravel

php
// Check authentication
if (Auth::check()) {
    // User is logged in
}

// Get authenticated user
$user = Auth::user();
$user = auth()->user();
$user = $request->user();

// Login
Auth::login($user);
Auth::loginUsingId(1);

// Logout
Auth::logout();
💡 Use Laravel Breeze for simple authentication scaffolding
⚡ Always regenerate session after login for security
📌 Use guards for multiple authentication systems
🔥 Remember to hash passwords with Hash::make()

Authorization

Gates and policies for authorization

php
// Gates
Gate::define('edit-post', function ($user, $post) {
    return $user->id === $post->user_id;
});

if (Gate::allows('edit-post', $post)) {
    // User can edit
}

// Policies
php artisan make:policy PostPolicy --model=Post

// In controller
$this->authorize('update', $post);
💡 Gates are simple closures, policies are classes for models
⚡ Use before() hook for super admin bypass
📌 Policies automatically discovered if naming convention followed
🔥 authorize() method throws 403 exception if unauthorized

API Development

Building APIs with Laravel

API Routes & Resources

Building RESTful APIs

php
// API routes (routes/api.php)
Route::apiResource('posts', PostController::class);

// API resource (transformation)
php artisan make:resource PostResource

class PostResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'body' => $this->body,
            'author' => new UserResource($this->user),
        ];
    }
}
💡 Use API resources to transform model data consistently
⚡ whenLoaded() prevents N+1 queries in resources
📌 API routes are automatically prefixed with /api
🔥 Use conditional fields to hide sensitive data

Authentication & Sanctum

API authentication with Laravel Sanctum

php
// Install Sanctum
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

// User model
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens;
}

// Create token
$token = $user->createToken('token-name');
return $token->plainTextToken;
💡 Sanctum provides both token and cookie-based authentication
⚡ Use abilities for fine-grained API permissions
📌 SPA auth uses cookies, mobile uses tokens
🔥 Always revoke tokens on logout for security

Testing

Testing Laravel applications

Feature & Unit Tests

Writing and running tests

php
// Feature test
public function test_homepage_returns_successful_response()
{
    $response = $this->get('/');

    $response->assertStatus(200);
    $response->assertSee('Welcome');
}

// Unit test
public function test_user_has_full_name()
{
    $user = new User(['first_name' => 'John', 'last_name' => 'Doe']);

    $this->assertEquals('John Doe', $user->fullName());
}

// Run tests
php artisan test
php artisan test --filter=UserTest
💡 Use RefreshDatabase trait for database isolation
⚡ Mock external services to avoid dependencies
📌 Test both success and failure paths
🔥 Run tests in parallel for faster execution

Advanced Features

Queues, events, caching, and more

Queues & Jobs

Background job processing

php
// Create job
php artisan make:job ProcessPayment

// Dispatch job
ProcessPayment::dispatch($order);
ProcessPayment::dispatch($order)->delay(now()->addMinutes(10));

// Job class
class ProcessPayment implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function handle()
    {
        // Process payment
    }
}
💡 Use queues for time-consuming tasks to improve response time
⚡ Horizon provides beautiful dashboard for Redis queues
📌 Chain jobs for sequential processing
🔥 Use Supervisor to keep queue workers running

Caching

Caching strategies in Laravel

php
// Store in cache
Cache::put('key', 'value', $seconds);
Cache::put('key', 'value', now()->addMinutes(10));

// Get from cache
$value = Cache::get('key');
$value = Cache::get('key', 'default');

// Remember pattern
$users = Cache::remember('users', 3600, function () {
    return User::all();
});
💡 Use remember() pattern for expensive queries
⚡ Cache tags allow grouped cache invalidation
📌 Redis/Memcached recommended for production
🔥 Always cache config/routes in production

More PHP Cheat Sheets