Przejdź do treściMDS CloudNOWOŚĆWypróbuj mdscloud.pl
Backend

Laravel - kompletny przewodnik po najpopularniejszym frameworku PHP

Opublikowano:
·5 min czytania·Autor: MDS Software Solutions Group

Laravel kompletny przewodnik

backend

Laravel - kompletny przewodnik po najpopularniejszym frameworku PHP

Laravel to framework PHP, który zrewolucjonizował sposób tworzenia aplikacji webowych. Od momentu premiery w 2011 roku, autorstwa Taylora Otwella, stał się najpopularniejszym frameworkiem w ekosystemie PHP, a jego elegancka składnia i bogaty zestaw narzędzi przyciągają zarówno początkujących, jak i doświadczonych programistów. W tym przewodniku omówimy kluczowe elementy Laravela - od architektury MVC, przez Eloquent ORM, aż po zaawansowane mechanizmy kolejkowania i testowania.

Dlaczego Laravel jest tak popularny?#

Laravel wyróżnia się na tle innych frameworków PHP kilkoma kluczowymi cechami:

  • Elegancka, ekspresywna składnia - kod jest czytelny i przyjemny w utrzymaniu
  • Ogromny ekosystem - od paneli administracyjnych po deployment w chmurze
  • Aktywna społeczność - tysiące pakietów, Laracasts, konferencje Laracon
  • Doskonała dokumentacja - jedna z najlepszych w świecie open-source
  • Szybkie prototypowanie - od pomysłu do MVP w rekordowym czasie
  • Wbudowane bezpieczeństwo - ochrona przed CSRF, XSS, SQL injection out-of-the-box

Według ankiety Stack Overflow, Laravel konsekwentnie plasuje się wśród najczęściej używanych frameworków backendowych na świecie, a na GitHubie posiada ponad 75 tysięcy gwiazdek.

Architektura MVC w Laravel#

Laravel implementuje wzorzec Model-View-Controller (MVC), który oddziela logikę biznesową od warstwy prezentacji i obsługi żądań HTTP.

Model#

Modele reprezentują dane i logikę biznesową. W Laravel każdy model odpowiada tabeli w bazie danych:

// app/Models/Article.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;

class Article extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'title',
        'slug',
        'content',
        'excerpt',
        'published_at',
        'user_id',
        'category_id',
    ];

    protected $casts = [
        'published_at' => 'datetime',
    ];

    public function author()
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    public function tags()
    {
        return $this->belongsToMany(Tag::class);
    }

    public function scopePublished($query)
    {
        return $query->whereNotNull('published_at')
                     ->where('published_at', '<=', now());
    }
}

View (Blade)#

Widoki odpowiadają za prezentację danych użytkownikowi. Laravel wykorzystuje silnik szablonów Blade, o którym więcej powiemy w dalszej części artykułu.

Controller#

Kontrolery przetwarzają żądania HTTP i koordynują interakcję między modelem a widokiem:

// app/Http/Controllers/ArticleController.php
namespace App\Http\Controllers;

use App\Models\Article;
use App\Http\Requests\StoreArticleRequest;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index(Request $request)
    {
        $articles = Article::published()
            ->with(['author', 'category', 'tags'])
            ->when($request->search, function ($query, $search) {
                $query->where('title', 'like', "%{$search}%");
            })
            ->latest('published_at')
            ->paginate(15);

        return view('articles.index', compact('articles'));
    }

    public function show(Article $article)
    {
        $article->load(['author', 'category', 'tags']);

        return view('articles.show', compact('article'));
    }

    public function store(StoreArticleRequest $request)
    {
        $article = $request->user()->articles()->create(
            $request->validated()
        );

        return redirect()
            ->route('articles.show', $article)
            ->with('success', 'Artykuł został opublikowany.');
    }
}

Eloquent ORM - potężny system zarządzania bazą danych#

