PHPackages                             paket/kurir - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. paket/kurir

ActiveLibrary

paket/kurir
===========

Minimal event system

0.1(4y ago)04MITPHPPHP &gt;=7.1

Since Sep 12Pushed 4y ago1 watchersCompare

[ Source](https://github.com/paketphp/kurir)[ Packagist](https://packagist.org/packages/paket/kurir)[ Docs](https://github.com/paketphp)[ RSS](/packages/paket-kurir/feed)WikiDiscussions master Synced 5d ago

READMEChangelogDependenciesVersions (2)Used By (0)

Kurir
=====

[](#kurir)

Kurir (*Swedish* courier) is a minimal event system for PHP. With Kurir you can subscribe to custom typed events.

[![](https://github.com/paketphp/kurir/workflows/tests/badge.svg)](https://github.com/paketphp/kurir/workflows/tests/badge.svg)

Usage
-----

[](#usage)

```
final class MyEvent implements Event
{
    private $message;

    public function __construct(string $message)
    {
        $this->message = $message;
    }

    public function getMessage(): string
    {
        return $this->message;
    }
}

$kurir = new Kurir();

$kurir->subscribe(function (MyEvent $event) {
   echo $event->getMessage();
});

$kurir->emit(new MyEvent('Hello, World!'));

```

Installation
------------

[](#installation)

`composer require paket/kurir`

Requirements
------------

[](#requirements)

Requires PHP 7.1 or higher.

General
-------

[](#general)

### Core interfaces

[](#core-interfaces)

Kurir consist of three interfaces, `Event`, `EventSource` and `EventEmitter`, where class `Kurir` implements `EventSource` and `EventEmitter`.

#### Event

[](#event)

```
interface Event
{
}

```

`Event` is the common type of all events, but it doesn't provide any methods, it is up to each event implementation to add the methods or properties that it needs.

#### EventSource

[](#eventsource)

```
interface EventSource
{
    public function subscribe(callable $listener): callable;

    public function unsubscribe(callable $listener): void;
}

```

Listeners can subscribe and unsubscribe to events by using `EventSource`. `subsribe()` returns the same callable that is past as a parameter to it, this helps when unsubscribing.

```
$listener = $eventSource->subscribe(function (MyEvent $event) {
   echo $event->getMessage();
});

$eventSource->unsubscribe($listener);

```

#### EventEmitter

[](#eventemitter)

```
interface EventEmitter
{
   public function emit(Event $event): void;
}

```

Used to emit one event of type `Event` to every subscriber of that event type.

### Example

[](#example)

By separating `EventSource` and `EventEmitter` to two different interfaces you only need to expose one or the other in program code, e.g. lets say we have a repository that saves records and we want to log that.

```
final class InsertedRecordEvent implements Event
{
    private $id;
    private $record;

    public function __construct(int $id, array $record)
    {
        $this->id = $id;
        $this->record = $record;
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function getRecord(): array
    {
        return $this->record;
    }
}

interface Storage
{
    public function insert(string $location, array $record): int;
}

final class RecordRepository
{
    private $storage;
    private $eventEmitter;

    public function __construct(Storage $storage, EventEmitter $eventEmitter)
    {
        $this->storage = $storage;
        $this->eventEmitter = $eventEmitter;
    }

    public function insertRecord(array $record)
    {
        $id = $this->storage->insert('record', $record);
        $this->eventEmitter->emit(new InsertedRecordEvent($id, $record));
    }
}

final class RecordLog
{
    private $eventSource;
    private $listener;

    public function __construct(EventSource $eventSource)
    {
        $this->eventSource = $eventSource;
        $this->listener = $this->eventSource->subscribe(function (InsertedRecordEvent $event) {
            echo "Inserted record {$event->getId()}";
        });
    }

    public function __destruct()
    {
        $this->eventSource->unsubscribe($this->listener);
    }
}

$kurir = new Kurir();
$repository = new RecordRepository($storage, $kurir);
$log = new RecordLog($kurir);
$repository->insertRecord(['action' => 'login', 'user' => 'joe', 'time' => 1631375296]);

```

License
-------

[](#license)

Kurir is released under the MIT License. See the bundled file LICENSE.txt.

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1707d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4140f6d5a37850bd48a8801b6764ed5d096de24b12a3443f33a2c303f1a8bc98?d=identicon)[tored](/maintainers/tored)

---

Top Contributors

[![tored](https://avatars.githubusercontent.com/u/363750?v=4)](https://github.com/tored "tored (7 commits)")

---

Tags

eventphp

### Embed Badge

![Health badge](/badges/paket-kurir/health.svg)

```
[![Health](https://phpackages.com/badges/paket-kurir/health.svg)](https://phpackages.com/packages/paket-kurir)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
