Wer mit Laravel arbeitet – egal ob Anfänger oder erfahrener Entwickler – kommt an der Verzeichnisstruktur nicht vorbei. Sie ist das Rückgrat jeder Applikation. Eine klare Struktur hilft, den Code zu organisieren, die Wartung zu vereinfachen und effizient im Team zu arbeiten. In diesem Artikel werfen wir einen genauen Blick auf die Verzeichnisse von Laravel und erklären, was sich hinter den einzelnen Ordnern verbirgt – verständlich, praxisnah und auf den Punkt gebracht.

Grundlegendes zur Laravel-Projektstruktur

Grundlegendes zur Laravel Verzeichnisstruktur

Nach dem Aufruf von laravel new oder composer create-project steht man sofort vor einer Reihe von Verzeichnissen und Dateien. Wer Laravel zum ersten Mal öffnet, sieht auf den ersten Blick: Hier steckt viel dahinter. Doch genau diese Struktur ist einer der großen Vorteile des Frameworks – sie bringt Ordnung in den Entwicklungsalltag und legt den Grundstein für sauberen, wartbaren Code.

Zweck der Struktur

Laravel folgt dem Prinzip der Trennung der Verantwortlichkeiten (Separation of Concerns). Das bedeutet, dass jede Datei und jeder Ordner eine ganz bestimmte Aufgabe hat. Die Geschäftslogik ist getrennt von der Darstellung, der Konfiguration des Routings und so weiter. Dieses Konzept macht die Anwendung nicht nur leichter verständlich, sondern auch robuster gegenüber Änderungen – ein echtes Plus, wenn Teams gemeinsam entwickeln oder ein Projekt über viele Monate wächst.

Die erste Orientierung

Unmittelbar nach der Erstellung eines neuen Laravel-Projekts befinden sich im Root-Verzeichnis einige wichtige Ordner und Dateien:

ElementFunktion
app/Enthält die Hauptanwendungslogik (Controller, Models usw.)
bootstrap/Startprozess der Anwendung und Cache-Einstellungen
config/Alle zentralen Konfigurationsdateien
database/Migrationen, Seeders und Testdaten
public/Öffentlich zugänglicher Ordner mit Einstiegspunkt der App
resources/Views, CSS, JS, Lokalisierung – alles, was zur Oberfläche gehört
routes/Definition der URL-Routen
storage/Logs, temporäre Daten, Caches
tests/Unit- und Feature-Tests
vendor/Drittanbieter-Pakete, die über Composer geladen wurden

Warum diese Trennung sinnvoll ist

Stell dir vor, du arbeitest mit fünf anderen Entwicklern an einem Projekt. Ohne eine klare Struktur wären Konflikte vorprogrammiert: Wo kommt welche Datei hin? Wie finde ich mich im Code eines Kollegen zurecht? Laravel löst dieses Problem, bevor es entsteht – indem es Regeln festlegt, wie ein Projekt zu organisieren ist. Diese Konventionen sparen Zeit, reduzieren Missverständnisse und verbessern die Wartbarkeit.

Darüber hinaus unterstützt Laravel out-of-the-box wichtige Software-Architekturprinzipien wie MVC (Model-View-Controller), Dependency Injection, Service Provider Pattern und viele mehr – und all das spiegelt sich direkt in der Verzeichnisstruktur wider.

Flexibel, aber mit Rahmen

Trotz der klaren Vorgaben ist Laravel nicht starr. Du kannst deine eigenen Verzeichnisse anlegen – zum Beispiel Services/, Actions/ oder DTOs/, wenn du deine Geschäftslogik noch weiter aufteilen möchtest. Solange du dich beim Autoloading an die PSR-4 Konventionen hältst (definiert in composer.json), erkennt Laravel deine Erweiterungen problemlos.

Fazit zum Einstieg

Die Verzeichnisstruktur von Laravel ist nicht zufällig so aufgebaut – sie folgt klaren Prinzipien, die eine professionelle Softwareentwicklung unterstützen. Wer sich hier schnell zurechtfindet, legt den Grundstein für stabile und skalierbare Anwendungen. Und das Beste: Je länger man mit Laravel arbeitet, desto mehr wird man die Klarheit und den logischen Aufbau zu schätzen wissen.

Das app/-Verzeichnis – Das Herzstück der Anwendung

Das app/-Verzeichnis – Das Herzstück der Anwendung

Dieses Verzeichnis ist sozusagen das Gehirn deiner Anwendung. Alles, was zur internen Verarbeitung eines Requests gehört – vom HTTP-Request über die Controller bis hin zur Datenbankabfrage mit einem Model – wird hier organisiert und verarbeitet. Laravel folgt dem Model-View-Controller-Prinzip (MVC) und genau dieser Controller-Teil sowie die Models werden hier zentral abgelegt.

Klare Trennung innerhalb von app/

Laravel bringt bereits eine sinnvolle Grundstruktur mit. Schauen wir uns die wichtigsten Unterverzeichnisse im Detail an:

Console/ – Eigene Artisan-Commands

Wenn du eigene Kommandozeilenbefehle erstellen möchtest, werden diese in diesem Ordner abgelegt. Laravel verwendet hier die Symfony Console Komponente, was bedeutet, dass du sehr mächtige CLI-Tools bauen kannst – zum Beispiel zum Importieren von Daten, für automatische Reports oder für regelmäßige Aufräumjobs.

Beispiel:

php artisan make:command CleanUpOldUsers

Exceptions/ – Fehlerbehandlung an zentraler Stelle

In diesem Ordner kontrollierst du, wie Laravel mit Ausnahmen (Exceptions) umgeht. Die wichtigste Datei ist Handler.php, in der du Exceptions abfangen, protokollieren oder benutzerfreundlich darstellen kannst. Dies ist besonders nützlich, wenn du die Antworten der API anpassen möchtest.

Http/ – Routing, Controller, Middleware

Dieses Verzeichnis ist oft das aktivste im Alltag. Es enthält:

  • Controllers/: Hier definierst du die Logik, wie auf bestimmte Routen reagiert werden soll.
  • Middleware/: Kontrolliert den Zugriff auf bestimmte Bereiche, z. B. ob ein User eingeloggt ist.
  • Requests/: Form Request Klassen zur Validierung und Autorisierung von Eingaben – sauber getrennt von der Controller-Logik.

Diese Aufteilung sorgt dafür, dass Controller nicht überladen werden und deine App modular bleibt.

