Zum Hauptinhalt springen

Was ist eine Facade?

Facades stellen eine „statische” Schnittstelle zu Klassen bereit, die im Service Container Ihrer Anwendung verfügbar sind. Laravel bringt zahlreiche Facades mit, über die Sie fast alle Funktionen des Frameworks erreichen. Laravel-Facades fungieren als „statische Proxies” auf konkrete Klassen im Service Container. Dabei bieten sie eine kompakte, ausdrucksstarke Syntax bei gleichzeitig besserer Testbarkeit und Flexibilität als klassische statische Methoden. Alle Laravel-Facades sind im Namespace Illuminate\Support\Facades definiert.
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;

Route::get('/cache', function () {
    return Cache::get('key');
});
Sie müssen nicht sofort jedes Detail hinter Facades verstehen. Beginnen Sie einfach mit der Nutzung und lernen Sie Laravel Schritt für Schritt kennen.

Wie Facades funktionieren

In einer Laravel-Anwendung sind Facades Klassen, die einen Zugriff auf ein Objekt aus dem Container bereitstellen. Realisiert wird das über die Klasse Facade. Alle Laravel-Facades sowie eigene Facades erben von der Basisklasse Illuminate\Support\Facades\Facade. Die Basisklasse Facade nutzt die Magic Method __callStatic(), um Aufrufe an der Facade an das aus dem Container aufgelöste Objekt zu delegieren.
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Profil des angegebenen Benutzers anzeigen.
     */
    public function showProfile(string $id): View
    {
        $user = Cache::get('user:'.$id);

        return view('profile', ['user' => $user]);
    }
}
Am Dateianfang importieren wir die Facade Cache. Diese leitet den Zugriff an eine Implementierung von Illuminate\Contracts\Cache\Factory weiter. Alle Aufrufe über die Facade landen bei der internen Cache-Instanz von Laravel. Wenn Sie sich die Klasse Illuminate\Support\Facades\Cache ansehen, werden Sie keine statische Methode get finden:
class Cache extends Facade
{
    /**
     * Registrierten Namen der Komponente zurückgeben.
     */
    protected static function getFacadeAccessor(): string
    {
        return 'cache';
    }
}
Die Cache-Facade erbt von der Basis Facade und definiert die Methode getFacadeAccessor(). Deren Rückgabewert ist der Name der Bindung im Service Container. Wenn ein Nutzer eine statische Methode der Cache-Facade aufruft, löst Laravel die Bindung cache aus dem Service Container auf und ruft auf dem Objekt die gewünschte Methode (hier get) auf.

Wann Facades sinnvoll sind – und wann nicht

Vorteile

Facades bieten viele Vorteile. Sie stellen eine prägnante, gut merkbare Syntax für Laravel-Funktionalität bereit, ohne dass Sie sich lange Klassennamen merken oder Dependencies manuell injizieren müssen. Dank PHP-Magie sind sie zugleich sehr gut testbar.

Auf Scope-Creep achten

Ein Risiko beim Umgang mit Facades ist der „Scope-Creep” einer Klasse. Weil Facades so bequem verwendet werden können und keine Injektion erfordern, wachsen Klassen leicht unbemerkt. Mit Dependency Injection wirkt ein aufgeblähter Konstruktor als visuelles Warnzeichen. Achten Sie also besonders bei Facades darauf, den Verantwortungsbereich Ihrer Klassen klein zu halten.
Wenn eine Klasse zu groß wird, überlegen Sie, sie in mehrere kleinere Klassen aufzuteilen.

Facades vs. Dependency Injection

Ein zentraler Vorteil von Dependency Injection ist, dass die injizierte Implementierung austauschbar ist – nützlich beispielsweise für Tests, wo Sie Mocks oder Stubs injizieren und Aufrufe verifizieren können. Rein statische Methoden lassen sich normalerweise weder mocken noch stubben. Da Facades aber Aufrufe an das aus dem Container aufgelöste Objekt delegieren, können Sie eine Facade genauso testen wie eine injizierte Instanz.
use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
    return Cache::get('key');
});
Zu dieser Route lässt sich der folgende Test schreiben, der prüft, dass Cache::get mit den erwarteten Argumenten aufgerufen wurde.
use Illuminate\Support\Facades\Cache;

test('basic example', function () {
    Cache::shouldReceive('get')
        ->with('key')
        ->andReturn('value');

    $response = $this->get('/cache');

    $response->assertSee('value');
});

Facades vs. Helper-Funktionen

Ergänzend zu Facades bringt Laravel Helfer-Funktionen mit, mit denen sich häufige Aufgaben erledigen lassen: Views erzeugen, Events feuern, Jobs dispatchen, HTTP-Antworten senden usw. Viele Helper machen dasselbe wie ihre entsprechenden Facades.
// Aufruf über eine Facade
return Illuminate\Support\Facades\View::make('profile');