Eloquent to ORM (Object-Relational Mapping) wbudowany w Laravel, który umożliwia elegancką pracę z bazą danych za pomocą modeli PHP. Jest to jeden z najważniejszych elementów frameworka.

Relacje w Eloquent#

Eloquent obsługuje wszystkie standardowe typy relacji bazodanowych:

// Jeden do wielu (One to Many)
class User extends Model
{
    public function articles()
    {
        return $this->hasMany(Article::class);
    }

    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

// Wiele do wielu (Many to Many) z tabelą pośrednią
class Article extends Model
{
    public function tags()
    {
        return $this->belongsToMany(Tag::class)
                    ->withPivot('order')
                    ->withTimestamps();
    }
}

// Relacja polimorficzna
class Comment extends Model
{
    public function commentable()
    {
        return $this->morphTo();
    }
}

class Article extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

Zaawansowane zapytania#

Eloquent Query Builder pozwala na budowanie skomplikowanych zapytań w elegancki sposób:

// Zaawansowane filtrowanie z eager loading
$articles = Article::query()
    ->with(['author:id,name,avatar', 'tags:id,name,slug'])
    ->withCount('comments')
    ->where('category_id', $categoryId)
    ->whereHas('tags', function ($query) use ($tagSlug) {
        $query->where('slug', $tagSlug);
    })
    ->when($sortBy === 'popular', function ($query) {
        $query->orderByDesc('comments_count');
    }, function ($query) {
        $query->latest('published_at');
    })
    ->paginate(20);

// Agregacja i grupowanie
$stats = Article::query()
    ->selectRaw('category_id, COUNT(*) as total, AVG(views) as avg_views')
    ->where('published_at', '>=', now()->subYear())
    ->groupBy('category_id')
    ->having('total', '>', 5)
    ->get();

// Masowe operacje
Article::where('published_at', '<', now()->subYears(2))
    ->update(['archived' => true]);

// Upsert - wstaw lub zaktualizuj
Article::upsert(
    [
        ['slug' => 'laravel-guide', 'title' => 'Laravel Guide', 'views' => 1],
        ['slug' => 'php-tips', 'title' => 'PHP Tips', 'views' => 1],
    ],
    uniqueBy: ['slug'],
    update: ['title']
);

Migracje i seedery#

Laravel zarządza schematem bazy danych za pomocą migracji:

// database/migrations/2025_03_10_create_articles_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->foreignId('category_id')->constrained();
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('excerpt')->nullable();
            $table->longText('content');
            $table->unsignedInteger('views')->default(0);
            $table->timestamp('published_at')->nullable()->index();
            $table->softDeletes();
            $table->timestamps();

            $table->fullText(['title', 'content']);
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('articles');
    }
};

Blade - silnik szablonów#

Blade to lekki, ale niezwykle potężny silnik szablonów Laravela. Kompiluje szablony do czystego kodu PHP, więc nie narzuca dodatkowego narzutu wydajnościowego.

{{-- resources/views/articles/index.blade.php --}}
<x-app-layout>
    <x-slot name="header">
        <h1 class="text-2xl font-bold">{{ __('Artykuły') }}</h1>
    </x-slot>

    <div class="max-w-7xl mx-auto py-8">
        {{-- Formularz wyszukiwania --}}
        <form action="{{ route('articles.index') }}" method="GET" class="mb-6">
            <x-input
                name="search"
                value="{{ request('search') }}"
                placeholder="Szukaj artykułów..."
            />
        </form>

        {{-- Lista artykułów --}}
        @forelse ($articles as $article)
            <article class="mb-6 p-6 bg-white rounded-lg shadow">
                <h2 class="text-xl font-semibold">
                    <a href="{{ route('articles.show', $article) }}">
                        {{ $article->title }}
                    </a>
                </h2>

                <div class="text-sm text-gray-500 mt-2">
                    {{ $article->published_at->translatedFormat('d F Y') }}
                    &middot; {{ $article->author->name }}
                </div>

                <p class="mt-3 text-gray-700">{{ $article->excerpt }}</p>

                <div class="mt-3 flex gap-2">
                    @foreach ($article->tags as $tag)
                        <x-badge>{{ $tag->name }}</x-badge>
                    @endforeach
                </div>
            </article>
        @empty
            <p class="text-gray-500">{{ __('Brak artykułów do wyświetlenia.') }}</p>
        @endforelse

        {{-- Paginacja --}}
        <div class="mt-8">
            {{ $articles->withQueryString()->links() }}
        </div>
    </div>
