> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Facades

> Erläutert die Funktionsweise und Nutzung von Facades in Laravel, Realtime Facades, das Testen sowie die Abgrenzung zu Dependency Injection.

## Was ist eine Facade?

Facades stellen eine „statische" Schnittstelle zu Klassen bereit, die im [Service Container](/de/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.

```php theme={null}
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;

Route::get('/cache', function () {
    return Cache::get('key');
});
```

<Info>
  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.
</Info>

## 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.

```mermaid theme={null}
flowchart LR
    A["Cache::get('key')"] --> B["Facade::__callStatic()"]
    B --> C["getFacadeAccessor()<br>→ 'cache'"]
    C --> D["Service Container<br>make('cache')"]
    D --> E["Instanz der konkreten Klasse<br>CacheManager"]
    E --> F["get('key')<br>ausführen"]
```

```php theme={null}
<?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:

```php theme={null}
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.

<Warning>
  Wenn eine Klasse zu groß wird, überlegen Sie, sie in mehrere kleinere Klassen aufzuteilen.
</Warning>

### 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.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
// 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.

```php theme={null}
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 theme={null}
<?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 theme={null}
<?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 theme={null}
<?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();
});
```

<Tip>
  Realtime Facades sind praktisch, wenn Sie Argumente vermeiden möchten, ohne die Testbarkeit über Mocks zu verlieren.
</Tip>

## 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.

```php theme={null}
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:

| Methode                   | Beschreibung                               |
| ------------------------- | ------------------------------------------ |
| `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:

| Facade         | Klasse                                    | Bindung      |
| -------------- | ----------------------------------------- | ------------ |
| `App`          | `Illuminate\Foundation\Application`       | `app`        |
| `Auth`         | `Illuminate\Auth\AuthManager`             | `auth`       |
| `Cache`        | `Illuminate\Cache\CacheManager`           | `cache`      |
| `Config`       | `Illuminate\Config\Repository`            | `config`     |
| `Cookie`       | `Illuminate\Cookie\CookieJar`             | `cookie`     |
| `Crypt`        | `Illuminate\Encryption\Encrypter`         | `encrypter`  |
| `DB`           | `Illuminate\Database\DatabaseManager`     | `db`         |
| `Event`        | `Illuminate\Events\Dispatcher`            | `events`     |
| `File`         | `Illuminate\Filesystem\Filesystem`        | `files`      |
| `Gate`         | `Illuminate\Contracts\Auth\Access\Gate`   | —            |
| `Hash`         | `Illuminate\Contracts\Hashing\Hasher`     | `hash`       |
| `Http`         | `Illuminate\Http\Client\Factory`          | —            |
| `Log`          | `Illuminate\Log\LogManager`               | `log`        |
| `Mail`         | `Illuminate\Mail\Mailer`                  | `mailer`     |
| `Notification` | `Illuminate\Notifications\ChannelManager` | —            |
| `Queue`        | `Illuminate\Queue\QueueManager`           | `queue`      |
| `RateLimiter`  | `Illuminate\Cache\RateLimiter`            | —            |
| `Redirect`     | `Illuminate\Routing\Redirector`           | `redirect`   |
| `Request`      | `Illuminate\Http\Request`                 | `request`    |
| `Route`        | `Illuminate\Routing\Router`               | `router`     |
| `Schema`       | `Illuminate\Database\Schema\Builder`      | —            |
| `Session`      | `Illuminate\Session\SessionManager`       | `session`    |
| `Storage`      | `Illuminate\Filesystem\FilesystemManager` | `filesystem` |
| `URL`          | `Illuminate\Routing\UrlGenerator`         | `url`        |
| `Validator`    | `Illuminate\Validation\Factory`           | `validator`  |
| `View`         | `Illuminate\View\Factory`                 | `view`       |

## Nächste Schritte

<Card title="Contracts" icon="file-contract" href="/de/contracts">
  Lernen Sie das Gegenstück zu Facades kennen und erfahren Sie, wann welches Konzept passt.
</Card>


## Related topics

- [Statische Analyse für Pakete (PHPStan / Larastan)](/de/advanced/package-static-analysis.md)
- [Laravel-Paketentwicklung](/de/advanced/package-development.md)
- [Contracts](/de/contracts.md)
- [Logging](/de/logging.md)
- [Webhook / Bot - LINE SDK für Laravel](/de/packages/laravel-line-sdk/bot.md)
