Événement is a very simple event dispatching library for PHP.

Related tags

Event evenement
Overview

Événement

Événement is a very simple event dispatching library for PHP.

It has the same design goals as Silex and Pimple, to empower the user while staying concise and simple.

It is very strongly inspired by the EventEmitter API found in node.js.

Build Status

Fetch

The recommended way to install Événement is through composer.

Just create a composer.json file for your project:

{
    "require": {
        "evenement/evenement": "^3.0 || ^2.0"
    }
}

Note: The 3.x version of Événement requires PHP 7 and the 2.x version requires PHP 5.4. If you are using PHP 5.3, please use the 1.x version:

{
    "require": {
        "evenement/evenement": "^1.0"
    }
}

And run these two commands to install it:

$ curl -s http://getcomposer.org/installer | php
$ php composer.phar install

Now you can add the autoloader, and you will have access to the library:

<?php
require 'vendor/autoload.php';

Usage

Creating an Emitter

<?php
$emitter = new Evenement\EventEmitter();

Adding Listeners

<?php
$emitter->on('user.created', function (User $user) use ($logger) {
    $logger->log(sprintf("User '%s' was created.", $user->getLogin()));
});

Removing Listeners

<?php
$emitter->off('user.created', function (User $user) use ($logger) {
    $logger->log(sprintf("User '%s' was created.", $user->getLogin()));
});

Emitting Events

<?php
$emitter->emit('user.created', [$user]);

Tests

$ ./vendor/bin/phpunit

License

MIT, see LICENSE.