</x-app-layout>

Komponenty Blade#

Laravel umożliwia tworzenie reużywalnych komponentów:

// app/View/Components/Badge.php
namespace App\View\Components;

use Illuminate\View\Component;

class Badge extends Component
{
    public function __construct(
        public string $color = 'blue'
    ) {}

    public function render()
    {
        return view('components.badge');
    }
}
{{-- resources/views/components/badge.blade.php --}}
<span {{ $attributes->merge([
    'class' => "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs
                font-medium bg-{$color}-100 text-{$color}-800"
]) }}>
    {{ $slot }}
</span>

Artisan CLI - narzędzie wiersza poleceń#

Artisan to interfejs wiersza poleceń dostarczany z Laravelem. Oferuje dziesiątki przydatnych komend przyspieszających codzienną pracę:

# Generowanie kodu
php artisan make:model Article -mfsc    # Model + migracja + fabryka + seeder + kontroler
php artisan make:request StoreArticleRequest
php artisan make:middleware EnsureArticleOwner
php artisan make:job ProcessArticleImages
php artisan make:event ArticlePublished
php artisan make:listener SendArticleNotification

# Migracje
php artisan migrate                     # Uruchom migracje
php artisan migrate:rollback            # Cofnij ostatni batch
php artisan migrate:fresh --seed        # Odtwórz bazę i uruchom seedery

# Cache i optymalizacja
php artisan config:cache                # Cache konfiguracji
php artisan route:cache                 # Cache tras
php artisan view:cache                  # Kompilacja widoków
php artisan optimize                    # Optymalizacja produkcyjna

# Kolejki
php artisan queue:work --tries=3        # Worker kolejki
php artisan queue:failed                # Wyświetl nieudane zadania

# Konsola interaktywna
php artisan tinker                      # REPL do eksperymentowania

Możesz także tworzyć własne komendy Artisan:

// app/Console/Commands/GenerateSitemap.php
namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Article;

class GenerateSitemap extends Command
{
    protected $signature = 'sitemap:generate
                            {--format=xml : Format wyjściowy (xml|json)}';

    protected $description = 'Generuje mapę strony na podstawie opublikowanych artykułów';

    public function handle(): int
    {
        $articles = Article::published()->get();

        $this->info("Generowanie mapy strony dla {$articles->count()} artykułów...");

        $bar = $this->output->createProgressBar($articles->count());

        foreach ($articles as $article) {
            // logika generowania sitemap
            $bar->advance();
        }

        $bar->finish();
        $this->newLine();
        $this->info('Mapa strony wygenerowana pomyślnie!');

        return Command::SUCCESS;
    }
}

Routing i middleware#

System routingu w Laravel jest intuicyjny i elastyczny:

// routes/web.php
use App\Http\Controllers\ArticleController;
use App\Http\Controllers\Api\ArticleApiController;

// Podstawowy routing
Route::get('/', function () {
    return view('welcome');
});

// Resource routing - generuje 7 standardowych tras CRUD
Route::resource('articles', ArticleController::class);

// API routing z wersjonowaniem
Route::prefix('api/v1')->middleware('auth:sanctum')->group(function () {
    Route::apiResource('articles', ArticleApiController::class);

    Route::post('articles/{article}/publish', [ArticleApiController::class, 'publish'])
        ->middleware('can:publish,article');
});