Models/ – Die Verbindung zur Datenbank

Hier befinden sich deine Eloquent Modelle. Jedes Modell repräsentiert eine Tabelle in der Datenbank. Laravel macht es einfach, mit den Modellen nicht nur Daten zu lesen und zu schreiben, sondern auch Beziehungen zwischen den Tabellen zu definieren – wie hasMany, belongsTo, hasOneThrough, etc.

Beispiel:

class Post extends Model {
    public function comments() {
        return $this->hasMany(Comment::class);
    }
}




In älteren Laravel-Versionen lagen die Modelle direkt im app/-Verzeichnis, seit Laravel 8 wird die Struktur mit dem Models/-Ordner empfohlen.

Providers/ – Service-Provider für Bootstrapping

Service Provider sind Klassen, die Laravel beim Start lädt. Sie registrieren Services im Container, binden Interfaces an Implementierungen oder konfigurieren Pakete. Die zentrale Datei ist dabei AppServiceProvider.php. Weitere Provider wie RouteServiceProvider.php kümmern sich um das Routing.

Wenn du eigene Logik für den Start der App benötigst – z.B. einen globalen Observer oder ein benutzerdefiniertes Binding – ist dies der richtige Ort.

Was gehört noch ins app/-Verzeichnis?

Je nach Projektgröße kann es sinnvoll sein, das app/-Verzeichnis durch eigene Unterverzeichnisse zu ergänzen, z.B:

  • Services/: Für komplexe Business-Logik
  • Actions/: Für einzelne, wiederverwendbare Abläufe (z. B. „Erzeuge PDF“ oder „Sende Benachrichtigung“)
  • DTOs/: Für strukturierte Datenübergabe zwischen Schichten
  • Repositories/: Für das Abstrahieren von Datenzugriffen

Diese Erweiterungen halten deine Controller schlank und machen die Anwendung langfristig wartbar.

Automatisches Laden dank PSR-4

Ein großer Vorteil: Laravel nutzt das PSR-4 Autoloading über den Composer. Sobald man eine neue Klasse im app/-Verzeichnis anlegt und den richtigen Namespace setzt, erkennt Laravel diese automatisch – kein manuelles Einbinden nötig.

Beispiel für den Namespace:

namespace App\Services;

Fazit zu app/

Das Verzeichnis app/ ist das Herzstück deiner App. Hier läuft die Hauptlogik zusammen, hier entscheidest du, wie deine App funktioniert – ob sie Daten verarbeitet, Anfragen filtert oder externe Dienste anspricht. Wenn du dieses Verzeichnis gut strukturierst, sparst du nicht nur Zeit, sondern vermeidest auch technische Schulden.

Das bootstrap/-Verzeichnis – Der Startpunkt

Bevor deine Anwendung richtig loslegen kann, muss das Verzeichnis bootstrap/ initialisiert werden. Es ist der erste interne Schritt nach dem Aufruf von public/index.php, d.h. sobald der Webserver Laravel aufruft. Wenn app/ das Gehirn der Anwendung ist, dann ist bootstrap/ das Nervensystem, das alles in Gang setzt.

Was passiert hier genau?

In diesem Ordner befindet sich die Datei app.php. Sie ist nicht besonders groß, aber entscheidend: Laravel legt hier das sogenannte Application-Objekt an, den zentralen Kern des Frameworks. Dieses Objekt fungiert als Service-Container, Event-Dispatcher, Konfigurationsmanager und mehr – alles in einem.

Das Application-Objekt registriert Kernkomponenten, lädt Konfigurationswerte, bindet Service Provider und übergibt dann an den Kernel, der schließlich die Anfrage bearbeitet.

Ein typischer Ablauf:

  1. public/index.php wird aufgerufen.
  2. bootstrap/app.php erstellt das Application-Objekt.
  3. Der Kernel übernimmt und verarbeitet die Anfrage über Middleware, Controller usw.
  4. Eine Response wird erzeugt und zurückgegeben.

Die bootstrap/app.php im Detail

Hier ein vereinfachter Auszug:

$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);

// Rückgabe der App an index.php
return $app;




Was passiert hier?

  • Die Laravel-Applikation wird instanziiert.
  • Der HTTP-Kernel wird registriert – hier beginnt die Kette der Middleware und Request-Verarbeitung.
  • Die App wird an die index.php übergeben, die nun damit arbeitet.

Du wirst hier selten etwas ändern müssen, aber zu wissen, dass und wie Laravel hier anfängt, hilft, die tieferen Prozesse zu verstehen.

Das bootstrap/cache/-Verzeichnis

Ein weiterer wichtiger Bestandteil ist das Verzeichnis bootstrap/cache/. Es dient der Performance-Optimierung. Hier legt Laravel gecachte Versionen von Konfigurationsdateien, Routen und Diensten ab. Typische Dateien in diesem Verzeichnis sind:

  • config.php – der Konfigurationscache (php artisan config:cache)
  • routes-v7.php – der Routing-Cache (php artisan route:cache)
  • packages.php – Cache für installierte Composer-Pakete
  • services.php – Laravel Package Discovery Mechanismus

Durch das Caching entfällt das Einlesen zahlreicher Dateien bei jeder Anfrage, was die Antwortzeiten insbesondere in produktiven Umgebungen deutlich verbessert.

Wichtig: Diese Dateien werden automatisch generiert. Du solltest sie niemals manuell editieren. Verwende stattdessen die entsprechenden Artisan-Befehle.

Wann du hier aktiv wirst

Auch wenn du normalerweise nicht direkt mit dem bootstrap/ Verzeichnis arbeitest, gibt es einige Situationen, in denen es relevant wird:

  • Deployment: Vor dem Livegang oder nach Konfigurationsänderungen solltest du Caches neu generieren (config:cache, route:cache).
  • Performanceanalyse: Wenn du Ladezeiten untersuchst, ist bootstrap/cache/ oft ein guter Startpunkt.
  • Debugging: Bei Problemen mit Service Providern oder Routen kannst du den Cache leeren, um Fehler durch veraltete Dateien auszuschließen.

Fazit zu bootstrap/

Das Verzeichnis bootstrap/ ist klein, aber wichtig. Es stellt sicher, dass Laravel korrekt startet, effizient läuft und bereit ist, Anfragen zu bearbeiten. Auch wenn du selten direkt eingreifen musst, solltest du seine Rolle verstehen, besonders wenn du Probleme mit dem Bootstrapping, dem Caching oder der Initialisierung deiner Anwendung hast.

