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

# Context

> Leer hoe je de Context-functionaliteit van Laravel gebruikt om informatie te delen tussen requests, jobs en commando's, en automatisch toe te voegen aan logs.

## Wat is Context?

De Context-functionaliteit van Laravel is een mechanisme om informatie vast te leggen en te delen over requests, queue-jobs en commando-uitvoeringen heen.
Wanneer je informatie toevoegt via de `Illuminate\Support\Facades\Context`-facade, wordt die informatie automatisch toegevoegd aan alle logregels die je applicatie wegschrijft.

Hierdoor kun je duidelijk onderscheid maken tussen informatie die je aan individuele log-aanroepen meegeeft en de gedeelde informatie die Context bewaart.
Dit is vooral nuttig voor tracing in gedistribueerde systemen en architecturen met queues.

### Propagatieflow van de context

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Middleware
    participant Controller
    participant Queue
    participant Job

    Client->>Middleware: HTTP-request
    Middleware->>Middleware: Context::add('trace_id', uuid)
    Middleware->>Controller: next($request)
    Controller->>Controller: Log::info(...) — trace_id automatisch toegevoegd
    Controller->>Queue: ProcessPodcast::dispatch()
    Queue->>Job: Context geserialiseerd verzonden
    Job->>Job: Context hersteld (Hydrate)
    Job->>Job: Log::info(...) — trace_id automatisch toegevoegd
```

## Basisgebruik

De meest typische toepassing is het instellen van een `trace_id` in middleware. Die wordt daarna automatisch opgenomen in alle volgende logregels.

<Steps>
  <Step title="Maak een middleware">
    ```shell theme={null}
    php artisan make:middleware AddContext
    ```
  </Step>

  <Step title="Voeg een trace-ID toe aan de Context">
    ```php theme={null}
    <?php

    namespace App\Http\Middleware;

    use Closure;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Context;
    use Illuminate\Support\Str;
    use Symfony\Component\HttpFoundation\Response;

    class AddContext
    {
        public function handle(Request $request, Closure $next): Response
        {
            Context::add('url', $request->url());
            Context::add('trace_id', Str::uuid()->toString());

            return $next($request);
        }
    }
    ```
  </Step>

  <Step title="Registreer de middleware">
    Registreer hem als globale middleware in `bootstrap/app.php`.

    ```php theme={null}
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->append(\App\Http\Middleware\AddContext::class);
    })
    ```
  </Step>
</Steps>

Na deze configuratie worden `url` en `trace_id` automatisch toegevoegd aan logs die je in controllers of services wegschrijft.

```php theme={null}
Log::info('User authenticated.', ['auth_id' => Auth::id()]);
```

```text theme={null}
User authenticated. {"auth_id":27} {"url":"https://example.com/login","trace_id":"e04e1a11-e75c-4db3-b5b5-cfef4ef56697"}
```

## Schrijven naar de context

### add — een waarde toevoegen

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

Context::add('key', 'value');

// Meerdere waarden tegelijk toevoegen
Context::add([
    'first_key'  => 'value',
    'second_key' => 'value',
]);
```

`add` overschrijft bestaande sleutels. Wil je alleen toevoegen als de sleutel nog niet bestaat, gebruik dan `addIf`.

```php theme={null}
Context::add('key', 'first');
Context::addIf('key', 'second');

Context::get('key');
// "first" — wordt niet overschreven
```

### increment / decrement — tellers beheren

Speciale methoden om numerieke waarden te verhogen of te verlagen. Met het tweede argument geef je de stapgrootte op.

```php theme={null}
Context::increment('records_added');
Context::increment('records_added', 5);

Context::decrement('records_added');
Context::decrement('records_added', 5);
```

### when — voorwaardelijk toevoegen

Met de `when`-methode kun je verschillende data toevoegen afhankelijk van of de voorwaarde `true` of `false` is.

```php theme={null}
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Context;

Context::when(
    Auth::user()->isAdmin(),
    fn ($context) => $context->add('permissions', Auth::user()->permissions),
    fn ($context) => $context->add('permissions', []),
);
```

### push — toevoegen aan een stack

Context ondersteunt "stacks" die data in lijstvorm bewaren.
Met `push` stapelt de data zich op in de volgorde waarin je hem toevoegt.

```php theme={null}
Context::push('breadcrumbs', 'first_value');
Context::push('breadcrumbs', 'second_value', 'third_value');

Context::get('breadcrumbs');
// ['first_value', 'second_value', 'third_value']
```

