PHPackages                             tobento/app-event - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. tobento/app-event

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

tobento/app-event
=================

App event support.

2.0(7mo ago)0111↓33.3%15MITPHPPHP &gt;=8.4

Since Jul 14Pushed 7mo ago1 watchersCompare

[ Source](https://github.com/tobento-ch/app-event)[ Packagist](https://packagist.org/packages/tobento/app-event)[ Docs](https://www.tobento.ch)[ RSS](/packages/tobento-app-event/feed)WikiDiscussions 2.x Synced 1mo ago

READMEChangelog (4)Dependencies (8)Versions (6)Used By (15)

App Event
=========

[](#app-event)

Event support for the app using the [**Event Service**](https://github.com/tobento-ch/service-event).

Table of Contents
-----------------

[](#table-of-contents)

- [Getting Started](#getting-started)
    - [Requirements](#requirements)
- [Documentation](#documentation)
    - [App](#app)
    - [Event Boot](#event-boot)
        - [Event Config](#event-config)
        - [Available Event Interfaces](#available-event-interfaces)
        - [Default Events](#default-events)
            - [Create Event](#create-event)
            - [Create Listener](#create-listener)
            - [Add Listeners](#add-listeners)
            - [Dispatch Event](#dispatch-event)
        - [Specific Events](#specific-events)
            - [Create Events](#create-events)
            - [Add Specific Listeners](#add-specific-listeners)
            - [Use Events](#use-events)
- [Credits](#credits)

---

Getting Started
===============

[](#getting-started)

Add the latest version of the app event project running this command.

```
composer require tobento/app-event

```

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

[](#requirements)

- PHP 8.4 or greater

Documentation
=============

[](#documentation)

App
---

[](#app)

Check out the [**App Skeleton**](https://github.com/tobento-ch/app-skeleton) if you are using the skeleton.

You may also check out the [**App**](https://github.com/tobento-ch/app) to learn more about the app in general.

Event Boot
----------

[](#event-boot)

The event boot does the following:

- installs and loads event config file
- implements event interfaces
- adds event listeners from config file

```
use Tobento\App\AppFactory;

// Create the app
$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots
$app->boot(\Tobento\App\Event\Boot\Event::class);

// Run the app
$app->run();
```

### Event Config

[](#event-config)

The configuration for the event is located in the `app/config/event.php` file at the default App Skeleton config location.

### Available Event Interfaces

[](#available-event-interfaces)

The following interfaces are available after booting:

```
use Tobento\App\AppFactory;
use Tobento\Service\Event\ListenersInterface;
use Tobento\Service\Event\EventsFactoryInterface;
use Tobento\Service\Event\EventsInterface;
use Psr\EventDispatcher\EventDispatcherInterface;

// Create the app
$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots
$app->boot(\Tobento\App\Event\Boot\Event::class);
$app->booting();

$listeners = $app->get(ListenersInterface::class);
// is declared as prototype, meaning returning always a new instance!

$eventsFactory = $app->get(EventsFactoryInterface::class);
$events = $app->get(EventsInterface::class);
$eventDispatcher = $app->get(EventDispatcherInterface::class);

// var_dump($events === $eventDispatcher);
// bool(true)

// Run the app
$app->run();
```

Check out the [**Event Service**](https://github.com/tobento-ch/service-event#events) to learn more about the interfaces.

### Default Events

[](#default-events)

You can access the default events by using the `Tobento\Service\Event\EventsInterface::class` from within the app or by autowiring.

Furthermore, the events are used as the default `Psr\EventDispatcher\EventDispatcherInterface::class` implementation.

#### Create Event

[](#create-event)

```
namespace App\Event;

use App\Entity\User;

final class UserRegistered
{
    public function __construct(
        public readonly User $user
    ) {}
}
```

#### Create Listener

[](#create-listener)

```
namespace App\Listener;

class SendWelcomeMail
{
    public function __invoke(UserRegistered $event): void
    {
        // send welcome mail.
    }
}
```

Check out the [**Defining Listeners**](https://github.com/tobento-ch/service-event#defining-and-add-listener) section to learn more about it.

#### Add Listeners

[](#add-listeners)

You can add listeners by the following ways:

**Using event config**

You may define the listener in the `app/config/event.php` file:

```
use Tobento\App\Event\ListenerRegistry;
use App\Event;
use App\Listener;

return [

    /*
    |--------------------------------------------------------------------------
    | Default Event Listeners
    |--------------------------------------------------------------------------
    |
    | Define the event listeners for the default events.
    |
    | As the events class uses reflection to scan listeners for its events named $event,
    | there is no need to define its event(s) for a listener.
    | But you might do so if you have multiple events in your listener and
    | want only to listen for the specific events or just because of better overview.
    |
    */

    'listeners' => [
        // Specify events to listeners:
        Event\UserRegistered::class => [
            Listener\SendWelcomeMail::class,

            // with build-in parameters:
            [Listener::class, ['number' => 5]],

            // with specific priority:
            new ListenerRegistry(
                listener: Listener::class,
                priority: 1,
            ),
        ],

        // Specify listeners without event:
        'auto' => [
            Listener\SendWelcomeMail::class,

            // with build-in parameters:
            [Listener::class, ['number' => 5]],

            // with specific priority:
            new ListenerRegistry(
                listener: Listener::class,
                priority: 1,
            ),
        ],
    ],

    // ...
];
```

**Manually using events**

You can add listeners manually by using the `EventsInterface::class`.

```
use Tobento\App\AppFactory;
use Tobento\Service\Event\EventsInterface;

// Create the app
$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots
$app->boot(\Tobento\App\Event\Boot\Event::class);
$app->booting();

$events = $app->get(EventsInterface::class);

// Add listeners
$events->listen(FooListener::class);

$events->listen(AnyListener::class)
       ->event(FooEvent::class)
       ->priority(2000);

// Run the app
$app->run();
```

Check out the [**Add Listeners**](https://github.com/tobento-ch/service-event#add-listeners) to learn more about adding listeners.

#### Dispatch Event

[](#dispatch-event)

You can dispatch events by the following ways:

**Using the event dispatcher**

The `EventDispatcherInterface::class` uses the default events as dispatcher implementation.

```
namespace App\Service;

use Psr\EventDispatcher\EventDispatcherInterface;
use App\Event\UserRegistered;
use App\Entity\User;

final class UserService
{
    public function __construct(
        private readonly EventDispatcherInterface $dispatcher
    ) {}

    public function register(User $user): void
    {
        // ...

        $this->dispatcher->dispatch(new UserRegistered($user));
    }
}
```

**Using the events**

```
namespace App\Service;

use Tobento\Service\Event\EventsInterface;
use App\Event\UserRegistered;
use App\Entity\User;

final class UserService
{
    public function __construct(
        private readonly EventsInterface $dispatcher
    ) {}

    public function register(User $user): void
    {
        // ...

        $this->dispatcher->dispatch(new UserRegistered($user));
    }
}
```

### Specific Events

[](#specific-events)

You may create specific events for certain services, components or bundles.

#### Create Events

[](#create-events)

To create specific events simply extend the `Events::class`:

```
use Tobento\Service\Event\Events;

final class ShopEvents extends Events
{
    //
}
```

The `ShopEvents::class` will be autowired while using the app!

#### Add Specific Listeners

[](#add-specific-listeners)

You can add listeners for your specific events by the following ways:

**Using event config**

You may define the listener in the `app/config/event.php` file:

```
use Tobento\App\Event\ListenerRegistry;

return [
    // ...

    /*
    |--------------------------------------------------------------------------
    | Specific Events Listeners
    |--------------------------------------------------------------------------
    |
    | Define the event listeners for the specific events.
    |
    | As the events class uses reflection to scan listeners for its events named $event,
    | there is no need to define its event(s) for a listener.
    | But you might do so if you have multiple events in your listener and
    | want only to listen for the specific events or just because of better overview.
    |
    */

    'events' => [
        ShopEvents::class => [
            // Specify events to listeners:
            SomeEvent::class => [
                Listener::class,

                // with build-in parameters:
                [Listener::class, ['number' => 5]],
            ],

            // Specify listeners without event:
            'auto' => [
                Listener::class,

                // with build-in parameters:
                [Listener::class, ['number' => 5]],

                // to define specific priority:
                new ListenerRegistry(
                    listener: Listener::class,
                    priority: 1,
                ),
            ],
        ],
    ],

    // ...
];
```

**Manually using events**

You can add listeners manually by using the `ShopEvents::class`.

```
use Tobento\App\AppFactory;

// Create the app
$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots
$app->boot(\Tobento\App\Event\Boot\Event::class);
$app->booting();

$events = $app->get(ShopEvents::class);

// Add listeners
$events->listen(FooListener::class);

$events->listen(AnyListener::class)
       ->event(FooEvent::class)
       ->priority(2000);

// Run the app
$app->run();
```

Check out the [**Add Listeners**](https://github.com/tobento-ch/service-event#add-listeners) to learn more about adding listeners.

**Using the app `on` method**

You can add listeners by using the app `on` method.

```
use Tobento\App\AppFactory;
use Tobento\App\Event\ConfigEventsRegistry;

// Create the app
$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots
$app->boot(\Tobento\App\Event\Boot\Event::class);
$app->booting();

$app->on(ShopEvents::class, function(ShopEvents $shopEvents) {
    // Add listeners
    $shopEvents->listen(FooListener::class);

    // Or add listeners from config:
    new ConfigEventsRegistry(priority: 1000)->addListenersFromArray(
        events: $shopEvents,

        // using same definition as config listeners.
        eventListeners: [
            SomeEvent::class => [
                Listener::class,

                // with build-in parameters:
                [Listener::class, ['number' => 5]],

                // ...
            ],
        ],
    );
});

// Run the app
$app->run();
```

Check out the [**Add Listeners**](https://github.com/tobento-ch/service-event#add-listeners) to learn more about adding listeners.

#### Use Events

[](#use-events)

After setting up your specific events, you can use it in your service.

```
namespace App\Service;

use Psr\EventDispatcher\EventDispatcherInterface;

final class ShopService
{
    public function __construct(
        private readonly EventDispatcherInterface $dispatcher
    ) {}
}

// or:
final class AnotherShopService
{
    public function __construct(
        private readonly ShopEvents $dispatcher
    ) {}
}
```

There are several ways to inject your events into your `ShopService::class`:

```
// using a closure:
$app->set(ShopService::class, function() {
    return new ShopService(
        dispatcher: $app->get(ShopEvents::class),
    );
});

// using the construct method:
$app->set(ShopService::class)->construct($app->get(ShopEvents::class));

// using the on method:
$app->on(ShopService::class, ['dispatcher' => ShopEvents::class]);
```

The `AnotherShopService::class` requires no action for injection as `ShopEvents::class` is defined as dispatcher which gets autowired.

You may check out the [**App Definitions**](https://github.com/tobento-ch/app#definitions) and the [**App On**](https://github.com/tobento-ch/app#on) method for more information.

Credits
=======

[](#credits)

- [Tobias Strub](https://www.tobento.ch)
- [All Contributors](../../contributors)

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance63

Regular maintenance activity

Popularity12

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity65

Established project with proven stability

 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

Every ~162 days

Recently: every ~193 days

Total

6

Last Release

224d ago

Major Versions

1.x-dev → 2.02025-10-02

PHP version history (2 changes)1.0.0PHP &gt;=8.0

2.0PHP &gt;=8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/055d6a1b5c2384bb179c75ab0b55914231d898fdc4dffeb30770f81200e52206?d=identicon)[TOBENTOch](/maintainers/TOBENTOch)

---

Top Contributors

[![tobento-ch](https://avatars.githubusercontent.com/u/16684832?v=4)](https://github.com/tobento-ch "tobento-ch (7 commits)")

---

Tags

eventpackageapptobento

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tobento-app-event/health.svg)

```
[![Health](https://phpackages.com/badges/tobento-app-event/health.svg)](https://phpackages.com/packages/tobento-app-event)
```

PHPackages © 2026

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