Das config/-Verzeichnis – Zentrale Konfiguration

Das config/-Verzeichnis – Zentrale Konfiguration

Dieses Verzeichnis ist die Schaltzentrale deiner Laravel-Anwendung. Von der Datenbankanbindung über Caching, Mail-Einstellungen, Queues bis hin zu Sicherheit und Logging wird hier alles konfiguriert, was konfiguriert werden muss. Anstatt Einstellungen über den Code zu verteilen, folgt Laravel dem Prinzip „Convention over Configuration“, lässt dir aber gleichzeitig die volle Kontrolle über jeden Aspekt.

Wie die Konfiguration funktioniert

Laravel liest beim Start die Dateien im Verzeichnis config/ ein und stellt die Werte über die globale Funktion config() zur Verfügung. So kann jederzeit auf eine Konfiguration zugegriffen werden:

$timezone = config('app.timezone');

Dahinter steht ein assoziatives Array in config/app.php, etwa:

'timezone' => 'UTC',

So bleibt alles zentral und leicht wartbar – ohne „magische Werte“ irgendwo im Code.

Zusammenspiel mit .env-Datei

Die Konfigurationsdateien selbst speichern keine festen Werte wie Passwörter oder Zugangsdaten. Stattdessen verwenden sie env()-Aufrufe, um Werte aus der .env-Datei zu laden:

'debug' => env('APP_DEBUG', false),

Das bedeutet, dass man dieselbe Konfigurationsdatei in allen Umgebungen (lokal, staging, live) verwenden kann – man muss nur die .env Datei anpassen. Laravel trennt also strikt zwischen Code und Umgebung.

Wichtige Konfigurationsdateien im Überblick

Hier einige besonders häufig genutzte Dateien:

  • app.php
    Grundlegende Einstellungen wie App-Name, Locale, Zeitzone, Service-Provider und Aliases.
  • database.php
    Konfiguration von Datenbankverbindungen – MySQL, SQLite, PostgreSQL, SQL Server uvm.
  • mail.php
    Mail-Driver, Absender, SMTP-Zugang – alles, was du zum Mailversand brauchst.
  • queue.php
    Welche Queue-Driver verwendet werden (z. B. sync, database, redis) und wie Jobs verarbeitet werden.
  • logging.php
    Wie Laravel Logs schreibt – lokal in Dateien, über Stack-Handler oder in externe Dienste wie Papertrail.
  • auth.php
    Authentifizierungslogik: Welche Guards und Provider aktiv sind, welches Modell den User repräsentiert.
  • cache.php, session.php, broadcasting.php
    Alle Einstellungen rund um Sessions, Caching-Mechanismen oder WebSocket-Broadcasts.

Diese Dateien sind gut kommentiert, verständlich aufgebaut und lassen sich leicht erweitern.

Eigene Konfigurationsdateien anlegen

Du kannst auch eigene Dateien im Verzeichnis config/ anlegen – ein typischer Anwendungsfall, wenn du komplexere Anwendungen mit vielen Services entwickelst.

Beispiel: Du erstellst die Datei config/payment.php:

return [ 
    'provider' => env('PAYMENT_PROVIDER', 'stripe'),
    'currency' => 'EUR',
];

Und nutzt das später im Code so:

$provider = config('payment.provider');

Das hält deinen Code sauber und deine Settings zentral – genau so, wie es sein sollte.

Caching der Konfiguration für bessere Performance

Für den produktiven Einsatz ist es wichtig, die Konfiguration zu cachen. Das geht mit einem einfachen Artisan-Befehl: php artisan config:cache Dabei erzeugt Laravel eine optimierte Datei bootstrap/cache/config.php. Diese Datei wird bei der nächsten Anfrage direkt gelesen – das spart viele Dateizugriffe.

Achtung: Wenn die .env oder die Konfigurationsdateien geändert werden, muss der Cache neu generiert werden.

Zum Zurücksetzen:

php artisan config:clear

Typische Stolperfallen vermeiden

  • Direktes Verwenden von env() im Code vermeiden
    env() solltest du nur in Konfigurationsdateien nutzen, nicht mitten im Code. In gecachten Konfigurationen stehen env()-Aufrufe nicht mehr zur Verfügung, was zu Fehlern führen kann.
  • Konfiguration nicht hartkodieren
    Harte Werte wie API-Keys oder Datenbanknamen gehören nie in PHP-Dateien direkt – sondern in die .env.
  • Cache regelmäßig aktualisieren
    Nach jeder Änderung im config/-Verzeichnis oder in der .env-Datei: Cache löschen und neu generieren.

Fazit zu config/

Das Verzeichnis config/ ist weit mehr als eine technische Notwendigkeit – es ist das Rückgrat einer sauberen, flexiblen und sicheren Laravel-Anwendung. Es trennt Code und Umgebung, erlaubt jederzeit risikolose Anpassungen und ist dank Caching-Mechanismus extrem performant. Wer Laravel professionell einsetzt, kommt um ein tiefes Verständnis dieses Ordners nicht herum.

Das database/-Verzeichnis – Datenbankbezogene Abläufe

Das database/-Verzeichnis – Datenbankbezogene Abläufe

Laravel stellt mit diesem Verzeichnis eine strukturierte Heimat für alle datenbankrelevanten Prozesse zur Verfügung. Das ist besonders wertvoll, um sauber versioniert zu arbeiten, Testdaten zu generieren oder die Datenbankstruktur im Team konsistent zu halten. Gerade in professionellen Projekten ist es wichtig, dass Schemaänderungen nachvollziehbar und automatisierbar sind – und genau das macht database/ möglich.

Aufbau des Verzeichnisses

Das database/-Verzeichnis enthält standardmäßig drei Unterordner:

migrations/ – Datenbankstruktur versionieren

Migrationen sind ein zentraler Bestandteil von Laravel. Sie dokumentieren und automatisieren jede Änderung an der Datenbankstruktur – vom Anlegen neuer Tabellen über das Hinzufügen von Spalten bis zum Löschen von Indizes.

Beispiel für eine Migration:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('body');
    $table->timestamps();
});

Mit dem Befehl php artisan migrate wird diese Definition in SQL übersetzt und ausgeführt. So wird die Datenbank direkt über den Code geändert – reproduzierbar und teamfähig.

Wichtig: Laravel merkt sich in der Tabelle migrations, welche Migrationen bereits durchgeführt wurden. So können Teams unabhängig und konfliktfrei arbeiten.