// Äquivalent per Helper-Funktion
return view('profile');
Es gibt keinen praktischen Unterschied zwischen den beiden Varianten. Auch bei Helper-Funktionen können Sie genauso testen wie bei der zugehörigen Facade.
use Illuminate\Support\Facades\Cache;

test('cache helper test', function () {
    Cache::shouldReceive('get')
        ->with('key')
        ->andReturn('value');

    $response = $this->get('/cache');

    $response->assertSee('value');
});

Realtime Facades

Mit Realtime Facades können Sie jede Klasse Ihrer Anwendung wie eine Facade verwenden. Zur Verdeutlichung sehen wir uns zuerst Code ohne Realtime Facade an. Angenommen, das Modell Podcast besitzt eine Methode publish. Zum Veröffentlichen eines Podcasts wird jedoch eine Publisher-Instanz benötigt.
<?php

namespace App\Models;

use App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;

class Podcast extends Model
{
    /**
     * Den Podcast veröffentlichen.
     */
    public function publish(Publisher $publisher): void
    {
        $this->update(['publishing' => now()]);

        $publisher->publish($this);
    }
}
Mit einer Realtime Facade müssen Sie den Publisher nicht mehr explizit übergeben – die Testbarkeit bleibt trotzdem erhalten. Für eine Realtime Facade stellen Sie dem Namespace der zu importierenden Klasse Facades voran.
<?php

namespace App\Models;

use Facades\App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;

class Podcast extends Model
{
    /**
     * Den Podcast veröffentlichen.
     */
    public function publish(): void
    {
        $this->update(['publishing' => now()]);

        Publisher::publish($this);
    }
}
Bei der Nutzung einer Realtime Facade wird die Publisher-Implementierung aus dem Service Container über den Klassen- oder Interface-Namen ermittelt, der auf das Präfix Facades folgt.
<?php

use App\Models\Podcast;
use Facades\App\Contracts\Publisher;
use Illuminate\Foundation\Testing\RefreshDatabase;

pest()->use(RefreshDatabase::class);

test('podcast can be published', function () {
    $podcast = Podcast::factory()->create();

    Publisher::shouldReceive('publish')->once()->with($podcast);

    $podcast->publish();
});
Realtime Facades sind praktisch, wenn Sie Argumente vermeiden möchten, ohne die Testbarkeit über Mocks zu verlieren.

Facades testen

Zum Testen von Facades verwenden Sie die Methode shouldReceive, die eine Mockery-Instanz zurückgibt. Da Facades von Laravels Service Container aufgelöst und verwaltet werden, sind sie deutlich besser testbar als klassische statische Klassen.
use Illuminate\Support\Facades\Cache;

test('Benutzerprofil anzeigen', function () {
    Cache::shouldReceive('get')
        ->once()
        ->with('user:1')
        ->andReturn(['name' => 'Taylor']);

    $response = $this->get('/users/1');

    $response->assertSee('Taylor');
});
Häufig verwendete Mock-Methoden:
MethodeBeschreibung
shouldReceive('method')Erwartet, dass die Methode aufgerufen wird
once()Erwartet genau einen Aufruf
times(n)Erwartet n Aufrufe
with(args)Erwartet Aufruf mit bestimmten Argumenten
andReturn(value)Gibt den angegebenen Wert zurück
andReturnNull()Gibt null zurück

Übersicht wichtiger Facades

Zuordnung häufig genutzter Facades zu ihren konkreten Klassen und den Bindungen im Service Container:
FacadeKlasseBindung
AppIlluminate\Foundation\Applicationapp
AuthIlluminate\Auth\AuthManagerauth
CacheIlluminate\Cache\CacheManagercache
ConfigIlluminate\Config\Repositoryconfig
CookieIlluminate\Cookie\CookieJarcookie
CryptIlluminate\Encryption\Encrypterencrypter
DBIlluminate\Database\DatabaseManagerdb
EventIlluminate\Events\Dispatcherevents
FileIlluminate\Filesystem\Filesystemfiles
GateIlluminate\Contracts\Auth\Access\Gate
HashIlluminate\Contracts\Hashing\Hasherhash
HttpIlluminate\Http\Client\Factory
LogIlluminate\Log\LogManagerlog
MailIlluminate\Mail\Mailermailer
NotificationIlluminate\Notifications\ChannelManager
QueueIlluminate\Queue\QueueManagerqueue
RateLimiterIlluminate\Cache\RateLimiter
RedirectIlluminate\Routing\Redirectorredirect
RequestIlluminate\Http\Requestrequest
RouteIlluminate\Routing\Routerrouter
SchemaIlluminate\Database\Schema\Builder
SessionIlluminate\Session\SessionManagersession
StorageIlluminate\Filesystem\FilesystemManagerfilesystem
URLIlluminate\Routing\UrlGeneratorurl
ValidatorIlluminate\Validation\Factoryvalidator
ViewIlluminate\View\Factoryview

Nächste Schritte

Contracts

Lernen Sie das Gegenstück zu Facades kennen und erfahren Sie, wann welches Konzept passt.
Zuletzt geändert am 13. Juli 2026