Returning a class object from a container

I’m having trouble figuring out how to return an instantiated class object from a container.

This works:

$container["person"] = function() {
  return new Person;
};

This does not:

$person = new Person;
$container["person"] = function() {
  return $person;
};

Here is the full code. I’m not getting errors, just not the name string from the person class.

// person class
class Person {

  function __construct() {
    $this->name = "Rob";
  }
}
$person = new Person;

// app
$app = new \Slim\App();
$container = $app->getContainer();
$container["person"] = function($c) {
  return $person;
};

$app->get('/api/person',function($request,$response) {
  $response->getBody()->write("Welcome, " . $this->person->name);
});

$app->run();

Gah, I figured it out. This works:

$person = new Person;
$container["person"] = function() use ($person) {
  return $person;
}
$person = new Person;
$container["person"] = function() {
  return $person;
};

The above code does not work because of Object Scoping.

Whenever you see { ... } you are creating a new variable scope there are a few slight exceptions to this rule but i think are outside the scope of your question.

In your example $person is actually null when you ask for a person. that class does not exist inside the function () {} scope.

You can pass variables INTO a scope by using use

You will notice that this code does actually work.

$person = new Person;
$container["person"] = function() use($person) {
  return $person;
};

In this example you are telling PHP that you would like to use the $person variable from the parent scope in this case the global namespace.

Furthermore you want to change your full code example.

// person class
class Person {
  public $name;
  function __construct() {
    $this->name = "Rob";
  }
}

// app
$app = new \Slim\App();
$container = $app->getContainer();
$container["person"] = function($c) {
  $person = new Person;
  return $person;
};

$app->get('/api/person',function($request,$response) {
  return $response->getBody()->write("Welcome, " . $this->person->name); //always return from a route
});

$app->run();

3 Changes.

  • Add the Construction of the Person to the Factory method of the container… ie the function (its called a factory).
  • Return from the function body.
  • Add a public variable for the name

@geggleto, thanks. You must have been typing while I figured it out :slight_smile:

1 Like