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

# ForwardsCalls-Trait

> Wie Sie mit Illuminate\Support\Traits\ForwardsCalls die Methodenweiterleitung in Proxy-/Decorator-Klassen sicher implementieren.

## Was ist der ForwardsCalls-Trait?

`Illuminate\Support\Traits\ForwardsCalls` ist ein Trait, der die Delegation von Methoden an ein anderes Objekt vereinheitlicht. Im Laravel-Kern wird er in „Wrapper-Objekten" wie Eloquent oder Mail eingesetzt.

<Info>
  Die Implementierung befindet sich unter `src/Illuminate/Support/Traits/ForwardsCalls.php`. Beim Weiterleiten einer nicht existierenden Methode wird eine `BadMethodCallException` mit dem aufrufenden Klassennamen erneut geworfen.
</Info>

```mermaid theme={null}
flowchart LR
  A["Ihre Proxy-Klasse"] -->|__call| B["forwardCallTo()"]
  B --> C["internen Driver / Builder"]
  C --> D["Ergebnis zurückgeben"]
  D --> A
```

## Kern-API

### `forwardCallTo($object, $method, $parameters)`

Leitet die Methode unverändert an das angegebene Objekt weiter. Der typische Aufrufort ist `__call()`.

### `forwardDecoratedCallTo($object, $method, $parameters)`

Nützlich, wenn Sie in einem Builder oder Decorator die Chain aufrechterhalten wollen. Gibt die weitergeleitete Methode „das Zielobjekt selbst" zurück, wird stattdessen das „aufrufende Objekt (`$this`)" zurückgegeben.

### Kombination mit `__call()` / `__callStatic()`

`ForwardsCalls` liefert keine Magic Methods. Sie implementieren `__call()` (bei Bedarf auch `__callStatic()`) in Ihrer Klasse und rufen dort die `forwardCallTo`-Methoden auf.

## Reale Anwendungsbeispiele (Laravel-intern)

<Steps>
  <Step title="Facade stellt einen Static Proxy bereit">
    `Illuminate\Support\Facades\Facade` delegiert in `__callStatic()` direkt an die Root-Instanz. Da Facades statisch aufgerufen werden, ist das keine Verwendung von `ForwardsCalls`, sondern eine direkte Weiterleitung.
  </Step>

  <Step title="Der Eloquent Builder nutzt forwardCallTo">
    `Illuminate\Database\Eloquent\Builder::__call()` reicht unbekannte Methoden über `forwardCallTo($this->query, ...)` an den internen Query Builder weiter und gibt am Ende `$this` zurück, um die Fluent Chain zu erhalten.
  </Step>

  <Step title="Relation / Mail / Event verwenden forwardDecoratedCallTo">
    In `Illuminate\Database\Eloquent\Relations\Relation`, `Illuminate\Mail\Message` und `Illuminate\Events\NullDispatcher` kommt `forwardDecoratedCallTo` zum Einsatz — es delegiert an das interne Objekt und bewahrt gleichzeitig die Chain der äußeren API.
  </Step>
</Steps>

## Einfache Proxy-Implementierung (`forwardCallTo`)

```php theme={null}
use Illuminate\Support\Traits\ForwardsCalls;

class CourierProxy
{
    use ForwardsCalls;

    public function __construct(
        protected CourierDriver $driver
    ) {}

    public function __call(string $method, array $parameters): mixed
    {
        return $this->forwardCallTo($this->driver, $method, $parameters);
    }
}
```

In dieser Form legt `CourierProxy` die public API des `CourierDriver` transparent offen.

## Method-Chain-fähiger Proxy (`forwardDecoratedCallTo`)

```php theme={null}
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Traits\ForwardsCalls;

class QueryProxy
{
    use ForwardsCalls;

    public function __construct(
        protected Builder $query
    ) {}

    public function __call(string $method, array $parameters): static
    {
        $this->forwardDecoratedCallTo($this->query, $method, $parameters);

        return $this;
    }

    public function get(): \Illuminate\Support\Collection
    {
        return $this->query->get();
    }
}
```