Comments
  • Indexed event listeners

    Indexed event listeners

    I pretty much made this PR to start a discussion.

    In this PR:

    • Indexed listeners.
    • Listeners cannot be added twice. #7 is related.
    • Performance of removeListener is significantly improved with a lot of listeners O(N) to Olog(N).

    Bug in this PR:

    • With once a duplicate listener can be added. (This is fixable).

    Do you think this is a common use case and are you willing to support it? If so, we might want to make a different trait, so you can choose whatever case suits your project best.

    opened by reenl 6
  • problem with foreach loop..

    problem with foreach loop..

    hi guys,

    i have a problem about events in foreach loop... I have this:

    $template_events = [
    'core_event_head_append'=>'template_event_head_append',
    'core_event_after_header'=>'template_event_after_header',
    'core_event_before_header'=>'template_event_before_header',
    'core_event_after_slider'=>'template_event_after_slider',
    'core_event_after_chat'=>'template_event_after_chat',
    'core_event_before_left_menu'=>'template_event_before_left_menu',
    'core_event_after_left_menu'=>'template_event_after_left_menu',
    'core_event_before_right_menu'=>'template_event_before_right_menu',
    'core_event_after_right_menu'=>'template_event_after_right_menu',
    'core_event_after_news'=>'template_event_after_news',
    'core_event_after_comments'=>'template_event_after_comments',
    'core_event_before_footer'=>'template_event_before_footer',
    'core_event_after_footer'=>'template_event_after_footer',
    'core_event_inside_multipurpose_menu'=>'template_event_inside_multipurpose_menu',
    'core_event_before_dropbox'=>'template_event_before_dropbox',
    'core_event_before_files'=>'template_event_before_files',
    'core_event_before_upload_videos'=>'template_event_before_upload_videos',
    'core_event_after_contact_description'=>'template_event_after_contact_description',
    'core_event_inside_custom_menu'=>'template_event_inside_custom_menu',
    'core_event_inside_custom_w_menu'=>'template_event_inside_custom_w_menu',
    'core_event_inside_head_ready_front'=>'template_event_inside_head_ready_front',
    //admin events
    'core_admin_event_ext_pages'=>'template_admin_event_ext_pages',
    'core_admin_event_custom_pages_ext'=>'template_admin_event_custom_pages_ext',
    'core_admin_event_after_home'=>'template_admin_event_after_home',
    'core_admin_event_before_home'=>'template_admin_event_before_home',
    'core_admin_event_inside_script_tag'=>'template_admin_event_inside_script_tag',
    'core_admin_event_after_jquery'=>'template_admin_event_after_jquery',
    'core_admin_event_head_append'=>'template_admin_event_head_append',
    ];
    

    and try to loop thru all with this:

    foreach($template_events as $core_event => $template_event) {
    	$dispatcher->on("$core_event", function($data) {
    		
    	  global $event_dispatcher, $template_event;
    	  var_dump($template_event);
    	  if(isset($event_dispatcher["$template_event"]))  {
    		$event_dispatcher["$template_event"] .= $data;
    	  } else {
    		$event_dispatcher["$template_event"] = $data;  
    	  }
    	}); 
    
    }
    

    but i can't... $template_event is not recognizable by on event... it return last value of array..

    How to do it properly ?

    opened by Pok4 5
  • Added forward feature

    Added forward feature

    Event Forwarding

    This PR would permit forwarding emitted events between a parent and its children without the need of registering listeners, to the parent, and re-emitting it to the child's listeners. Simply, by passing an object implementing EventEmitterInterface to EventEmitter::forward. Moreover when EventEmitter::emit is called, it will iterate over the children's array and call their emit method with identical arguments.

    opened by alichry 5
  • Allow removal of listeners registered with 'once'.

    Allow removal of listeners registered with 'once'.

    I ran into a problem where I had to remove a listener for event A in a listener for event B, but in some cases the listener for A was registered with once. Because one-time listeners are wrapped in closures they are not being matched by removeListener.

    There are probably myriad ways to solve this, in this PR I tried to minimise changes to on and emit, as well as preserve the current invocation order of the listeners.

    What do you think?

    opened by jmalloc 5
  • Implemented a static event emitter

    Implemented a static event emitter

    I have a use case where i need static calls to the event emitter.

    This PR provides a trait which provides all the EventEmitter methods statically.

    The solution uses __callStatic to forward calls to an instance of EventEmitter. This prevents any code duplication, since the StaticEventEmitterTrait does not need to be changed when EventEmitter is changed. There is a performance hit, but it's not that bad.

    I did some performance testing (https://gist.github.com/ihabunek/8803125). And for 100 listeners, and 100k events, the results are:

    Dynamic adding: 0
    Dynamic emitting: 4.2352
    --
    Static adding: 0.001
    Static emitting: 4.3292
    

    Also, the performance hit can be mitigated by using:

    MyEmitter::emitter()->on(...);
    

    instead of the shorter version which invokes __callStatic:

    MyEmitter::on(...);
    
    opened by ihabunek 4
  • EventEmitter::listeners() returns

    EventEmitter::listeners() returns "[" when no listeners available.

    Hello,

    there was a naming conflict in class EventEmitter, listeners was a function and an array, which resulted in the function returning "[" instead of an empty array when no listeners for an event are found.

    opened by skenqbx 3
  • Implement EventEmitter2

    Implement EventEmitter2

    opened by bergie 3
  • Add once method

    Add once method

    Node.js EventEmitter has, in addition to on, also an once method.

    This method registers a callback, but removes it the first time it has fired. It is quite useful in some situations. See for example the difference between:

    https://github.com/bergie/noflo/blob/master/lib/Port.coffee#L35 https://github.com/bergie/phpflo/blob/master/src/PhpFlo/Port.php#L51

    opened by bergie 3
  • php 8.1 warnings when i'm using arrays in dispatcher

    php 8.1 warnings when i'm using arrays in dispatcher

    Hi guys, i have this:

    $event_dispatcher[] = "" //globalize
    $dispatcher->on('core_event_after_right_menu', function($data) {
      global $event_dispatcher;
      $event_dispatcher['template_event_after_right_menu'] .= $data;
    });
    

    On PHP 7.4 not have any problems, but in 8.1 i get this: PHP Warning: in file C:/xampp2/htdocs/includes/events.php on line 47: Undefined array key "template_event_after_right_menu"

    Can you give me a advice how to solve this problem gently ?

    PS: The code works, but i get the warning...

    opened by Pok4 2
  • EventEmitterTrait::off

    EventEmitterTrait::off

    https://github.com/igorw/evenement/blob/e5c7014414b4295aae60afa81317015be39e0016/src/Evenement/EventEmitterTrait.php#L51

    there logical error

    
    public function off($event, callable $listener = null)
        {
            if ($listener === null) {
                return $this->removeListener($event, $listener);
            }
            return $this->removeAllListeners($event);
    }
    
    must be
    
    public function off($event, callable $listener = null)
        {
            if ($listener !== null) {
                return $this->removeListener($event, $listener);
            }
            return $this->removeAllListeners($event);
    }
    
    opened by shuchkin 2
  • [Question] memory leaks or GC not kicking in or it just php?

    [Question] memory leaks or GC not kicking in or it just php?

    Trying to figure out why PHP doesn't free up memory for evenement @ https://gist.github.com/attozk/e77987fd01488db836b6

    I have let the script run for a long time and it still doesn't free up memory. In other cases I have ran out of memory.

    opened by attozk 2
  • Added power support for the travis.yml file with ppc64le

    Added power support for the travis.yml file with ppc64le

    Added power support for the travis.yml file with ppc64le. This is part of the Ubuntu distribution for ppc64le. This helps us simplify testing later when distributions are re-building and re-releasing.

    opened by sreekanth370 0
  • PSR-14 compatibility

    PSR-14 compatibility

    Do you plan to make this package compatible with PSR?

    https://www.php-fig.org/psr/psr-14 https://github.com/php-fig/event-dispatcher https://github.com/php-fig/event-dispatcher-util

    opened by andrzejkupczyk 2
  • Adding a 'once' listener inside an 'on' handler for the same event will immediately trigger the 'once' with that event

    Adding a 'once' listener inside an 'on' handler for the same event will immediately trigger the 'once' with that event

    macOS High Sierra 10.13.4 PHP 7.0.31 (cli) (built: Jul 19 2018 23:41:03) ( NTS )

    Running this code:

    $emitter  = new Evenement\EventEmitter();
    
    $emitter->on('A', function() use (&$emitter) {
      print("Original A call\n");
    
      $emitter
        ->on('A', function() {
          print("Nested A call\n");
        })
        ->once('A', function() {
          print("Nested A ONCE call\n");
        });
    });
    
    $emitter->emit('A');
    

    Produces the following output:

    Original A call
    Nested A ONCE call

    But I think the expected result should be:

    Original A call

    opened by dpbricher 2
  • Event namespace support

    Event namespace support

    Something like https://api.jquery.com/event.namespace/ For excample, we want to listen on statusChanged event buy only for value idle. We can code like that:

    Listeners:

    $this->once("statusChanged.idle", function() {
        echo "The status is changed to idle.\n";
    });
    $this->on("statusChanged", function() {
       echo "The status is changed.\n";
    });
    

    the emitter

    $this->emit("statusChange.idle");
    $this->emit("statusChange.idle");
    

    Result:

    The status is changed to idle
    The status is changed.
    The status is changed.
    

    instead of

    $this->on("statusChanged", function($status) {
       echo "The status is changed.\n";
    });
    $onceListener = function($status) use (&$onceListener ) {
       if ($status == "idle") {
            echo "The status is changed to idle.\n";
            $this->removeListener("statusChanged", $onceListener);
        }
    };
    $this->on("statusChanged", $onceListener );
    $this->emit("statusChange", ['idle']);
    

    The main advantage that we can easily use it with once.

    opened by shtse8 1
Owner
Igor
Igor
[READ-ONLY] The event dispatcher library for CakePHP. This repo is a split of the main code that can be found in https://github.com/cakephp/cakephp

CakePHP Event Library This library emulates several aspects of how events are triggered and managed in popular JavaScript libraries such as jQuery: An

CakePHP 21 Oct 6, 2022
An asynchronous event driven PHP socket framework. Supports HTTP, Websocket, SSL and other custom protocols. PHP>=5.3.

Workerman What is it Workerman is an asynchronous event-driven PHP framework with high performance to build fast and scalable network applications. Wo

walkor 10.2k Jan 4, 2023
Event-driven, non-blocking I/O with PHP.

Event-driven, non-blocking I/O with PHP. ReactPHP is a low-level library for event-driven programming in PHP. At its core is an event loop, on top of

ReactPHP 8.5k Jan 8, 2023
PHP Application using DDD CQRS Event Sourcing with Hexagonal Architecture

PHP Application using DDD CQRS Event Sourcing with Hexagonal Architecture Application built with Ecotone Framework and powered by integrations with Pr

EcotoneFramework 65 Dec 27, 2022
Revolt is a rock-solid event loop for concurrent PHP applications.

Revolt is a rock-solid event loop for concurrent PHP applications.

Revolt PHP 586 Jan 2, 2023
Infrastructure and testing helpers for creating CQRS and event sourced applications.

Broadway Broadway is a project providing infrastructure and testing helpers for creating CQRS and event sourced applications. Broadway tries hard to n

null 1.5k Dec 27, 2022
Icicle is a PHP library for writing asynchronous code using synchronous coding techniques

Icicle is now deprecated in favor of Amp v2.0. This version is is currently under development, but close to release. The v2.0 branches are amp_v2 in a

icicle.io 1.1k Dec 21, 2022
🚀 Coroutine-based concurrency library for PHP

English | 中文 Swoole is an event-driven asynchronous & coroutine-based concurrency networking communication engine with high performance written in C++

Swoole Project 17.7k Jan 5, 2023
The Hoa\Websocket library.

Hoa is a modular, extensible and structured set of PHP libraries. Moreover, Hoa aims at being a bridge between industrial and research worlds. Hoa\Web

Hoa 419 Dec 30, 2022
The Hoa\Eventsource library.

Hoa is a modular, extensible and structured set of PHP libraries. Moreover, Hoa aims at being a bridge between industrial and research worlds. Hoa\Eve

Hoa 106 Dec 5, 2022
A non-blocking concurrency framework for PHP applications. 🐘

Amp is a non-blocking concurrency framework for PHP. It provides an event loop, promises and streams as a base for asynchronous programming. Promises

Amp 3.8k Jan 6, 2023
Asynchronous coroutines for PHP 7.

Recoil An asynchronous coroutine kernel for PHP 7. composer require recoil/recoil The Recoil project comprises the following packages: recoil/api - T

Recoil 787 Dec 8, 2022
PHP 7.4 EventStore Implementation

Prooph Event Store Common classes and interface for Prooph Event Store implementations. Installation You can install prooph/event-store via composer b

null 532 Dec 9, 2022
Reactive extensions for PHP.

This package is abandoned. Use https://github.com/ReactiveX/RxPHP instead Rx.PHP Reactive extensions for PHP. The reactive extensions for PHP are a se

Alexander 208 Apr 6, 2021
Golang's defer statement for PHP

PHP Defer A defer statement originally comes from Golang. This library allows you to use defer functionality in PHP code. Usage <?php defer($context,

null 249 Dec 31, 2022
Reactive extensions for PHP

RxPHP Reactive extensions for PHP. The reactive extensions for PHP are a set of libraries to compose asynchronous and event-based programs using obser

ReactiveX 1.6k Dec 12, 2022
PSR-7 middleware foundation for building and dispatching middleware pipelines

laminas-stratigility From "Strata", Latin for "layer", and "agility". This package supersedes and replaces phly/conduit. Stratigility is a port of Sen

Laminas Project 47 Dec 22, 2022
Potjet pour la contibution pour un évenement

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

null 1 Feb 4, 2022
Very easy to use a current limiting component, the code is very simple, based on the webman framework.

Very easy to use a current limiting component, the code is very simple, based on the webman framework.

nsp-team 13 Dec 29, 2022
A very slight PHP framework, very easy to use and integrate.

A very slight PHP framework, very easy to use and integrate.

Jerry 95 Oct 26, 2022