Weitere nützliche Befehle:

  • php artisan migrate:rollback – letzte Migration zurücksetzen
  • php artisan migrate:fresh – Datenbank komplett neu aufsetzen
  • php artisan migrate:status – Überblick über den Stand

seeders/ – Daten befüllen für Tests und Entwicklung

Seeder sind PHP-Klassen, mit denen du Daten in die Datenbank einfügen kannst. Vor allem in der Entwicklung brauchst du oft eine gewisse Grundstruktur – zum Beispiel Admin-Benutzer oder Beispielartikel. Anstatt dies manuell zu tun, erstellst du einen Seeder:

public function run()
{
    DB::table('users')->insert([
        'name' => 'Admin',
        'email' => 'admin@example.com',
        'password' => bcrypt('secret'),
    ]);
}




Seeders kannst du dann über den Artisan-Befehl ausführen:

php artisan db:seed

Noch besser: Man kann Seeder miteinander verknüpfen und zentral über DatabaseSeeder.php aufrufen – das sorgt für eine saubere Initialisierung.

factories/ – Realistische Testdaten generieren

Die Factories sind eng mit den Seedern und den Tests verbunden. Sie ermöglichen es, große Mengen an Testdaten schnell und realistisch zu erzeugen. Dabei arbeitet Laravel mit der Faker-Bibliothek, um z.B. zufällige Namen, E-Mails oder Texte zu erzeugen.

Beispiel für eine Factory:

$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => bcrypt('password'),
    ];
});




Mit User::factory()->count(10)->create(); erstellst du auf einen Schlag zehn User – ideal für automatisierte Tests oder lokale Entwicklung.

Seit Laravel 8 gibt es ein neues Factory-System mit Klassenstruktur. Beispiel:

User::factory()->create([
    'email' => 'test@example.com',
]);




Auch komplexe Beziehungen lassen sich elegant abbilden:

User::factory()
    ->hasPosts(3)
    ->create();




Das macht das Erstellen kompletter Datensätze mit Beziehungen unglaublich einfach.

Weitere Aspekte des database/-Verzeichnisses

  • SQL-Dumps:
    Du kannst hier auch .sql-Dateien speichern, z. B. Datenbank-Dumps für spezielle Testfälle.
  • Testdatenbank konfigurieren:
    Die phpunit.xml-Datei kann auf eine eigene Testdatenbank verweisen – Laravel nutzt dann dieselben Migrations und Factories, um vor jedem Test eine frische Umgebung bereitzustellen.

Best Practices für das Arbeiten mit database/

  • Verwende Migrationen konsequent – auch für kleine Änderungen. Manuelles Editieren der Datenbank ist fehleranfällig.
  • Nutze Factories und Seeder nicht nur für Tests, sondern auch zur Einrichtung lokaler Entwicklungsumgebungen.
  • Halte deine DatabaseSeeder.php übersichtlich und modular.
  • Versioniere alle Datenbankänderungen mit Git – das macht Deployments und Rollbacks sicher.

Fazit zu database/

Das database/Verzeichnis ist weit mehr als ein technischer Speicherort – es ist der Schlüssel zu einer konsistenten Datenbankentwicklung. Mit Migrationen, Seedern und Factories sorgt Laravel dafür, dass Struktur und Inhalt der Datenbank reproduzierbar, testbar und teamfähig bleiben. Wer dieses Repository beherrscht, hat den Grundstein für eine robuste und wartbare Datenlogik gelegt.

Das public/-Verzeichnis – Einstiegspunkt für den Webserver

Das public/-Verzeichnis – Einstiegspunkt für den Webserver

Es ist sozusagen das Eingangstor zu deiner Laravel-Applikation – alles, was von außen sichtbar ist, befindet sich hier oder geht von hier aus. Genau aus diesem Grund wird dieses Verzeichnis auch als Root-Dokumentenverzeichnis für den Webserver (z.B. Nginx oder Apache) konfiguriert. Dies schützt den Rest der Anwendung – insbesondere Logik, Konfiguration und sensible Daten – vor öffentlichem Zugriff.

Die zentrale Rolle der index.php

Die Datei index.php ist der eigentliche Einstiegspunkt der Anwendung. Sie wird vom Webserver aufgerufen, sobald eine Anfrage eintrifft. Sie macht aber selbst fast nichts – stattdessen lädt und startet sie das Laravel-Framework. Die wichtigsten Schritte sind

  1. Laden der Autoloader-Dateien von Composer (require __DIR__.'/../vendor/autoload.php';)
  2. Laden der Anwendung über bootstrap/app.php
  3. Übergabe der HTTP-Anfrage an den Laravel-Kernel
  4. Rückgabe der HTTP-Response an den Browser

Man kann sich index.php als das dünne Band vorstellen, das externe Anfragen an die interne Logik weiterleitet – sicher, schlank und kontrolliert.

Warum nur public/ öffentlich erreichbar sein sollte

Ein weit verbreiteter Anfängerfehler ist es, den Webserver auf das Laravel-Hauptverzeichnis auszurichten. Dies öffnet die Tür zu vertraulichen Informationen: .env, config/, routes/, storage/ – all dies ist potentiell einsehbar.

Darum:
Nur public/ darf öffentlich erreichbar sein.

Dementsprechend muss dein Webserver – egal ob lokal mit Valet oder auf einem Server mit Nginx – so konfiguriert sein, dass public/ als Root dient:

Beispiel Nginx-Konfiguration:

root /var/www/deine-app/public;

So stellst du sicher, dass wirklich nur die freigegebenen Dateien erreichbar sind.

Was noch in public/ liegt

Neben index.php enthält das public/-Verzeichnis alle statischen Dateien – also solche, die direkt vom Browser geladen werden können, ohne dass Laravel involviert ist:

  • CSS-Dateien (z. B. aus dem Build-Prozess via Vite oder Tailwind)
  • JavaScript-Dateien (z. B. Vue, Alpine, Vanilla JS)
  • Bilder, Icons, Logos
  • Fonts
  • Favicon und robots.txt
  • .htaccess (nur bei Apache wichtig)

Diese Dateien erreichst du direkt über die URL, etwa:
https://deine-app.de/css/app.css

Sie müssen auch nicht über PHP gerendert werden – sie werden direkt vom Webserver ausgeliefert, was Performance bringt.

Der Umgang mit Assets und Vite

