Bug Report #1090
Event::$data problems with multiple events
| Status: | Closed | Start date: | ||
|---|---|---|---|---|
| Priority: | High | Due date: | ||
| Assignee: | % Done: | 0% |
||
| Category: | Core | |||
| Target version: | 2.3.3 | |||
| Resolution: | fixed | Points: |
Description
When running multiple events at once it's possible that Event::$data is reset before it can be discarded.
Take this scenario for example:
Two events:
site.inject
block.load
Attached callbacks:
site.inject -> load_site()
block.load -> load_blocks()
block.load -> load_menu_as_block()
The load_blocks callback will do a call to Event::run('site.inject');
$data = 'test';
Here's what happens when we fire Event::run('block.load', $data):- call to function load_blocks -> Event::$data is 'test'
- inside load_blocks Event::run('site.inject') is fired -> Event::$data is empty
- call to function load_menu_as_block -> Event::$data is empty because it has been reset when site.inject was called
So bottom line is that when an event is fired in between two callbacks the Event::$data is being reset. This is a big problem when using a lot of events at once and passing data from one callback to another.
To solve this I made a very simple patch which keeps backwards compatbility with the current Event::$data method. Basically the $data variable passed to Event::run is passed directly (by reference) to the callback.
So instead of having this:
function test() {
echo Event::$data;
}
You use this:
function test(&$data) {
echo Event::$data;
}
Both methods will work and the second will preserve the $data var for each individual callback.
Please see the patch for how it works. It's only one line of code that is changed and everything is backwards compatible.
Related issues
History
Updated by Bob - almost 3 years ago
Did you mean:
function test(&$data) {
echo $data;
}
Is this really a bug? Do other parts of Kohana rely on this behaviour?
Updated by Bob - almost 3 years ago
Also call_user_func does not pass parameters by reference. You would want to change your patch to:
1 foreach ($callbacks as $callback) {
2 call_user_func_array($callback, array(&$data));
3 }
Updated by Parnell Springmeyer over 2 years ago
- Resolution set to fixed
I implemented the changed noted above - it does maintain backwards compatibility as call_user_func_array() will not throw any errors if a callback is specified that has an arity of zero while being passed an array of parameters from call_user_func_array().
Updated by Parnell Springmeyer over 2 years ago
- Status changed from New to Closed