Skip to content

Instantly share code, notes, and snippets.

@enxas
Created February 2, 2025 12:59
Show Gist options
  • Select an option

  • Save enxas/d439384b8ce44a7cadc77313dd5af7dc to your computer and use it in GitHub Desktop.

Select an option

Save enxas/d439384b8ce44a7cadc77313dd5af7dc to your computer and use it in GitHub Desktop.
A plain PHP reimplementation of Laravel's higher-order messages.
<?php
class Participant
{
public function __construct(private int $teamNumber, public int $score = 0) {}
public function belongsToTeam(int $teamNumber): bool
{
return $this->teamNumber === $teamNumber;
}
}
class HigherOrderCollectionProxy
{
public function __construct(private $collection, private string $collMethod) {}
public function __call(string $method, array $parameters)
{
return $this->collection->{$this->collMethod}(fn($value) => $value->{$method}(...$parameters));
}
public function __get(string $key)
{
return $this->collection->{$this->collMethod}(fn($value) => $value->{$key});
}
}
class MyCollection
{
public function __construct(private array $items = []) {}
public function __get(string $key)
{
return new HigherOrderCollectionProxy($this, $key);
}
public function filter(callable $callback): static
{
return new static(array_filter($this->items, $callback));
}
public function sum(callable $callback): int|float
{
return array_reduce($this->items, fn($result, $item) => $result + $callback($item), 0);
}
}
$participants = new MyCollection([
new Participant(teamNumber: 1, score: 11),
new Participant(teamNumber: 1, score: 6),
new Participant(teamNumber: 2, score: 5),
new Participant(teamNumber: 2, score: 8),
new Participant(teamNumber: 2, score: 7),
new Participant(teamNumber: 3, score: 20),
]);
$team2Participants = $participants->filter(fn($participant) => $participant->belongsToTeam(2));
$totalScore = $team2Participants->sum(fn($participant) => $participant->score);
// chaining
$totalScore = $participants
->filter(fn($participant) => $participant->belongsToTeam(2))
->sum(fn($participant) => $participant->score);
// Higher Order Messages
$team2Participants = $participants->filter->belongsToTeam(2);
$totalScore = $team2Participants->sum->score;
// chaining
$currentYearAmount = $participants->filter->belongsToTeam(2)->sum->score;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment