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

# Higher-Order Messages in Collections

> Funktionsweise und praktischer Einsatz der Higher-Order Messages von Collections.

## Was sind Higher-Order Messages?

Higher-Order Messages sind eine Syntax, mit der Sie Collection-Methoden wie einen Property-Zugriff aufrufen. Ohne einen Callback zu schreiben, können Sie für jedes Element eine Methode aufrufen oder eine Property abfragen.

```php theme={null}
// Klassische Schreibweise
$names = $users->map(fn ($user) => $user->name);

// Schreibweise mit Higher-Order Message
$names = $users->map->name;
```

`$users->map->name` bedeutet „aus jedem Nutzer die Property `name` entnehmen und mit `map` verarbeiten".

## Funktionsweise — HigherOrderCollectionProxy

Wenn Sie wie in `$collection->map` als Property zugreifen, wird `__get()` des Traits `EnumeratesValues` aufgerufen.

```php theme={null}
// src/Illuminate/Collections/Traits/EnumeratesValues.php
public function __get($key)
{
    if (! in_array($key, static::$proxies)) {
        throw new Exception("Property [{$key}] does not exist on this collection instance.");
    }

    return new HigherOrderCollectionProxy($this, $key);
}
```

Ist der Methodenname in `$proxies` enthalten, wird eine Instanz von `HigherOrderCollectionProxy` zurückgegeben. Dieser Proxy hält die Collection und den Methodennamen fest.

### Property-Zugriff über \_\_get proxieren

Greifen Sie danach auf eine Property zu (`->name`), wird `__get()` des Proxys aufgerufen.

```php theme={null}
// src/Illuminate/Collections/HigherOrderCollectionProxy.php
public function __get($key)
{
    return $this->collection->{$this->method}(function ($value) use ($key) {
        return is_array($value) ? $value[$key] : $value->{$key};
    });
}
```

Damit ist `$users->map->name` äquivalent zu:

```php theme={null}
$users->map(fn ($user) => $user->name);
```

### Methodenaufruf über \_\_call proxieren

Rufen Sie im Anschluss eine Methode auf (`->activate()`), wird `__call()` des Proxys ausgeführt.

```php theme={null}
public function __call($method, $parameters)
{
    return $this->collection->{$this->method}(function ($value) use ($method, $parameters) {
        return is_string($value)
            ? $value::{$method}(...$parameters)
            : $value->{$method}(...$parameters);
    });
}
```

`$users->each->activate()` entspricht:

```php theme={null}
$users->each(fn ($user) => $user->activate());
```

## Liste unterstützter Methoden

Welche Methoden als Higher-Order Message verwendbar sind, definiert das Array `$proxies`.

```php theme={null}
protected static $proxies = [
    'average', 'avg',
    'contains', 'doesntContain', 'some',
    'each', 'every',
    'filter', 'reject',
    'first', 'last',
    'flatMap', 'map',
    'groupBy', 'keyBy',
    'hasMany', 'hasSole',
    'max', 'min', 'sum', 'percentage',
    'partition',
    'skipUntil', 'skipWhile',
    'sortBy', 'sortByDesc',
    'takeUntil', 'takeWhile',
    'unique',
    'unless', 'until', 'when',
];
```

Eigene Methoden fügen Sie über `Collection::proxy()` hinzu.

```php theme={null}
Collection::proxy('myCustomMethod');
```

## Praktische Anwendungsfälle

### Collections von Eloquent-Modellen

Higher-Order Messages sind bei Eloquent-Collections besonders praktisch.

```php theme={null}
$users = User::with('posts')->get();

// Methodenaufruf: Status jedes Nutzers aktualisieren
$users->each->markAsVerified();

// Property-Zugriff: nur Namen entnehmen
$names = $users->map->name;

// Argument an die Methode übergeben
$users->each->sendPasswordReset('ja');

// E-Mails versenden
$users->each->notify(new WelcomeNotification);
```

### Filtern

```php theme={null}
$activeUsers = $users->filter->isActive();

// behält nur Nutzer, deren isActive() true liefert
// äquivalent zu $users->filter(fn ($user) => $user->isActive())

$inactiveUsers = $users->reject->isActive();
```

