Kyle Thomas Kyle Thomas - 2 months ago 9
PHP Question

How to access a global object inside a method closure

I currently have a dependency injection module which allows me to create a factory of objects:

class DiModule
{
private $Callbacks;

public function set(
$foo,
$bar
) {
$this->Callbacks[$foo] = $bar;
}

public function get(
$foo
) {
return $this->Callbacks[$foo];
}
}


I then have an event object which stores a method closure and the session that will trigger the event.

class Event
{
private $Sesh;
private $Method;

public function set(
$sesh = array(),
$method
) {
$this->Sesh = $sesh;
$this->Method = $method;
}

public function get(
) {
return [$this->Sesh,$this->Method];
}
}


I then have a listener object which searches the sessions set and triggers the event associated with that object.

class Listener
{
private $Sesh;
public function setSesh(
$foo
) {
$this->Sesh = $foo;
}

private $Event;
public function set(
$foo,
Event $event
) {
$this->Event[$foo] = $event;
}

public function dispatch(
$foo
) {
$state = true;

if(isset($this->Event[$foo]))
{
foreach($this->Event[$foo]->get()[0] as $sesh)
{
if(!isset($this->Sesh[$sesh]) || empty($this->Sesh[$sesh]))
{
$state = false;
}
}
}

return ($state) ? [true, $this->Event[$foo]->get()[1]()] : [false, "Event was not triggered."];
}
}


This is an example of this being executed

$di = new DiModule();

$di->set('L', new Listener());
$di->set('E', new Event());

$di->get('E')->set(['misc'], function () { global $di; return $di; });

$di->get('L')->setSesh(array('misc' => 'active')); // not actual sessions yet
$di->get('L')->set('example', $di->get('E'));
var_dump($di->get('L')->dispatch('example'));


The issue is when I try to access my global
$di
inside a closure, I have googled this numerous times but cannot find a solution.

This is the error I receive:


WARNING Missing argument 2 for DiModule::get(), called in /home/phptester.net/public_html/code.php70(5) : eval()'d code on line 82 and defined on line number 7

Answer

You need to use the use keyword to access an outside variable from within a closure.

So this:

$di->get('E')->set(['misc'], function () { global $di; return $di; });

Should be written like this:

$di->get('E')->set(['misc'], function () use ($di) { return $di; });
Comments