// Grupowanie tras
Route::middleware(['auth', 'verified'])->prefix('admin')->name('admin.')->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
    Route::resource('users', UserController::class)->except(['show']);
});

Tworzenie middleware#

Middleware to filtry przetwarzające żądania HTTP:

// app/Http/Middleware/TrackPageViews.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\Models\PageView;

class TrackPageViews
{
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        if ($request->isMethod('GET') && !$request->ajax()) {
            PageView::create([
                'url' => $request->fullUrl(),
                'user_id' => $request->user()?->id,
                'ip_address' => $request->ip(),
                'user_agent' => $request->userAgent(),
            ]);
        }

        return $response;
    }
}

Uwierzytelnianie i autoryzacja#

Laravel oferuje kilka gotowych pakietów startowych do uwierzytelniania:

Laravel Breeze#

Minimalistyczny pakiet z pełną implementacją logowania, rejestracji, resetowania hasła i weryfikacji e-mail:

composer require laravel/breeze --dev
php artisan breeze:install blade   # lub react, vue, api
php artisan migrate
npm install && npm run dev

Laravel Jetstream#

Zaawansowany pakiet z dodatkowymi funkcjami:

  • Uwierzytelnianie dwuskładnikowe (2FA)
  • Zarządzanie sesjami
  • Zarządzanie zespołami
  • Integracja z API (tokeny Sanctum)

Polityki autoryzacji#

Laravel umożliwia definiowanie polityk autoryzacji:

// app/Policies/ArticlePolicy.php
namespace App\Policies;

use App\Models\Article;
use App\Models\User;

class ArticlePolicy
{
    public function update(User $user, Article $article): bool
    {
        return $user->id === $article->user_id
            || $user->hasRole('editor');
    }

    public function delete(User $user, Article $article): bool
    {
        return $user->id === $article->user_id
            || $user->hasRole('admin');
    }

    public function publish(User $user, Article $article): bool
    {
        return $user->hasAnyRole(['editor', 'admin']);
    }
}

Użycie w kontrolerze:

public function update(StoreArticleRequest $request, Article $article)
{
    $this->authorize('update', $article);

    $article->update($request->validated());

    return redirect()->route('articles.show', $article);
}

Kolejki i zadania (Queues & Jobs)#

System kolejek Laravela pozwala na odroczenie czasochłonnych operacji, znacznie poprawiając czas odpowiedzi aplikacji:

// app/Jobs/ProcessArticleImages.php
namespace App\Jobs;

use App\Models\Article;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;

class ProcessArticleImages implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;
    public int $backoff = 60;
    public int $timeout = 120;

    public function __construct(
        private Article $article
    ) {}

    public function handle(): void
    {
        $content = $this->article->content;

        preg_match_all('/<img[^>]+src="([^"]+)"/', $content, $matches);

        foreach ($matches[1] as $imageUrl) {
            $image = Image::make($imageUrl);

            // Generuj miniaturę
            $thumbnail = $image->fit(400, 300);
            $thumbnailPath = 'thumbnails/' . basename($imageUrl);
            Storage::disk('public')->put($thumbnailPath, $thumbnail->encode());

            // Generuj wersję WebP
            $webp = $image->encode('webp', 85);
            $webpPath = 'images/' . pathinfo(basename($imageUrl), PATHINFO_FILENAME) . '.webp';
            Storage::disk('public')->put($webpPath, $webp);
        }
    }

    public function failed(\Throwable $exception): void
    {
        logger()->error('Przetwarzanie obrazów nie powiodło się', [
            'article_id' => $this->article->id,
            'error' => $exception->getMessage(),
        ]);
    }
}

Dispatch zadania:

// Dispatch do kolejki
ProcessArticleImages::dispatch($article);

// Dispatch z opóźnieniem
ProcessArticleImages::dispatch($article)->delay(now()->addMinutes(5));