```php theme={null}
$users = (new QueryProxy(User::query()))
    ->where('active', true)
    ->orderByDesc('created_at')
    ->limit(10)
    ->get();
```

<Tip>
  Statt jedes Mal manuell `return $this` zu schreiben, ist es sicherer, die Regel „Wenn der Rückgabewert das Ziel-Objekt selbst ist, durch `$this` ersetzen" von `forwardDecoratedCallTo` zu nutzen.
</Tip>

## Automatisches Werfen einer BadMethodCallException

Wird eine nicht existierende Methode aufgerufen, wirft `ForwardsCalls` eine neue `BadMethodCallException` mit dem aufrufenden Klassennamen.

```php theme={null}
try {
    (new CourierProxy($driver))->missingMethod();
} catch (\BadMethodCallException $e) {
    // Beispiel: Call to undefined method App\Services\CourierProxy::missingMethod()
    report($e);
}
```

So kann der Nutzer sofort erkennen, „an welcher äußeren API der Fehler auftrat".

## Vergleich mit Macroable

| Aspekt                    | `Macroable`                                     | `ForwardsCalls`                               |
| ------------------------- | ----------------------------------------------- | --------------------------------------------- |
| Zweck                     | Neue Methoden an eine bestehende Klasse anfügen | Methoden an ein anderes Objekt delegieren     |
| Haupteinstieg             | `macro()`, `mixin()`                            | `forwardCallTo()`, `forwardDecoratedCallTo()` |
| Geeigneter Anwendungsfall | API-Erweiterung                                 | Proxy / Decorator / Adapter                   |

<Warning>
  Wenn Sie „Methoden ergänzen" wollen und stattdessen `ForwardsCalls` verwenden, schlagen Aufrufe von Methoden, die das Delegationsziel nicht kennt, immer fehl. Wählen Sie für API-Erweiterungen `Macroable`.
</Warning>

## Anwendungsbeispiele in der Paketentwicklung

### 1) Manager, der Treiber umschaltet

```php theme={null}
use Illuminate\Support\Traits\ForwardsCalls;

class SmsManager
{
    use ForwardsCalls;

    public function __construct(
        protected SmsDriver $driver
    ) {}

    public function via(string $name): static
    {
        $this->driver = app(SmsDriverFactory::class)->make($name);

        return $this;
    }

    public function __call(string $method, array $parameters): mixed
    {
        return $this->forwardCallTo($this->driver, $method, $parameters);
    }
}
```

### 2) Adapter mit mehreren Backends

Unterschiedliche Backends wie HTTP, Queue oder WebSocket lassen sich hinter einer einheitlichen API bündeln.

### 3) Spy / Stub für Tests

Statt eines echten Drivers injizieren Sie einen Spy — die Aufrufe werden per `forwardCallTo` unverändert durchgereicht, und Sie können Anzahl sowie Argumente der Aufrufe prüfen.

## Verwandte Seiten

<Columns cols={2}>
  <Card title="Macroable-Trait" icon="puzzle-piece" href="/de/advanced/macroable">
    Lernen Sie das Erweiterungsmuster kennen, um bestehenden Klassen neue Methoden hinzuzufügen.
  </Card>

  <Card title="Conditionable-Trait" icon="git-branch" href="/de/advanced/conditionable">
    Lernen Sie den Entwurf von Bedingungs-Chains mit `when()` / `unless()` kennen.
  </Card>
</Columns>


## Related topics

- [Macroable-Trait](/de/advanced/macroable.md)
- [Datenbank-Seeding](/de/seeding.md)
- [Fluent-Klasse](/de/advanced/fluent.md)
- [Conditionable-Trait](/de/advanced/conditionable.md)
- [Dumpable-Trait](/de/advanced/dumpable.md)
