Laravel - Ein umfassender Leitfaden zum beliebtesten PHP-Framework
Laravel Ein umfassender
backendLaravel - Ein umfassender Leitfaden zum beliebtesten PHP-Framework
Laravel ist das PHP-Framework, das die Entwicklung von Webanwendungen revolutioniert hat. Seit seiner Veröffentlichung im Jahr 2011 durch Taylor Otwell hat es sich zum beliebtesten Framework im PHP-Ökosystem entwickelt. Seine elegante Syntax und sein umfangreicher Werkzeugkasten ziehen sowohl Einsteiger als auch erfahrene Entwickler an. In diesem Leitfaden gehen wir die wesentlichen Elemente von Laravel durch - von der MVC-Architektur über Eloquent ORM bis hin zu fortgeschrittenen Mechanismen für Warteschlangen und Tests.
Warum ist Laravel so beliebt?#
Laravel hebt sich durch mehrere entscheidende Merkmale von anderen PHP-Frameworks ab:
- Elegante, ausdrucksstarke Syntax - lesbarer und wartungsfreundlicher Code
- Umfangreiches Ökosystem - von Admin-Panels bis zum Cloud-Deployment
- Aktive Community - tausende Pakete, Laracasts, Laracon-Konferenzen
- Hervorragende Dokumentation - eine der besten in der Open-Source-Welt
- Schnelles Prototyping - von der Idee zum MVP in Rekordzeit
- Integrierte Sicherheit - CSRF-, XSS- und SQL-Injection-Schutz von Haus aus
Laut der Stack Overflow-Umfrage zählt Laravel konstant zu den meistgenutzten Backend-Frameworks weltweit und hat über 75.000 Sterne auf GitHub.
MVC-Architektur in Laravel#
Laravel implementiert das Model-View-Controller (MVC)-Muster, das die Geschäftslogik von der Präsentationsschicht und der HTTP-Anfrageverarbeitung trennt.
Model#
Models repräsentieren Daten und Geschäftslogik. In Laravel entspricht jedes Model einer Datenbanktabelle:
// 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)#
Views sind für die Darstellung der Daten an den Benutzer verantwortlich. Laravel verwendet die Blade-Template-Engine, die wir später in diesem Artikel ausführlicher behandeln werden.
Controller#
Controller verarbeiten HTTP-Anfragen und koordinieren die Interaktion zwischen Model und View:
// 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', 'Artikel erfolgreich veröffentlicht.');
}
}
Eloquent ORM - Ein leistungsstarkes Datenbankmanagementsystem#
Eloquent ist das in Laravel integrierte ORM (Object-Relational Mapping), das eine elegante Datenbankinteraktion über PHP-Models ermöglicht. Es ist eine der wichtigsten Komponenten des Frameworks.
Beziehungen in Eloquent#
Eloquent unterstützt alle gängigen Datenbankbeziehungstypen:
// Eins zu Viele (One to Many)
class User extends Model
{
public function articles()
{
return $this->hasMany(Article::class);
}
public function profile()
{
return $this->hasOne(Profile::class);
}
}
// Viele zu Viele (Many to Many) mit Pivot-Tabelle
class Article extends Model
{
public function tags()
{
return $this->belongsToMany(Tag::class)
->withPivot('order')
->withTimestamps();
}
}
// Polymorphe Beziehung
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
class Article extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
Fortgeschrittene Abfragen#
Der Eloquent Query Builder ermöglicht es, komplexe Abfragen auf elegante Weise zu erstellen:
// Fortgeschrittenes Filtern mit 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);
// Aggregation und Gruppierung
$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();
// Massenoperationen
Article::where('published_at', '<', now()->subYears(2))
->update(['archived' => true]);
// Upsert - Einfügen oder Aktualisieren
Article::upsert(
[
['slug' => 'laravel-guide', 'title' => 'Laravel Guide', 'views' => 1],
['slug' => 'php-tips', 'title' => 'PHP Tips', 'views' => 1],
],
uniqueBy: ['slug'],
update: ['title']
);
Migrationen und Seeder#
Laravel verwaltet Datenbankschemata über Migrationen:
// 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 - Die Template-Engine#
Blade ist eine leichtgewichtige, aber leistungsstarke Template-Engine, die mit Laravel geliefert wird. Sie kompiliert Templates in reinen PHP-Code und verursacht daher keinen zusätzlichen Performance-Overhead.
{{-- resources/views/articles/index.blade.php --}}
<x-app-layout>
<x-slot name="header">
<h1 class="text-2xl font-bold">{{ __('Artikel') }}</h1>
</x-slot>
<div class="max-w-7xl mx-auto py-8">
{{-- Suchformular --}}
<form action="{{ route('articles.index') }}" method="GET" class="mb-6">
<x-input
name="search"
value="{{ request('search') }}"
placeholder="Artikel suchen..."
/>
</form>
{{-- Artikelliste --}}
@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') }}
· {{ $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">{{ __('Keine Artikel vorhanden.') }}</p>
@endforelse
{{-- Paginierung --}}
<div class="mt-8">
{{ $articles->withQueryString()->links() }}
</div>
</div>
</x-app-layout>
Blade-Komponenten#
Laravel ermöglicht die Erstellung wiederverwendbarer Komponenten:
// 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 - Das Kommandozeilenwerkzeug#
Artisan ist die Kommandozeilenschnittstelle, die mit Laravel ausgeliefert wird. Sie bietet dutzende nützlicher Befehle, die die tägliche Entwicklungsarbeit beschleunigen:
# Codegenerierung
php artisan make:model Article -mfsc # Model + Migration + Factory + Seeder + Controller
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
# Migrationen
php artisan migrate # Migrationen ausführen
php artisan migrate:rollback # Letzten Batch zurückrollen
php artisan migrate:fresh --seed # Datenbank neu aufbauen und Seeder ausführen
# Cache und Optimierung
php artisan config:cache # Konfiguration cachen
php artisan route:cache # Routen cachen
php artisan view:cache # Views kompilieren
php artisan optimize # Produktionsoptimierung
# Warteschlangen
php artisan queue:work --tries=3 # Queue-Worker
php artisan queue:failed # Fehlgeschlagene Jobs anzeigen
# Interaktive Konsole
php artisan tinker # REPL zum Experimentieren
Sie können auch eigene Artisan-Befehle erstellen:
// 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 : Ausgabeformat (xml|json)}';
protected $description = 'Generiert eine Sitemap basierend auf veröffentlichten Artikeln';
public function handle(): int
{
$articles = Article::published()->get();
$this->info("Sitemap für {$articles->count()} Artikel wird generiert...");
$bar = $this->output->createProgressBar($articles->count());
foreach ($articles as $article) {
// Sitemap-Generierungslogik
$bar->advance();
}
$bar->finish();
$this->newLine();
$this->info('Sitemap erfolgreich generiert!');
return Command::SUCCESS;
}
}
Routing und Middleware#
Das Routing-System von Laravel ist intuitiv und flexibel:
// routes/web.php
use App\Http\Controllers\ArticleController;
use App\Http\Controllers\Api\ArticleApiController;
// Grundlegendes Routing
Route::get('/', function () {
return view('welcome');
});
// Resource-Routing - generiert 7 Standard-CRUD-Routen
Route::resource('articles', ArticleController::class);
// API-Routing mit Versionierung
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');
});
// Routengruppierung
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']);
});
Middleware erstellen#
Middleware sind Filter, die HTTP-Anfragen verarbeiten:
// 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;
}
}
Authentifizierung und Autorisierung#
Laravel bietet mehrere Starter-Kits für die Authentifizierung:
Laravel Breeze#
Ein minimalistisches Paket mit vollständiger Implementierung von Login, Registrierung, Passwort-Reset und E-Mail-Verifizierung:
composer require laravel/breeze --dev
php artisan breeze:install blade # oder react, vue, api
php artisan migrate
npm install && npm run dev
Laravel Jetstream#
Ein erweitertes Paket mit zusätzlichen Funktionen:
- Zwei-Faktor-Authentifizierung (2FA)
- Sitzungsverwaltung
- Teamverwaltung
- API-Integration (Sanctum-Tokens)
Autorisierungsrichtlinien#
Laravel ermöglicht die Definition von Autorisierungsrichtlinien:
// 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']);
}
}
Verwendung im Controller:
public function update(StoreArticleRequest $request, Article $article)
{
$this->authorize('update', $article);
$article->update($request->validated());
return redirect()->route('articles.show', $article);
}
Warteschlangen und Jobs (Queues & Jobs)#
Das Warteschlangensystem von Laravel ermöglicht es, zeitintensive Operationen auszulagern und so die Antwortzeit der Anwendung erheblich zu verbessern:
// 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);
// Miniaturansicht generieren
$thumbnail = $image->fit(400, 300);
$thumbnailPath = 'thumbnails/' . basename($imageUrl);
Storage::disk('public')->put($thumbnailPath, $thumbnail->encode());
// WebP-Version generieren
$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('Bildverarbeitung fehlgeschlagen', [
'article_id' => $this->article->id,
'error' => $exception->getMessage(),
]);
}
}
Jobs dispatchen:
// In die Warteschlange dispatchen
ProcessArticleImages::dispatch($article);
// Mit Verzögerung dispatchen
ProcessArticleImages::dispatch($article)->delay(now()->addMinutes(5));
// Job-Verkettung
Bus::chain([
new ProcessArticleImages($article),
new GenerateArticleSummary($article),
new NotifySubscribers($article),
])->dispatch();
Laravel Sail - Docker für Laravel#
Laravel Sail ist ein leichtgewichtiges Werkzeug zur Verwaltung von Docker-Umgebungen in Laravel-Projekten:
# Neues Projekt mit Sail erstellen
curl -s "https://laravel.build/my-project?with=mysql,redis,meilisearch" | bash
# Umgebung starten
cd my-project
./vendor/bin/sail up -d
# Befehle über 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 liefert fertige Container mit PHP, MySQL/PostgreSQL, Redis, Meilisearch, Mailpit und anderen Diensten, wodurch die manuelle Konfiguration der Entwicklungsumgebung entfällt.
Testen mit PHPUnit und Pest#
Laravel wurde mit Testbarkeit im Sinn gebaut. Das Framework unterstützt sowohl PHPUnit als auch das moderne Test-Framework Pest:
Tests mit 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' => 'Testartikel',
'content' => 'Inhalt des Testartikels',
'category_id' => Category::factory()->create()->id,
];
$this->actingAs($this->user)
->post(route('articles.store'), $articleData)
->assertRedirect();
$this->assertDatabaseHas('articles', [
'title' => 'Testartikel',
'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']);
});
HTTP-API-Tests#
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'],
]);
});
Das Laravel-Ökosystem#
Laravel ist nicht nur ein Framework - es ist ein ganzes Ökosystem von Werkzeugen:
Laravel Nova#
Ein Premium-Admin-Panel, das die schnelle Erstellung von CRUD-Oberflächen ermöglicht:
// 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('Titel', 'title')->sortable()->rules('required'),
Slug::make('Slug')->from('title'),
Markdown::make('Inhalt', 'content')->rules('required'),
BelongsTo::make('Autor', 'author', User::class),
DateTime::make('Veröffentlicht am', 'published_at'),
];
}
}
Laravel Forge#
Eine Serververwaltungsplattform, die das Server-Provisioning auf DigitalOcean, AWS, Hetzner und anderen automatisiert. Sie konfiguriert Nginx, PHP, SSL, Datenbanken und vieles mehr mit einem einzigen Klick.
Laravel Vapor#
Serverless-Deployment für Laravel auf AWS Lambda. Automatische Skalierung, keine Serververwaltung, Integration mit SQS, S3, CloudFront und Aurora.
Weitere Werkzeuge des Ökosystems#
- Laravel Horizon - Dashboard zur Überwachung von Redis-Warteschlangen
- Laravel Telescope - Debugger und Profiler für Entwicklungsumgebungen
- Laravel Pint - automatischer Code-Fixer basierend auf PHP-CS-Fixer
- Laravel Pennant - Feature-Flags
- Laravel Pulse - Echtzeit-Performance-Monitoring für Anwendungen
- Laravel Reverb - First-Party-WebSocket-Server
Performance-Optimierung#
Hier sind bewährte Techniken zur Optimierung von Laravel-Anwendungen:
Eager Loading - Das N+1-Problem beseitigen#
// Anstelle von (N+1-Problem):
$articles = Article::all();
foreach ($articles as $article) {
echo $article->author->name; // Zusätzliche Abfrage für jeden Artikel
}
// Eager Loading verwenden:
$articles = Article::with('author')->get();
foreach ($articles as $article) {
echo $article->author->name; // Keine zusätzlichen Abfragen
}
// N+1 in der Entwicklung verhindern:
// AppServiceProvider.php
Model::preventLazyLoading(!app()->isProduction());
Daten-Caching#
use Illuminate\Support\Facades\Cache;
// Cache mit TTL
$popularArticles = Cache::remember('popular_articles', 3600, function () {
return Article::published()
->withCount('comments')
->orderByDesc('comments_count')
->take(10)
->get();
});
// Cache-Tags (erfordert Redis oder Memcached)
Cache::tags(['articles', 'homepage'])->put('featured', $articles, 3600);
Cache::tags(['articles'])->flush(); // Alle Artikel-Caches löschen
Optimierungsbefehle für die Produktion#
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
Datenbankindizes#
// In einer Migration - Indizes hinzufügen
Schema::table('articles', function (Blueprint $table) {
$table->index('published_at');
$table->index(['category_id', 'published_at']);
$table->fullText(['title', 'content']);
});
Fazit#
Laravel ist ein ausgereiftes, vielseitiges Framework, mit dem Sie Anwendungen jeder Größenordnung erstellen können - von einfachen Websites bis hin zu komplexen Enterprise-Systemen. Seine elegante Syntax, das leistungsstarke Eloquent ORM, das umfangreiche Ökosystem und die aktive Community machen es zu einer ausgezeichneten Wahl sowohl für Startups als auch für große Organisationen.
Die wichtigsten Stärken von Laravel:
- Produktivität - fertige Lösungen für gängige Web-Probleme
- Skalierbarkeit - Warteschlangen, Caching, Serverless mit Vapor
- Sicherheit - integrierter Schutz vor den häufigsten Angriffen
- Testbarkeit - einfaches Schreiben von Tests mit PHPUnit und Pest
- Ökosystem - von Nova bis Forge, alles was ein Team braucht
Benötigen Sie eine professionelle Laravel-Anwendung?#
MDS Software Solutions Group ist spezialisiert auf die Entwicklung leistungsstarker, skalierbarer Webanwendungen mit Laravel und modernen Backend-Technologien. Unser Team erfahrener Entwickler hilft Ihnen beim Design, bei der Entwicklung und beim Deployment einer Lösung, die auf Ihre geschäftlichen Anforderungen zugeschnitten ist.
Wir bieten:
- Individuelle Webanwendungsentwicklung von Grund auf
- Modernisierung und Optimierung bestehender Systeme
- Integration mit Drittanbieter-APIs und Diensten
- Cloud-Deployment und DevOps
Kontaktieren Sie uns und lassen Sie uns über Ihr Projekt sprechen.
Team von Programmierexperten, die sich auf moderne Webtechnologien spezialisiert haben.