### Aggregation

```php theme={null}
// Summe über die Property post_count jedes Nutzers
$totalPosts = $users->sum->post_count;

// Maximum der Property score jedes Nutzers
$highestScore = $users->max->score;

// Durchschnitt der Property age jedes Nutzers
$averageAge = $users->avg->age;
```

### Gruppieren und sortieren

```php theme={null}
// Nach der Property role gruppieren
$grouped = $users->groupBy->role;

// Aufsteigend nach der Property name sortieren
$sorted = $users->sortBy->name;

// Absteigend nach der Property created_at sortieren
$sorted = $users->sortByDesc->created_at;
```

### Mit flatMap verschachtelte Strukturen entpacken

```php theme={null}
// Die posts-Beziehung jedes Nutzers zu einer einzigen Collection zusammenführen
$posts = $users->flatMap->posts;
```

### Bedingungen prüfen

```php theme={null}
// Sind alle Administratoren?
$allAdmins = $users->every->isAdmin();

// Gibt es mindestens einen aktiven Nutzer?
$hasActive = $users->contains->isActive();

// Haben alle einen bestimmten Plan?
$allPro = $users->every->hasPlan('pro');
```

### Collections aus Strings

Auch bei Collections aus Strings können Sie sie nutzen. Der `__call()`-Proxy ruft die Methode bei Strings als statische Methode auf.

```php theme={null}
$names = collect(['alice', 'bob', 'charlie']);

// Bei String-Collections ist eine Closure explizit
$upper = $names->map(fn ($name) => strtoupper($name));
// ['ALICE', 'BOB', 'CHARLIE']
```

<Info>
  Für Higher-Order Messages auf String-Collections muss die Methode statisch für den String-Typ definiert sein. Natürlicher ist der Einsatz bei Collections von Eloquent-Modellen oder eigenen Klassen.
</Info>

## Vergleich mit klassischen Closures

Higher-Order Messages sind kompakt, decken aber nicht jede Situation ab.

```php theme={null}
// Higher-Order Message: gut für schlichte Property-Abfragen oder Methodenaufrufe
$emails = $users->map->email;
$users->each->sendWelcomeMail();
$admins = $users->filter->isAdmin();

// Closure: passend bei komplexer Logik oder Argumenten
$formatted = $users->map(function ($user) {
    return "{$user->name} <{$user->email}>";
});

$filtered = $users->filter(function ($user) use ($minAge, $role) {
    return $user->age >= $minAge && $user->role === $role;
});
```

<Tip>
  Wenn Sie „die gleiche Property aus jedem Element ziehen" oder „die gleiche Methode auf jedem Element aufrufen", ist eine Higher-Order Message besser lesbar. Bei komplexen Bedingungen oder dynamischen Argumenten greifen Sie zur Closure.
</Tip>

## Higher-Order Messages in eigenen Klassen einsetzen

Um den Mechanismus von `HigherOrderCollectionProxy` über den Trait `EnumeratesValues` zu nutzen, registrieren Sie Methoden per `Collection::proxy()` als Proxy-Ziele.

```php theme={null}
namespace App\Providers;

use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        // Eigenes Macro als Proxy-Ziel registrieren
        Collection::macro('active', function () {
            return $this->filter(fn ($item) => $item->isActive());
        });

        Collection::proxy('active');
    }
}
```

```php theme={null}
// Nach der Registrierung als Higher-Order Message verwendbar
$activeUsers = $users->active;
```

## Nächste Schritte

<Card title="Conditionable-Trait" icon="git-branch" href="/de/advanced/conditionable">
  Lernen Sie die interne Implementierung von `when()` / `unless()` und deren Einsatz im QueryBuilder oder in eigenen Klassen.
</Card>


## Related topics

- [Collection Deep Dive](/de/advanced/collection-deep-dive.md)
- [Conditionable-Trait](/de/advanced/conditionable.md)
- [Collections](/de/collections.md)
- [tap()-Helper und Tappable-Trait](/de/advanced/tap.md)
- [Eloquent-Collections](/de/eloquent-collections.md)