Een voorbeeld waarin de uitvoeringsgeschiedenis van queries op een stack wordt bijgehouden:

```php theme={null}
use Illuminate\Support\Facades\Context;
use Illuminate\Support\Facades\DB;

// Registreren in de boot-methode van AppServiceProvider.php
DB::listen(function ($event) {
    Context::push('queries', [$event->time, $event->sql]);
});
```

## De context ophalen

### get / all

```php theme={null}
$value = Context::get('key');

// Alles ophalen
$data = Context::all();
```

### only / except — slechts een deel ophalen

```php theme={null}
$data = Context::only(['first_key', 'second_key']);

$data = Context::except(['first_key']);
```

### pull / pop — ophalen en verwijderen

`pull` haalt de waarde van een sleutel op en verwijdert die tegelijkertijd uit de context.

```php theme={null}
$value = Context::pull('key');
```

Gebruik `pop` om de laatste waarde van een stack te halen.

```php theme={null}
Context::push('breadcrumbs', 'first_value', 'second_value');

Context::pop('breadcrumbs');
// 'second_value'

Context::get('breadcrumbs');
// ['first_value']
```

### remember — instellen en teruggeven als de sleutel niet bestaat

```php theme={null}
$permissions = Context::remember(
    'user-permissions',
    fn () => $user->permissions,
);
```

### has / missing — controleren of een sleutel bestaat

```php theme={null}
if (Context::has('key')) {
    // ...
}

if (Context::missing('key')) {
    // ...
}
```

<Info>
  `has` geeft `true` terug, zelfs als er `null` is opgeslagen. Het controleert alleen of de sleutel geregistreerd is.
</Info>

## Context verwijderen

Verwijder een sleutel met `forget`.

```php theme={null}
Context::add(['first_key' => 1, 'second_key' => 2]);

Context::forget('first_key');

Context::all();
// ['second_key' => 2]

// Meerdere sleutels tegelijk verwijderen
Context::forget(['first_key', 'second_key']);
```

## Context met scope

Met de `scope`-methode kun je de context tijdelijk wijzigen tijdens de uitvoering van een closure; daarna wordt automatisch de oorspronkelijke toestand hersteld.
Dit is handig in tests of lokale bewerkingen waarbij je tijdelijk extra informatie in logs wilt opnemen.

```php theme={null}
use Illuminate\Support\Facades\Context;
use Illuminate\Support\Facades\Log;

Context::add('trace_id', 'abc-999');
Context::addHidden('user_id', 123);

Context::scope(
    function () {
        Context::add('action', 'adding_friend');

        $userId = Context::getHidden('user_id');

        Log::debug("Adding user [{$userId}] to friends list.");
        // Adding user [987] to friends list.  {"trace_id":"abc-999","user_name":"taylor_otwell","action":"adding_friend"}
    },
    data: ['user_name' => 'taylor_otwell'],
    hidden: ['user_id' => 987],
);

// Na afloop van de scope zijn de oorspronkelijke waarden hersteld
Context::all();
// ['trace_id' => 'abc-999']

Context::allHidden();
// ['user_id' => 123]
```

<Warning>
  Als je binnen de scope een object wijzigt, is die wijziging ook buiten de scope zichtbaar. Bij primitieve waarden is er geen probleem.
</Warning>

## Hidden context

Data die je niet in logs wilt laten verschijnen (wachtwoorden, API-sleutels, persoonsgegevens, enz.) sla je op in de hidden context.
Deze data is niet op te halen met de gewone `get`-methode; je kunt er alleen bij via speciale methoden zoals `getHidden`.

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

Context::addHidden('key', 'value');

Context::getHidden('key');
// 'value'

Context::get('key');
// null — niet op te halen met de gewone get
```

De hidden context heeft dezelfde set methoden als de gewone context.

```php theme={null}
Context::addHidden(/* ... */);
Context::addHiddenIf(/* ... */);
Context::pushHidden(/* ... */);
Context::getHidden(/* ... */);
Context::pullHidden(/* ... */);
Context::popHidden(/* ... */);
Context::onlyHidden(/* ... */);
Context::exceptHidden(/* ... */);
Context::allHidden(/* ... */);
Context::hasHidden(/* ... */);
Context::missingHidden(/* ... */);
Context::forgetHidden(/* ... */);
```

## Doorgeven aan queue-jobs

Wanneer je een job naar de queue dispatcht, wordt de huidige context automatisch geserialiseerd en opgenomen in de payload van de job.
Bij het uitvoeren van de job wordt de oorspronkelijke context hersteld, zodat de `trace_id` die je bij het request hebt toegevoegd automatisch wordt doorgegeven aan de logs op de queue.

```php theme={null}
// Instellen in middleware
Context::add('trace_id', Str::uuid()->toString());