// Łańcuch zadań
Bus::chain([
    new ProcessArticleImages($article),
    new GenerateArticleSummary($article),
    new NotifySubscribers($article),
])->dispatch();

Laravel Sail - Docker dla Laravela#

Laravel Sail to lekkie narzędzie do zarządzania środowiskiem Docker dla projektów Laravel:

# Tworzenie nowego projektu z Sail
curl -s "https://laravel.build/my-project?with=mysql,redis,meilisearch" | bash

# Uruchomienie środowiska
cd my-project
./vendor/bin/sail up -d

# Komendy przez Sail
./vendor/bin/sail artisan migrate
./vendor/bin/sail composer require laravel/sanctum
./vendor/bin/sail npm run dev
./vendor/bin/sail test
./vendor/bin/sail tinker

Sail dostarcza gotowe kontenary z PHP, MySQL/PostgreSQL, Redis, Meilisearch, Mailpit i innymi usługami, eliminując konieczność ręcznej konfiguracji środowiska deweloperskiego.

Testowanie z PHPUnit i Pest#

Laravel jest zbudowany z myślą o testowalności. Framework wspiera zarówno PHPUnit, jak i nowoczesny Pest:

Testy z Pest#

// tests/Feature/ArticleTest.php
use App\Models\Article;
use App\Models\User;

beforeEach(function () {
    $this->user = User::factory()->create();
});

it('displays published articles on the index page', function () {
    $articles = Article::factory()
        ->count(3)
        ->published()
        ->create();

    $this->get(route('articles.index'))
        ->assertOk()
        ->assertSee($articles->first()->title);
});

it('allows authenticated users to create articles', function () {
    $articleData = [
        'title' => 'Testowy artykuł',
        'content' => 'Treść testowego artykułu',
        'category_id' => Category::factory()->create()->id,
    ];

    $this->actingAs($this->user)
        ->post(route('articles.store'), $articleData)
        ->assertRedirect();

    $this->assertDatabaseHas('articles', [
        'title' => 'Testowy artykuł',
        'user_id' => $this->user->id,
    ]);
});

it('prevents guests from creating articles', function () {
    $this->post(route('articles.store'), [])
        ->assertRedirect(route('login'));
});

it('validates required fields when creating an article', function () {
    $this->actingAs($this->user)
        ->post(route('articles.store'), [])
        ->assertSessionHasErrors(['title', 'content', 'category_id']);
});

Testy HTTP API#

it('returns paginated articles from API', function () {
    Article::factory()->count(25)->published()->create();

    $response = $this->actingAs($this->user, 'sanctum')
        ->getJson('/api/v1/articles?page=1&per_page=10');

    $response->assertOk()
        ->assertJsonCount(10, 'data')
        ->assertJsonStructure([
            'data' => [['id', 'title', 'slug', 'excerpt', 'published_at']],
            'meta' => ['current_page', 'last_page', 'total'],
        ]);
});

Ekosystem Laravela#

Laravel to nie tylko framework - to cały ekosystem narzędzi:

Laravel Nova#

Panel administracyjny premium, który pozwala na szybkie tworzenie interfejsów CRUD:

// app/Nova/Article.php
class Article extends Resource
{
    public static $model = \App\Models\Article::class;

    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Text::make('Tytuł', 'title')->sortable()->rules('required'),
            Slug::make('Slug')->from('title'),
            Markdown::make('Treść', 'content')->rules('required'),
            BelongsTo::make('Autor', 'author', User::class),
            DateTime::make('Opublikowano', 'published_at'),
        ];
    }
}

Laravel Forge#

Platforma do zarządzania serwerami - automatyzuje provisioning serwerów na DigitalOcean, AWS, Hetzner i innych. Konfiguruje Nginx, PHP, SSL, bazy danych i wiele więcej jednym kliknięciem.

Laravel Vapor#

Serverless deployment dla Laravela na AWS Lambda. Automatyczne skalowanie, zero zarządzania serwerami, integracja z SQS, S3, CloudFront i Aurora.