Seit Laravel 9 ist Vite der Standard für Asset-Bundling. Die Quelldateien (etwa .scss oder .ts) liegen im resources/-Verzeichnis, werden dort bearbeitet und beim Build in das public/-Verzeichnis geschrieben – etwa nach public/build/.

Im Code bindest du Assets dann so ein:

@vite(['resources/css/app.css', 'resources/js/app.js'])

Laravel kümmert sich im Hintergrund darum, dass im Produktionsmodus die richtigen, versionierten Dateien geladen werden – inklusive Cache-Busting.

Uploads und öffentlich zugängliche Dateien

Wenn deine Anwendung Dateiuploads (z.B. Benutzerfotos oder PDFs) verarbeitet, sollten diese nicht direkt nach public/ hochgeladen werden. Stattdessen landen sie normalerweise im Verzeichnis storage/app/public/ und werden über einen symbolischen Link mit public/storage verbunden.

Dazu dient der Artisan-Befehl:

php artisan storage:link

Danach sind die hochgeladenen Dateien über public/storage/xyz.jpg erreichbar – sauber getrennt vom Systemkern und trotzdem öffentlich zugänglich.

Fazit zu public/

Das Verzeichnis public/ ist ein zentrales Sicherheits- und Strukturkonzept in Laravel. Es hält alle öffentlich zugänglichen Dateien bereit und kapselt gleichzeitig den Kern der Anwendung vor direktem Zugriff. Ob statische Assets, der Einstiegspunkt via index.php oder Build-Ergebnisse – alles, was von außen erreichbar sein soll, gehört hierher. Wer public/ richtig einsetzt, schützt seine Anwendung und hält sie gleichzeitig performant und übersichtlich.

Das resources/-Verzeichnis – Views, Assets, Übersetzungen

Das resources/-Verzeichnis – Views, Assets, Übersetzungen

Im Verzeichnis resources/ befindet sich alles, was mit der Benutzeroberfläche, dem Design und der Sprache deiner Anwendung zu tun hat. Hier wird festgelegt, wie deine Anwendung aussieht und wie sie mit dem Benutzer kommuniziert – sowohl optisch als auch sprachlich.

Ob Blade Templates für HTML, Stylesheets, JavaScript oder Sprachdateien: Dieses Verzeichnis ist die kreative Schaltzentrale deiner Laravel-App.

Aufbau des Verzeichnisses

Das resources/-Verzeichnis ist in der Regel in drei Hauptbereiche unterteilt:

  • views/ – HTML-Templates (Blade)
  • lang/ – Übersetzungen und Lokalisierung
  • css/, js/ – Quellcode für das Frontend, verarbeitet durch Vite

views/ – Die Templates deiner Anwendung

Das Verzeichnis views/ enthält die sogenannten Blade-Dateien, Laravels eigene Templating-Sprache. Blade ist extrem flexibel, leicht verständlich und erlaubt es, HTML mit dynamischen PHP-Inhalten zu kombinieren – ohne unübersichtliches Inline-PHP.

Ein einfaches Blade-Template könnte so aussehen:

<!DOCTYPE html>
<html>
<head>
    <title>{{ $title }}</title>
</head>
<body>
    <h1>{{ $headline }}</h1>
    @yield('content')
</body>
</html>




Blade bietet viele Komfortfunktionen:

  • @if, @foreach, @include, @component, @extends usw.
  • Layouts mit Vererbung (@extends('layouts.app'))
  • Teilansichten (@include('partials.header'))
  • Schutz vor XSS mit {{ $variable }} (automatisches Escaping)

Die Views sind standardmäßig in Ordnern wie views/welcome.blade.php, views/layouts/, views/auth/ usw. organisiert – du kannst sie aber beliebig erweitern, solange du dich an die Pfadkonventionen hältst.

lang/ – Mehrsprachigkeit und Lokalisierung

Wenn du deine Anwendung mehrsprachig aufbauen möchtest, ist resources/lang/ der richtige Ort. Hier legst du einen Ordner pro Sprache an, z.B:

  • lang/en/
  • lang/de/

Darin befinden sich PHP- oder JSON-Dateien mit Schlüssel-Wert-Paaren:

// lang/de/messages.php
return [
    'welcome' => 'Willkommen!',
    'login' => 'Anmelden',
];




Im Code greifst du dann so darauf zu:

{{ __('messages.welcome') }}

Oder mit dem globalen trans()-Helper:

trans('messages.login');

Ab Laravel 9 können auch einzelne JSON-Dateien (z.B. de.json) verwendet werden, was besonders für einfache Übersetzungen nützlich ist:

{
    "Welcome": "Willkommen",
    "Logout": "Abmelden"
}




Das macht Lokalisierung einfach und flexibel – ideal für mehrsprachige Projekte, auch im späteren Ausbau.

css/, js/ – Moderne Frontend-Assets

Laravel verwendet Vite als Build-Tool, um moderne Frontend-Workflows zu ermöglichen. Die eigentlichen Quelldateien befinden sich im Verzeichnis resources/:

  • resources/css/ → z. B. Tailwind CSS, SCSS oder Standard-CSS
  • resources/js/ → Vue, AlpineJS oder Vanilla JS

Du kannst hier also deine gesamte Frontend-Struktur modular aufbauen – Vite kümmert sich beim Build darum, alles zu bündeln, zu versionieren und nach public/ auszugeben.

Beispiel einer typischen Vite Integration in einem Bladefile:

@vite(['resources/css/app.css', 'resources/js/app.js'])

Dadurch bekommst du Features wie:

  • Live-Reloading im lokalen Entwicklungsserver
  • Minimierung und Versionierung im Produktionsmodus
  • Optimierte Performance durch moderne Bundling-Techniken

Laravel erleichtert dir damit die Arbeit im Frontend erheblich – egal, ob du ein klassisches HTML-Frontend oder eine Single-Page-App entwickelst.

Weitere Ressourcen im resources/-Verzeichnis

Je nach Projektstruktur können hier noch weitere Ressourcen liegen:

  • Icons, SVGs oder andere statische Design-Elemente (vor dem Build-Prozess)
  • Mail-Templates (früher lagen sie auch oft in views/emails/)
  • Livewire-Komponenten oder andere UI-Bibliotheken

Du kannst die Struktur flexibel anpassen, solange du die Referenzen korrekt im Code oder in der Vite-Konfiguration setzt.

