2

The code:

final class SimpleEventManager {
    private $listeners = array();

    public function listen($event, $callable) {
        $this->listeners[$event][] = $callable;
    }

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

$manager = new SimpleEventManager;
$manager->listen('sql', function($sql) {
    $sql .= " order by username desc";
});
$sql = "select * from users";
$manager->fire('sql', array($sql));
var_dump($sql); // is: select * from users
                // want: select * from users order by username desc

So basically i want my event listeners to be able to modify the arguments that come in. I've tried doing things like array &$arguments = array() but then I'm getting the Cannot pass parameter 2 by reference error.

Does anyone know how I can solve this?

user2538584
  • 521
  • 1
  • 5
  • 11
  • 1
    Modify the function to *accept* the argument by reference. `public function fire($event, &$arguments)` – random_user_name Sep 06 '13 at 16:10
  • Not the answer, but why are you calling foreach? `$this->listeners[$event]` isn't an array. – OneOfOne Sep 06 '13 at 16:12
  • @cale_b I'm not sure what you mean, could you give a bigger code example? I've tried using `fire($event, &$arguments)` but then I get the same error at `$manager->fire('sql', array($sql))` – user2538584 Sep 06 '13 at 16:17
  • Does this answer your question? [PHP error: "Cannot pass parameter 2 by reference"](https://stackoverflow.com/questions/13105373/php-error-cannot-pass-parameter-2-by-reference) – ggorlen May 27 '22 at 23:04

1 Answers1

2

You can't pass it by reference because only variable may be passed by reference. The literal array($sql) is clearly not a variable.

That said, this isn't the problem.

In fact, there's a lot of problems, mostly because of $sql being "copied" so many times:

  1. When creating the array($sql)
  2. When calling fire() (due to not being passed by reference)
  3. When calling the anonymous function (again, not being passed by reference)

First of all you need to define your array as a variable, such as $arr = array(&$sql);

Then keep your current "fix" of passing &$arguments by reference.

Finally, adjust your anonymous function to function(&$sql) to also work by reference.

All in all, this could be made a lot easier if your code weren't so convoluted ;)

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592