承接 tobento/app-event 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tobento/app-event

Composer 安装命令:

composer require tobento/app-event

包简介

App event support.

README 文档

README

Event support for the app using the Event Service.

Table of Contents

Getting Started

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

composer require tobento/app-event

Requirements

  • PHP 8.4 or greater

Documentation

App

Check out the App Skeleton if you are using the skeleton.

You may also check out the App to learn more about the app in general.

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

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

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 to learn more about the interfaces.

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

namespace App\Event;

use App\Entity\User;

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

Create Listener

namespace App\Listener;

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

Check out the Defining Listeners section to learn more about it.

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 to learn more about adding listeners.

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

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

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

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 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 to learn more about adding listeners.

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 and the App On method for more information.

Credits

tobento/app-event 适用场景与选型建议

tobento/app-event 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 116 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 07 月 14 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「package」 「event」 「app」 「tobento」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 tobento/app-event 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 tobento/app-event 我们能提供哪些服务?
定制开发 / 二次开发

基于 tobento/app-event 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 116
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 15
  • 依赖项目数: 18
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-07-14