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

> Leer hoe je met Illuminate\Support\Traits\ForwardsCalls veilig method forwarding implementeert voor proxy- en decoratorklassen.

## Wat is de ForwardsCalls-trait

`Illuminate\Support\Traits\ForwardsCalls` is een trait die het delegeren van methodes naar een ander object standaardiseert. In Laravel zelf wordt hij gebruikt in "wrapper-objecten" zoals Eloquent en Mail.

<Info>
  De implementatie staat in `src/Illuminate/Support/Traits/ForwardsCalls.php`. Als je een niet-bestaande methode doorstuurt, wordt de fout opnieuw gegooid als een `BadMethodCallException` met de naam van de aanroepende klasse erin.
</Info>

```mermaid theme={null}
flowchart LR
  A["Jouw Proxy-klasse"] -->|__call| B["forwardCallTo()"]
  B --> C["Interne Driver / Builder"]
  C --> D["Resultaat teruggeven"]
  D --> A
```

## Kern-API

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

Stuurt een methode ongewijzigd door naar het opgegeven object. Meestal roep je dit aan vanuit `__call()`.

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

Gebruik je wanneer je in een Builder of Decorator de chain wilt behouden. Als de doorgestuurde methode "het doelobject zelf" teruggeeft, wordt dit vervangen door "het aanroepende object (`$this`)".

### Combineren met `__call()` / `__callStatic()`

`ForwardsCalls` levert zelf geen magic methods. Je implementeert in je eigen klasse `__call()` (en zo nodig `__callStatic()`) en roept daarbinnen de `forwardCallTo`-methodes aan.

## Praktijkvoorbeelden (binnen Laravel)

<Steps>
  <Step title="Facades bieden een static proxy">
    `Illuminate\Support\Facades\Facade` delegeert via `__callStatic()` rechtstreeks naar de root instance. Omdat facades statische aanroepen zijn, gebruikt de implementatie directe forwarding in plaats van `ForwardsCalls`.
  </Step>

  <Step title="De Eloquent Builder gebruikt forwardCallTo">
    `Illuminate\Database\Eloquent\Builder::__call()` geeft onopgeloste methodes met `forwardCallTo($this->query, ...)` door aan de interne Query Builder en geeft daarna `$this` terug om de fluent chain te behouden.
  </Step>

  <Step title="Relation / Mail / Event gebruiken forwardDecoratedCallTo">
    In `Illuminate\Database\Eloquent\Relations\Relation`, `Illuminate\Mail\Message` en `Illuminate\Events\NullDispatcher` wordt `forwardDecoratedCallTo` gebruikt: er wordt gedelegeerd naar het interne object, terwijl de chain van de buitenste API behouden blijft.
  </Step>
</Steps>

## Basisimplementatie van een proxy (`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 deze vorm kan `CourierProxy` de publieke API van `CourierDriver` transparant blootstellen.

## Proxy met method chaining (`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>
  In plaats van handmatig `return $this` te schrijven, is het veiliger om te vertrouwen op de regel van `forwardDecoratedCallTo`: "als de returnwaarde het doelobject zelf is, vervang die dan door `$this`".
</Tip>

## Automatisch gooien van BadMethodCallException

Als je een niet-bestaande methode aanroept, gooit `ForwardsCalls` een `BadMethodCallException` opnieuw met de naam van de aanroepende klasse.

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

Zo kan de gebruiker meteen achterhalen "in welke buitenste API het misging".

## Vergelijking met Macroable

| Aspect               | `Macroable`                                        | `ForwardsCalls`                               |
| -------------------- | -------------------------------------------------- | --------------------------------------------- |
| Doel                 | Nieuwe methodes toevoegen aan een bestaande klasse | Methodes delegeren naar een ander object      |
| Belangrijkste ingang | `macro()`, `mixin()`                               | `forwardCallTo()`, `forwardDecoratedCallTo()` |
| Geschikt voor        | API-uitbreiding                                    | Proxy / Decorator / Adapter                   |

<Warning>
  Als je `ForwardsCalls` gebruikt terwijl je eigenlijk "methodes wilt toevoegen", zullen methodes die het doelobject niet heeft altijd falen. Kies `Macroable` als API-uitbreiding je doel is.
</Warning>

## Toepassingen in pakketontwikkeling

### 1) Een Manager die van driver wisselt

```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) Een Adapter met meerdere backends

Verschillende backends zoals HTTP, Queue of WebSocket kun je onder één API verenigen en de aanroepen delegeren.

### 3) Spy / Stub voor tests

Je kunt een Spy injecteren in plaats van de echte driver, de aanroepen via `forwardCallTo` gewoon laten doorstromen en vervolgens het aantal aanroepen en de argumenten verifiëren.

## Gerelateerde pagina's

<Columns cols={2}>
  <Card title="Macroable-trait" icon="puzzle-piece" href="/nl/advanced/macroable">
    Leer het uitbreidingspatroon waarmee je nieuwe methodes toevoegt aan bestaande klassen.
  </Card>

  <Card title="Conditionable-trait" icon="git-branch" href="/nl/advanced/conditionable">
    Leer hoe je voorwaardelijke chains ontwerpt met `when()` / `unless()`.
  </Card>
</Columns>


## Related topics

- [Macroable-trait](/nl/advanced/macroable.md)
- [Laravel-updates van augustus 2026](/nl/blog/changelog/202608.md)
- [Database seeding](/nl/seeding.md)
- [Queues en jobs](/nl/queues.md)
- [Fluent-klasse](/nl/advanced/fluent.md)