Best Practices im Umgang mit resources/

  • Halte deine Views übersichtlich – nutze Layouts und Partials, um Code-Wiederholung zu vermeiden.
  • Übersetzungen sollten klar benannt und gruppiert sein (auth.php, messages.php etc.).
  • Verwende sinnvolle Namensräume und pflege Ordnung, besonders bei vielen Komponenten.
  • Nutze den Vite-Dev-Server im lokalen Setup, um Änderungen in Echtzeit zu sehen (npm run dev).

Fazit zu resources/

Das Verzeichnis resources/ ist der kreative Raum in Laravel – hier definierst du, wie deine Anwendung aussieht, was sie sagt und wie sie mit dem Benutzer interagiert. Mit Blade, Vite und einer flexiblen Übersetzungsstruktur gibt dir Laravel alles an die Hand, um moderne, performante und benutzerfreundliche Frontends zu entwickeln – egal ob mehrsprachige Websites oder dynamische Webanwendungen.

Das routes/-Verzeichnis – Die Wegweiser deiner Anwendung

Das routes/-Verzeichnis – Die Wegweiser deiner Anwendung

Alle eingehenden HTTP-Anfragen landen früher oder später bei einer Route – und genau diese Routen definierst du im Verzeichnis routes/. Es ist also der zentrale Ort, an dem du festlegst, welche URL welchen Code ausführt.

Laravel macht dir das Routing einfach, aber gleichzeitig extrem mächtig. Statt mit komplexen Konfigurationsdateien arbeitest du einfach mit PHP – sauber, lesbar und flexibel.

Was ist Routing überhaupt?

Routing bedeutet, dass Laravel eingehende Anfragen (z.B. GET /home oder POST /login) analysiert und entscheidet, welche Aktion ausgeführt werden soll – z.B. eine Seite anzeigen, einen Controller ausführen oder JSON zurückgeben.

In Laravel definiert man das Routing deklarativ mit Methoden wie Route::get(), Route::post(), Route::put() etc. Das macht die Logik auf einen Blick verständlich.

Struktur des routes/-Verzeichnisses

Im routes/-Ordner findest du standardmäßig vier Dateien – jede mit einer klaren Zuständigkeit:

DateiZweck
web.phpRouten für das klassische Web – mit Sessions, Cookies, CSRF usw.
api.phpRouten für APIs – stateless, oft im JSON-Format
console.phpBefehle, die über die Konsole ausgeführt werden (Artisan)
channels.phpDefinition von Broadcast-Kanälen für Echtzeitkommunikation (WebSockets)

Du kannst diese Dateien natürlich weiter strukturieren, etwa mit Unterdateien, die du aus web.php heraus inkludierst – ideal bei größeren Projekten.

Beispiele für Routing in web.php

Ein einfacher GET-Route:

Route::get('/about', function () {
    return view('about');
});




Eine Route mit Controller:

Route::get('/dashboard', [DashboardController::class, 'index']);

Eine Route mit Middleware:

Route::get('/admin', [AdminController::class, 'index'])
     ->middleware('auth');




Eine benannte Route:

Route::get('/profile', [ProfileController::class, 'show'])->name('profile');

Das ermöglicht es dir, die Route später dynamisch aufzurufen:

<a href="{{ route('profile') }}">Mein Profil</a>

Das api.php-Routing – speziell für APIs

Routen in api.php sind automatisch mit dem Prefix /api versehen und nutzen die Middleware api – das bedeutet:

  • Keine Sessions oder Cookies
  • Standardmäßig JSON als Antwort
  • Ideal für Mobile Apps, Single-Page-Apps, externe Schnittstellen

Beispiel:

Route::get('/posts', [PostController::class, 'index']);

Diese Route wäre unter https://deine-app.de/api/posts erreichbar.

Für APIs bietet Laravel zusätzlich Features wie Rate-Limiting, Auth über Token (z.B. Sanctum, Passport) und Ressourcen-Routing.

Routen gruppieren und strukturieren

Bei größeren Projekten wird das Routing schnell unübersichtlich – Laravel bietet mehrere Möglichkeiten, das zu strukturieren:

Route Groups mit Middleware, Prefix oder Namespace

Route::middleware(['auth'])->prefix('admin')->group(function () {
    Route::get('/dashboard', [AdminController::class, 'dashboard']);
});




Ressourcen-Routen (CRUD in einem Aufruf)

Route::resource('posts', PostController::class);

Erzeugt automatisch sieben Routen (index, create, store, show, edit, update, destroy).

3. API Resources

Für APIs lässt sich apiResource verwenden:

Route::apiResource('users', UserController::class);

Reduziert auf die nötigsten Methoden – ohne create und edit.

