Giter Club home page Giter Club logo

evenement's Introduction

É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.

Continuous Integration Latest Stable Version Total Downloads License

Fetch

The recommended way to install Événement is through composer. By running the following command:

$ composer require evenement/evenement

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->removeListener('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.

evenement's People

Contributors

alichry avatar amystephen avatar arnaudligny avatar battlecook avatar bowlofeggs avatar fionera avatar igorw avatar kinimodmeyer avatar lavoiesl avatar nyholm avatar samnela avatar shtse8 avatar staabm avatar wormling avatar wyrihaximus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

evenement's Issues

EventEmitterTrait::off

public function off($event, callable $listener = null)

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);
}

`off` instead of `removeListener`

At the moment, we need to cancel a listener with removeListener, while adding a listener with on. I suggest adding a off method like jQuery. It's for better understanding with on/off.

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 ?

Add PHP 5.4 trait implementation

Right now there is no easy way to add an EventEmitter to an existing class, since you cannot extend the class and the emitter at the same time. This is a great use case for traits.

An example of extending the Symfony request class:

use Evenement\EventEmitterTrait;
use Symfony\Component\HttpFoundation\Request;

class StreamedRequest extends Request
{
    use EventEmitterTrait;
}

$request = new StreamedRequest();
$request->on('data', function ($data) {
    var_dump('received data: '.$data);
});

Since I don't want to force PHP 5.4 but I don't want to copy-paste the implementation either, this will take place in a separate branch.

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.

ISP

Shouldn't you split up the interface into one for emitting events and one for acting upon events?

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

EventEmitterTrait::on() fatal error when passed callable array

When I do the following, I get a fatal error.

class Foo
{
    public function bar()
    {
        echo 'FooBar';
    }
}

$callable = [new Foo, 'bar'];

$emitter = new Evenement\EventEmitter();
$emitter->on('foo', $callable);

$emitter->emit('foo');

Interestingly, I don't get a fatal error if I type hint for callable inside a class, so I wonder if there's a bug in PHP that means type hints for callable inside trait methods aren't satisfied by callable arrays?

Either way, it limits the functionality of this library to not be able to pass a callable array so I wonder if an abstract class would be better?

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...

why use ...arguments

why EventEmitterTrait.php use (...$arguments), i just delete three ..., and i can use it well like
$result = array( 'code' => $ex->getCode(), 'message'=> $ex->getMessage(), 'line' => $ex->getLine(), 'file' => $ex->getFile(), 'trace' => $ex->getTrace(), ); $server->emit('log.exception', $result);

Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'

Hi. I use evenement. Cool and simple lib :)

I came across on this error. Our project uses php apc. And I can't cache closure objects in apc cache. I found a solution https://github.com/jeremeamia/super_closure. But then I need to write some code as follows

$emitter->on('my.event', new SerializableClosure(function () {
    // piece of code
}));

Not so convinient. What do you think about? Maybe use super_closure lib in evenement source (update "on" method)?

Provide a PHP 5.3 alternative

I looked in packagist for an equivalent of Node's EventEmitter for PHP 5.3, and your code is the closes that I could find. The translation to PHP 5.3 is trivial but would be very useful.

<?php
namespace Evenement;
class EventEmitter implements EventEmitterInterface
{
    protected $listeners = array();

    public function on($event, $listener)
    {
        if (!isset($this->listeners[$event])) {
            $this->listeners[$event] = array();
        }

        $this->listeners[$event][] = $listener;
    }

    public function once($event, $listener)
    {
        $that = $this;
        $onceListener = function () use (&$onceListener, $event, $listener, $that) {
            $that->removeListener($event, $onceListener);
            call_user_func_array($listener, func_get_args());
        };
        $this->on($event, $onceListener);
    }

    public function removeListener($event, $listener)
    {
        if (isset($this->listeners[$event])) {
            if (false !== $index = array_search($listener, $this->listeners[$event], true)) {
                unset($this->listeners[$event][$index]);
            }
        }
    }

    public function removeAllListeners($event = null)
    {
        if ($event !== null) {
            unset($this->listeners[$event]);
        } else {
            $this->listeners = array();
        }
    }

    public function listeners($event)
    {
        return isset($this->listeners[$event]) ? $this->listeners[$event] : array();
    }

    public function emit($event, $arguments = array())
    {
        foreach ($this->listeners($event) as $listener) {
            call_user_func_array($listener, $arguments);
        }
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.