Answers.Body: <p>I don't think that syntax is possible, and in any case it could get a bit confusing. Why not simply use a single anonymous function and then call your individual handlers inside that e.g.</p>
  <pre><code>Event::on(
      Entry::class,
      Entry::EVENT_AFTER_SAVE, function(Event $event) {
          $this-&gt;NotifyWhenCookPostedArticle();
          $this-&gt;RunSomethingElse();
          $this-&gt;DoSomethingDifferent();
      }
  );
  
  public function NotifyWhenCookPostedArticle() {
      return 'woop';
  }
  </code></pre>
  <p>(Depending on how separate those things are and/or how large and complex you expect the site to be/become, you would typically abstract them further into your Services layer for reusability and encapsulation).</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-25T15:44:48.980Z
Answers.Text: Yes you are totally right. Thank you.
Answers.UserDisplayName: Slowwie
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-25T11:31:22.353Z
Answers.LastActivityDate: 2021-01-25T11:31:22.353Z
Answers.UserDisplayName: James Smith
Answers.Body: <p>I wrote a convient solution - so you can do things like that with invokable Classes:</p>
  <p>In AppModule.php:</p>
  <pre><code>Event::on(
          Entry::class,
          Entry::EVENT_AFTER_SAVE,
          new OnEntryAfterSave()
      );
  </code></pre>
  <p>In modules\appmodule\Listeners\OnEntryAfterSave.php</p>
  <pre><code>class OnEntryAfterSave
  {
      use Invokable, HasActions;
  
      protected function actions(): array
      {
          return [
              NotifyWhenCookPostedArticle::class,
              RunSomethingElse::class
          ];
      }
  
  }
  </code></pre>
  <p>For this you have to create this two traits:</p>
  <pre><code>trait Invokable
  {
      public function __invoke($args)
      {
          foreach (get_class_methods($this) as $method) {
              if (StringHelper::startsWith($method, 'invoke')) {
                  $this-&gt;$method($args);
              }
          }
      }
  }
  </code></pre>
  <p>This was just the setup for using as many invoke functions as you want and extend the class more and more. (just for future thinking - to keep it clean and short)</p>
  <p>Then the HasActions trait actually listens for actions to call:</p>
  <pre><code>trait HasActions
  {
      public function invokeActions(ModelEvent $event)
      {
          if (method_exists($this, 'actions')) {
              foreach ($this-&gt;actions() as $action) {
                  (new $action)($event);
              }
          }
      }
  }
  </code></pre>
  <p>With this setup you can just create a listener class for each CraftEvent to pass.
  This class only holds an array of Action Classes to call.</p>
  <p>I like it. It's super clean and reuseable.</p>
  <p>You can put it into an Abstract Class to extend from. So you end up with something like this:</p>
  <pre><code>class OnEntryAfterSave extends BaseListener
  {
  
      protected function actions(): array
      {
          return [
              NotifyWhenCookPostedArticle::class,
              RunSomethingElse::class
          ];
      }
  
  } 
  </code></pre>
  <p>Super slick. ;)</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-26T05:58:57.077Z
Answers.LastActivityDate: 2021-01-26T06:17:34.850Z
Answers.LastEditDate: 2021-01-26T06:17:34.850Z
Answers.UserDisplayName: Slowwie
Body: <p>Is it possible to register multiple EventHandlers?</p>
  <p>I mean something like this:</p>
  <pre><code>    Event::on(
          Entry::class,
          Entry::EVENT_AFTER_SAVE,[
             NotifyWhenCookPostedArticle::handle,
             RunSomethingElse::handle,
             DeSomethingDifferent::handle
          ]
  </code></pre>
  <p>I tried it and got a <code>PHP Warning – yii\base\ErrorException call_user_func() expects parameter 1 to be a valid callback, second array member is not a valid method</code></p>
  <p>Is there a notation or helper to get this to work?</p>
  <p>Thanks in advance .
  Michael</p>
  
Tags: <craft3><events>
Title: Multiple Listeners (Handlers) on Event
ThreadText: # Multiple Listeners (Handlers) on Event
  
  (Asked by: username_0 on 2021-01-25)
  
  Is it possible to register multiple EventHandlers?
  
  I mean something like this:
  
  ```
      Event::on(
          Entry::class,
          Entry::EVENT_AFTER_SAVE,[
             NotifyWhenCookPostedArticle::handle,
             RunSomethingElse::handle,
             DeSomethingDifferent::handle
          ]
  
  ```
  
  I tried it and got a `PHP Warning – yii\base\ErrorException call_user_func() expects parameter 1 to be a valid callback, second array member is not a valid method`
  
  Is there a notation or helper to get this to work?
  
  Thanks in advance .
  Michael
  
  **Tags:** craft3, events
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2021-01-25. Score: 2 | Accepted answer
  
  I don't think that syntax is possible, and in any case it could get a bit confusing. Why not simply use a single anonymous function and then call your individual handlers inside that e.g.
  
  ```
  Event::on(
      Entry::class,
      Entry::EVENT_AFTER_SAVE, function(Event $event) {
          $this->NotifyWhenCookPostedArticle();
          $this->RunSomethingElse();
          $this->DoSomethingDifferent();
      }
  );
  
  public function NotifyWhenCookPostedArticle() {
      return 'woop';
  }
  
  ```
  
  (Depending on how separate those things are and/or how large and complex you expect the site to be/become, you would typically abstract them further into your Services layer for reusability and encapsulation).
  
  > **Comments:**
  > **username_0**: Yes you are totally right. Thank you.  
  
  ---
  
  ### Answer by username_0 on 2021-01-26. Score: 1
  
  I wrote a convient solution - so you can do things like that with invokable Classes:
  
  In AppModule.php:
  
  ```
  Event::on(
          Entry::class,
          Entry::EVENT_AFTER_SAVE,
          new OnEntryAfterSave()
      );
  
  ```
  
  In modules\appmodule\Listeners\OnEntryAfterSave.php
  
  ```
  class OnEntryAfterSave
  {
      use Invokable, HasActions;
  
      protected function actions(): array
      {
          return [
              NotifyWhenCookPostedArticle::class,
              RunSomethingElse::class
          ];
      }
  
  }
  
  ```
  
  For this you have to create this two traits:
  
  ```
  trait Invokable
  {
      public function __invoke($args)
      {
          foreach (get_class_methods($this) as $method) {
              if (StringHelper::startsWith($method, 'invoke')) {
                  $this->$method($args);
              }
          }
      }
  }
  
  ```
  
  This was just the setup for using as many invoke functions as you want and extend the class more and more. (just for future thinking - to keep it clean and short)
  
  Then the HasActions trait actually listens for actions to call:
  
  ```
  trait HasActions
  {
      public function invokeActions(ModelEvent $event)
      {
          if (method_exists($this, 'actions')) {
              foreach ($this->actions() as $action) {
                  (new $action)($event);
              }
          }
      }
  }
  
  ```
  
  With this setup you can just create a listener class for each CraftEvent to pass.
  This class only holds an array of Action Classes to call.
  
  I like it. It's super clean and reuseable.
  
  You can put it into an Abstract Class to extend from. So you end up with something like this:
  
  ```
  class OnEntryAfterSave extends BaseListener
  {
  
      protected function actions(): array
      {
          return [
              NotifyWhenCookPostedArticle::class,
              RunSomethingElse::class
          ];
      }
  
  } 
  
  ```
  
  Super slick. ;)
  
  
  ---
  
  