// De job dispatchen in een controller
ProcessPodcast::dispatch($podcast);
```

```php theme={null}
class ProcessPodcast implements ShouldQueue
{
    use Queueable;

    public function handle(): void
    {
        Log::info('Processing podcast.', ['podcast_id' => $this->podcast->id]);
    }
}
```

```text theme={null}
Processing podcast. {"podcast_id":95} {"url":"https://example.com/login","trace_id":"e04e1a11-e75c-4db3-b5b5-cfef4ef56697"}
```

Je ziet dat de `trace_id` van het request ook in de logs op de queue is opgenomen.

### Dehydrating — aanpassen bij het verzenden van een job

Met `Context::dehydrating` kun je de context bewerken vlak voordat de job wordt verzonden.
Dit gebruik je bijvoorbeeld als je de locale, bepaald door de `Accept-Language`-header, aan de queue wilt doorgeven.

```php theme={null}
// AppServiceProvider.php

use Illuminate\Log\Context\Repository;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Context;

public function boot(): void
{
    Context::dehydrating(function (Repository $context) {
        $context->addHidden('locale', Config::get('app.locale'));
    });
}
```

<Warning>
  Gebruik binnen de `dehydrating`-callback niet de `Context`-facade, maar werk alleen met de `$context`-repository die aan de callback wordt doorgegeven.
  Als je de facade gebruikt, wijzig je de context van het huidige proces.
</Warning>

### Hydrated — herstellen bij het uitvoeren van een job

Met `Context::hydrated` kun je logica toevoegen op het moment dat de context wordt hersteld, vlak voordat de job wordt uitgevoerd.
Bijvoorbeeld om de opgeslagen locale weer in de configuratie te zetten:

```php theme={null}
// AppServiceProvider.php

use Illuminate\Log\Context\Repository;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Context;

public function boot(): void
{
    Context::hydrated(function (Repository $context) {
        if ($context->hasHidden('locale')) {
            Config::set('app.locale', $context->getHidden('locale'));
        }
    });
}
```

<Warning>
  Gebruik ook binnen de `hydrated`-callback niet de `Context`-facade, maar werk alleen met de doorgegeven `$context`-repository.
</Warning>

## Samenvatting

<AccordionGroup>
  <Accordion title="Het verschil tussen Context en Log::withContext">
    |                          | `Context`                         | `Log::withContext`        |
    | ------------------------ | --------------------------------- | ------------------------- |
    | Bereik                   | Alle logkanalen                   | Alleen specifieke kanalen |
    | Doorgeven aan queue-jobs | Automatisch (Dehydrate/Hydrate)   | Nee                       |
    | Hidden data              | Ondersteund                       | Nee                       |
    | Toepassing               | Tracing, gedistribueerde systemen | Kanaalspecifieke metadata |
  </Accordion>

  <Accordion title="Data die je in de hidden context zou moeten opslaan">
    Omdat de hidden context niet in logs verschijnt, kun je hier veilig de volgende soorten data opslaan:

    * Sessie-ID's en gebruikers-ID's (als je die niet in logs wilt)
    * API-sleutels en authenticatietokens
    * Locale en configuratiewaarden (die je wilt doorgeven aan de queue, maar niet in logs nodig hebt)
    * Interne vlaggen en statussen
  </Accordion>

  <Accordion title="Veelvoorkomende patronen voor Dehydrate/Hydrate">
    1. **Locale doorgeven**: sla `app.locale` op in de hidden context met `dehydrating` en herstel hem met `Config::set` in `hydrated`.
    2. **Authenticatiegegevens propageren**: zorg dat gegevens van de geauthenticeerde gebruiker uit het request ook beschikbaar zijn in queue-jobs.
    3. **Tenant-ID**: deel de tenant-identifier over de queue heen in multi-tenant-applicaties.
  </Accordion>
</AccordionGroup>


## Related topics

- [Logging](/nl/logging.md)
- [Sessioncontext en filtering](/nl/packages/laravel-copilot-sdk/session-context.md)
- [Foutafhandeling](/nl/error-handling.md)
- [Telemetry](/nl/packages/laravel-copilot-sdk/telemetry.md)
- [Streaming events](/nl/packages/laravel-copilot-sdk/streaming-events.md)