Inne narzędzia ekosystemu#

  • Laravel Horizon - dashboard do monitorowania kolejek Redis
  • Laravel Telescope - debugger i profiler dla środowiska deweloperskiego
  • Laravel Pint - automatyczny code fixer oparty na PHP-CS-Fixer
  • Laravel Pennant - feature flags
  • Laravel Pulse - monitoring wydajności aplikacji w czasie rzeczywistym
  • Laravel Reverb - serwer WebSocket pierwszej strony

Optymalizacja wydajności#

Kilka sprawdzonych technik optymalizacji aplikacji Laravel:

Eager Loading - eliminacja problemu N+1#

// Zamiast tego (N+1 problem):
$articles = Article::all();
foreach ($articles as $article) {
    echo $article->author->name; // Dodatkowe zapytanie dla każdego artykułu
}

// Użyj eager loading:
$articles = Article::with('author')->get();
foreach ($articles as $article) {
    echo $article->author->name; // Brak dodatkowych zapytań
}

// Zapobieganie N+1 w środowisku deweloperskim:
// AppServiceProvider.php
Model::preventLazyLoading(!app()->isProduction());

Cache'owanie danych#

use Illuminate\Support\Facades\Cache;

// Cache z TTL
$popularArticles = Cache::remember('popular_articles', 3600, function () {
    return Article::published()
        ->withCount('comments')
        ->orderByDesc('comments_count')
        ->take(10)
        ->get();
});

// Cache tags (wymaga Redis lub Memcached)
Cache::tags(['articles', 'homepage'])->put('featured', $articles, 3600);
Cache::tags(['articles'])->flush(); // Wyczyść wszystkie cache artykułów

Komendy optymalizacyjne na produkcji#

php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
php artisan optimize
composer install --optimize-autoloader --no-dev

Indeksy bazy danych#

// W migracji - dodawanie indeksów
Schema::table('articles', function (Blueprint $table) {
    $table->index('published_at');
    $table->index(['category_id', 'published_at']);
    $table->fullText(['title', 'content']);
});

Podsumowanie#

Laravel to dojrzały, wszechstronny framework, który pozwala budować aplikacje każdej skali - od prostych stron internetowych po rozbudowane systemy enterprise. Jego elegancka składnia, potężny Eloquent ORM, rozbudowany ekosystem i aktywna społeczność sprawiają, że jest doskonałym wyborem zarówno dla startupów, jak i dużych organizacji.

Kluczowe atuty Laravela:

  • Produktywność - gotowe rozwiązania dla typowych problemów webowych
  • Skalowalność - kolejki, cache, serverless z Vapor
  • Bezpieczeństwo - wbudowana ochrona przed najczęstszymi atakami
  • Testowalność - łatwe pisanie testów z PHPUnit i Pest
  • Ekosystem - od Nova po Forge, wszystko czego potrzebuje zespół

Potrzebujesz profesjonalnej aplikacji w Laravel?#

MDS Software Solutions Group specjalizuje się w tworzeniu wydajnych, skalowalnych aplikacji webowych z wykorzystaniem Laravel i nowoczesnych technologii backendowych. Nasz zespół doświadczonych programistów pomoże Ci zaprojektować, zbudować i wdrożyć rozwiązanie dopasowane do Twoich potrzeb biznesowych.

Oferujemy:

  • Tworzenie aplikacji webowych od podstaw
  • Modernizację i optymalizację istniejących systemów
  • Integracje z zewnętrznymi API i usługami
  • Wdrożenia w chmurze i DevOps

Skontaktuj się z nami i porozmawiajmy o Twoim projekcie.

Autor
MDS Software Solutions Group

Zespół ekspertów programistycznych specjalizujących się w nowoczesnych technologiach webowych.

Laravel - kompletny przewodnik po najpopularniejszym frameworku PHP | MDS Software Solutions Group | MDS Software Solutions Group