Routen in console.php und channels.php

  • console.php
    Hier definierst du benutzerdefinierte Artisan-Befehle. Diese Routen sind nicht HTTP-basiert, sondern für die Kommandozeile gedacht – ideal für Wartungsjobs, Reports oder Tools. Beispiel: Artisan::command('cleanup:users', function () { // Logik hier });
  • channels.php
    Wenn du Laravel Echo oder Websockets einsetzt, definierst du hier, wer Zugriff auf welche Channels hat – etwa für Chat-Funktionen oder Benachrichtigungen. Beispiel: Broadcast::channel('orders.{orderId}', function ($user, $orderId) { return $user->id === Order::find($orderId)->user_id; });

Caching für Performance

In produktiven Umgebungen ist es sinnvoll, Routen zu cachen – insbesondere bei großen Projekten. Dies geschieht mit: php artisan route:cache Damit wird eine optimierte Datei in bootstrap/cache/routes.php abgelegt. Änderungen an den Routen erfordern dann einen erneuten Cache-Build:

php artisan route:clear

Best Practices für Routing

  • Verwende sprechende, SEO-freundliche URLs (z. B. /blog/artikel/123 statt /show?id=123)
  • Gruppiere Routen logisch – z. B. nach Modulen oder Zugriffsebene
  • Nutze benannte Routen für Links und Weiterleitungen
  • Reduziere Inline-Closures – setze stattdessen auf Controller-Methoden
  • Cache Routen nur im Produktivbetrieb, nicht während der Entwicklung

Fazit zu routes/

Das Verzeichnis routes/ ist die Schaltzentrale für alle Anfragen an deine Laravel-Applikation. Ob klassische Webseiten, moderne APIs oder Echtzeitfunktionen – hier legst du fest, was passieren soll, wenn jemand deine Anwendung aufruft. Laravel macht es dir angenehm einfach, aber gleichzeitig flexibel genug für große, skalierbare Projekte. Wer das Routing versteht, hat die Kontrolle über den Datenfluss – und das ist in jeder Webanwendung entscheidend.

Das storage/-Verzeichnis – Zwischenablage der Anwendung

Das storage/-Verzeichnis – Zwischenablage der Anwendung

Ob Logs, temporäre Dateien, gecachte Views oder User-Uploads – das Verzeichnis storage/ ist die Ablagefläche deiner Laravel-Anwendung. Es ist ein unscheinbarer, aber unverzichtbarer Teil des Frameworks, denn hier laufen viele Hintergrundprozesse zusammen, die für eine performante und stabile Anwendung sorgen.

Während das Verzeichnis app/ die Logik und resources/ die Oberfläche verwaltet, dient storage/ als Arbeitsbereich im Hintergrund. Laravel schreibt hier Daten, auf die der Benutzer keinen direkten Zugriff hat, die aber für den Ablauf der Anwendung essentiell sind.

Die drei Hauptbereiche im Überblick

Das storage/-Verzeichnis ist sauber gegliedert in drei Unterordner:

app/ – App-interne Dateien und Benutzer-Uploads

Hier landen die Dateien, die du selbst speicherst – zum Beispiel generierte PDFs, Excel-Dateien oder Benutzer-Uploads. Standardmäßig ist dieses Verzeichnis nicht öffentlich zugänglich, was auch gut so ist, denn nicht jede Datei sollte von außen zugänglich sein.

Für Dateien, die du öffentlich zur Verfügung stellen möchtest (z.B. Profilbilder), verwendest du in der Regel das Verzeichnis

php artisan storage:link

Damit wird ein symbolischer Link von public/storage auf storage/app/public erstellt. Du kannst dann im Code z. B. folgendes verwenden:

<;img src="{{ asset('storage/userpics/avatar.jpg') }}">

Laravel kümmert sich automatisch um Pfade und Zugriff.

framework/ – Caches, Sessions, Views

Dieser Ordner wird vom Framework selbst verwaltet und enthält temporäre Daten:

  • cache/: Gespeicherte Konfigurations- und Routen-Caches
  • sessions/: Session-Dateien, falls du file als Session-Treiber verwendest
  • views/: Kompilierte Blade-Templates – also fertiges HTML nach Verarbeitung durch Blade

Besonders interessant ist views/: Laravel kompiliert jede .blade.php Datei einmal und speichert das Ergebnis hier. Das beschleunigt das Rendering erheblich, da das Template nicht bei jedem Aufruf neu interpretiert werden muss.

Wenn du z.B. den php artisan-Befehl view:clear verwendest, leert Laravel diesen Ordner und erzwingt eine Neuerstellung.

logs/ – Protokolle und Fehlermeldungen

In diesem Ordner landen die Logdateien deiner Anwendung. Standardmäßig ist das: storage/logs/laravel.log Hier schreibt Laravel alles rein, was über Log::info(), Log::error() oder durch Exceptions erzeugt wird. Das ist extrem nützlich für Debugging und Fehlersuche.

Du kannst die Log-Konfiguration in config/logging.php anpassen – z.B. für tägliche Rotationen (daily), externe Dienste wie Papertrail oder eine Kombination mehrerer Channels (stack).

Berechtigungen: Ein oft übersehener Punkt

Das Verzeichnis storage/ muss vom Webserver beschreibbar sein, sonst kann Laravel keine Logs schreiben, keine Sessions speichern und keine Caches anlegen.

Je nach Hostingumgebung müssen die Zugriffsrechte gesetzt werden, z.B:

chmod -R 775 storage
chown -R www-data:www-data storage




Gerade bei der Ersteinrichtung oder nach einem Serverwechsel ist dies einer der häufigsten Stolpersteine.

Typische Anwendungsfälle

  • Datei-Uploads speichern und verarbeiten
  • PDFs generieren und temporär ablegen
  • Kompilierte E-Mails oder Reports zwischenlagern
  • Session-Daten lokal halten (bei file-Session-Treiber)
  • Langfristige Logs zur Fehleranalyse speichern

Auch externe Storage-Treiber wie Amazon S3 oder FTP können über das Laravel-Filesystem angesprochen werden – aber storage/ bleibt meist der lokale Default.

Best Practices für das Arbeiten mit storage/

  • Nutze Storage-Facade oder das Filesystem-Contract statt file_put_contents() – das macht deine Anwendung portabler.
  • Bereinige alte Dateien regelmäßig (z. B. mit einem Artisan-Command über den Task Scheduler).
  • Halte sensible Dateien nie direkt im public/-Verzeichnis – verwende storage/app oder storage/app/private.
  • Setze auf klare Pfadkonventionen innerhalb von storage/app, z. B. invoices/, avatars/, exports/.

Fazit zu storage/

Das Verzeichnis storage/ ist die Werkbank von Laravel: Unsichtbar für den Benutzer, aber zentral für die Arbeit im Hintergrund. Ob Sessions, Logs, Caches oder Dateien – hier legt deine Anwendung alles ab, was temporär oder dauerhaft benötigt wird. Wer es sinnvoll nutzt und die Zugriffsrechte richtig konfiguriert, sorgt für Stabilität, Performance und Sicherheit im laufenden Betrieb.

Das tests/-Verzeichnis – Testgetriebene Entwicklung mit Laravel

Das tests/-Verzeichnis – Testgetriebene Entwicklung mit Laravel

Automatisierte Tests haben in Laravel ihren festen Platz – direkt im Verzeichnis tests/. Hier legst du alle Unit- und Feature-Tests ab, mit denen du sicherstellen kannst, dass deine Anwendung funktioniert, stabil läuft und bei Änderungen keine unerwarteten Nebeneffekte auftreten.

Laravel bringt bereits im Standard-Setup alles mit, was du brauchst: PHPUnit, Test-Hilfsfunktionen, einen Beispieltest – und eine durchdachte Verzeichnisstruktur. Ob du testgetrieben entwickelst (TDD) oder bestehende Funktionen absicherst – Laravel nimmt dir viel Arbeit ab.

Die Grundstruktur von tests/

Das Verzeichnis ist in zwei Hauptbereiche unterteilt:

OrdnerZweck
Feature/Tests ganzer Abläufe – inkl. Routen, Views, DB
Unit/Tests einzelner Klassen, Funktionen oder Logik

Außerdem gibt es die zentrale Datei TestCase.php, die deine Basisklasse für alle Tests ist. Hier kannst du Setups definieren, gemeinsame Helferfunktionen hinterlegen oder Test-Services registrieren.

Unterschied zwischen Feature- und Unit-Tests

Feature-Tests

Diese Tests prüfen komplette Abläufe – zum Beispiel, ob sich ein Benutzer erfolgreich einloggen kann oder ob ein Formular korrekt verarbeitet wird.

Beispiel:

public function test_user_can_view_homepage()
{
    $response = $this->get('/');
    $response->assertStatus(200);
    $response->assertSee('Willkommen');
}




Hier wird tatsächlich eine HTTP-Anfrage simuliert – Laravel bootet den gesamten Application Stack inklusive Middleware, Routing, Datenbank (mit Testdaten) und Views.

Unit-Tests

Diese Tests konzentrieren sich auf eine bestimmte Klasse oder Methode – isoliert vom Rest des Frameworks. Sie testen die Logik im Detail: Berechnungsregeln, String-Verarbeitung, Services.

Beispiel:

public function test_tax_calculation()
{
    $service = new TaxService();
    $result = $service->calculate(100);
    $this->assertEquals(119, $result);
}

Solche Tests sind schnell und unabhängig. Sie helfen, Kernlogik stabil zu halten – besonders bei komplexer Business-Logik.

Tests schreiben mit Artisan

Laravel bietet dafür eigene Artisan-Kommandos:

php artisan make:test RegisterUserTest

Erstellt standardmäßig einen Feature-Test. Willst du explizit einen Unit-Test:

php artisan make:test UserHelperTest --unit

Du kannst dann in der erzeugten Klasse direkt loslegen – die Teststruktur ist vorgegeben.

Datenbank in Tests: Die RefreshDatabase-Methode

Wenn dein Test mit der Datenbank arbeitet (z.B. neue Benutzer anlegt), sorgt Laravel dafür, dass du für jeden Testlauf eine neue Datenbank bekommst. Dazu verwendest du das Trait RefreshDatabase:

use Illuminate\Foundation\Testing\RefreshDatabase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;
    
    public function test_user_registration()
    {
        $response = $this->post('/register', [
            'name' => 'Max',
            'email' => 'max@example.com',
            'password' => 'secret',
            'password_confirmation' => 'secret'
        ]);

        $this->assertDatabaseHas('users', ['email' => 'max@example.com']);
    }
}




So bleibt deine Datenbank sauber – nach jedem Test wird sie automatisch zurückgesetzt.

Browser-Tests mit Laravel Dusk (optional)

Für vollautomatisierte Tests mit einem echten Browser kann man Laravel Dusk verwenden. Dusk startet Chrome im Hintergrund und testet die Oberfläche – ideal für E2E-Tests (End-to-End). So können z.B. Klicks, Eingaben, Logins und Formularinteraktionen real simuliert werden.

Dusk wird als separates Paket installiert:

composer require --dev laravel/dusk

Tests ausführen

Alle Tests startest du ganz einfach mit:

php artisan test

Alternativ direkt mit PHPUnit:

vendor/bin/phpunit

Laravel gibt dir ein übersichtliches Ergebnis mit grün/roter Anzeige, Zeitdauer und Fehlern. Das macht es einfach, gezielt Fehler aufzuspüren.

Du kannst auch einzelne Tests oder nur eine bestimmte Methode ausführen:

php artisan test --filter=UserCanRegisterTest

Best Practices für Tests in Laravel

  • Schreibe Tests für kritische Logik zuerst – z. B. Zahlungsabwicklung, Registrierung, Berechtigungen.
  • Nutze Factories, um Testdaten schnell und konsistent zu erzeugen.
  • Vermeide zu viele Abhängigkeiten im Unit-Test – mocke externe Services.
  • Setze auf sprechende Testnamen, z. B. test_guest_cannot_access_dashboard().
  • Automatisiere Tests im Deployment, z. B. über GitHub Actions, GitLab CI oder andere CI/CD-Systeme.

Fazit zu tests/

Das tests/ Verzeichnis ist der Beweis, dass Laravel Testing ernst nimmt – und das Testen so einfach wie möglich macht. Egal ob einfache Funktionen oder komplexe Userflows: Mit Feature- und Unit-Tests kannst du alles abdecken. Richtig eingesetzt schützen Tests vor ungewollten Nebeneffekten, machen Refactorings sicherer und geben dir als Entwickler deutlich mehr Ruhe beim Arbeiten. Kurz: Testen lohnt sich – besonders mit Laravel.

Warum die Laravel-Verzeichnisstruktur den Unterschied macht

Die Verzeichnisstruktur von Laravel erscheint auf den ersten Blick komplex, entpuppt sich aber schnell als durchdachtes Gerüst für jede Art von Webanwendung. Sie bietet Orientierung, fördert Best Practices und ermöglicht eine klare Trennung von Verantwortlichkeiten.

Wer die Struktur versteht, arbeitet schneller, macht weniger Fehler und kann im Team effizient agieren. Vor allem bei Wartung und Skalierung zahlt sich dieses Wissen aus.

Laravel FAQ

FAQ – Häufig gestellte Fragen zur Laravel-Verzeichnisstruktur

Was passiert, wenn ich eigene Verzeichnisse in app/ erstelle?
Laravel lädt alle Klassen im app/-Verzeichnis, solange sie korrekt per PSR-4 eingebunden sind. Eigene Ordner wie Services/ oder Actions/ sind problemlos möglich.

Kann ich die Struktur verändern oder anpassen?
Grundsätzlich ja, aber mit Vorsicht. Manche Pfade sind in Laravel fest verdrahtet. Änderungen sollten bewusst und dokumentiert sein.

Wie gehe ich mit wachsender Projektgröße um?
Modulare Ansätze wie Domain-Driven Design oder Packages (z. B. nWidart/laravel-modules) helfen, die Struktur auch bei großen Anwendungen übersichtlich zu halten.

Was gehört in public/ und was nicht?
Nur öffentlich zugängliche Dateien: index.php, statische Assets, Favicon etc. Anwendungslogik, Konfiguration und sensible Dateien bleiben außerhalb.

Warum funktioniert meine Route nicht, obwohl sie definiert ist?
Mögliche Gründe: Caching (php artisan route:cache), falscher HTTP-Verb, Middleware oder Konflikte mit vorhandenen Pfaden. Routen-Cache regelmäßig löschen bei Änderungen.