How does the dependency container anonymous function know what $c is?

$container['db'] = function ($c) {
    $db = $c['settings']['db'];
    $pdo = new PDO("mysql:host=" . $db['host'] . ";dbname=" . $db['dbname'],
       $db['user'], $db['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
   return $pdo;
};

How does the anonymous function know what $c is? I’m relatively new to PHP, so there may be something about PHP anonymous functions that I don’t know. If so, any links to reading material would be greatly appreciated.
Thank you.

Here is a logger Dependency example >> http://www.slimframework.com/docs/tutorial/first-app.html#use-monolog-in-your-application

Extract from that link is below for easy reference :

The dependency is named logger and the code to add it looks like this:

$container[‘logger’] = function($c) {
$logger = new \Monolog\Logger(‘my_logger’);
$file_handler = new \Monolog\Handler\StreamHandler(“…/logs/app.log”);
$logger->pushHandler($file_handler);
return $logger;
};


>We’re adding an element to the container, which is itself an anonymous function **(the $c that is passed in is the container itself so you can acess other dependencies if you need to). This will be called when we try to access this dependency for the first time**; the code here does the setup of the dependency. **Next time we try to access the same dependence, the same object that was created the first time will be used the next time**.

You can use `$container` instead of `$c` for better clarity. Its just a local variable to that function, populated and called by Slim.


Explore More :

* Another [Example](http://www.slimframework.com/docs/tutorial/first-app.html#add-a-database-connection) **DB Connection Dependency**
* [More about Anonymous functions / Closures]( http://php.net/manual/en/functions.anonymous.php)
* [How to pass object context to an anonymous function](http://stackoverflow.com/questions/6330602/how-to-pass-object-context-to-an-anonymous-function)

I don’t understand it also, and susanth’s answer didn’t help at all!

For example (from the php.net):

$greet = function($name)
{
printf(“Hello %s\r\n”, $name);
};
$greet(‘World’);

That is perfectly clear!

But with the container, omg… Where is this “greet(‘World’)” part??

That means, where is the closure call happening ?

Slim will make the call when that event is triggered. From a basic slim user view point, you don’t have to worry much about that. If it makes you confusing, think of it as a black box.

Set the call back function with a parameter to host the container ( say … $c ). And when the event is triggered, $c will be populated with container object, automatically by slim.

View the mechanism as a contract. something like You do like this. I will provide you with this features.

With this mind set you can keep on exploring slim, without much need to know about internal working mechanism. Mean while experiment on basic examples of closures. you will automatically reach the light at a point.

key is keep on going / experimenting.

It’s not even a “Slim thing”. This feature works with Pimple even without any framework. And I want to understand how. And if you can’t explain it, please remain silent. At least stop quoting things! Rather try to explain in your own words.

Hi @minemax


It’s not even a “Slim thing”. This feature works with Pimple even without any framework.

Yes it is based on Pimple. Slim is making use of Pimple >> http://www.slimframework.com/docs/concepts/di.html
Slim uses a dependency container to prepare, manage, and inject application dependencies. Slim supports containers that implement the Container-Interop interface. You can use Slim’s built-in container (based on Pimple) or third-party containers like Acclimate or PHP-DI.

packagist.org Slim, Pimple

You can find more about Pimple working

And if you are looking for Pimple Internals.


you should beable to find answer for >> Where is this “greet(‘World’)” part??
Inside this File. It is just a 155 line of code ( without comments ). :slight_smile:


… And if you can’t explain it, please remain silent.

@minemax Sorry to see you get annoyed by my post. Am here to share and learn in a friendly way . Am not an Slim internals expert nor Pimple too. If am posting anything wrong, there are experts in this forum to point out that ( including you ). Am open to accept my faults; if any.


… At least stop quoting things!

By Quoting, I just want to mention your these words >> Where is this “greet(‘World’)” part??. Please don’t take it any other way.


… Rather try to explain in your own words.

What I can explain is based on my understanding only !!!. If am wrong, am always open and happy to learn / fix it. Together we can build a better understanding in a friendly way.

Am always trying to follow these guidelines

Treating library as a black box is what I do when am interested to build things using the library as a ready made layer. Having internals knowledge is really a plus.

Thank you @minemax :slight_smile:

1 Like

Omg, you’re hopeless… I really hope you’re not one of the Slim framework developers…

I’ll try to explain, although I don’t have a ton of experience with Slim.

When you call $this->db (where $this is a container), Slim (through Pimple, the DI engine) returns an object with a call to the anonymous function that you posted in your OP, with itself as the parameter (I think in line 109 of Pimple\Container.php).

Therefor, inside the anonymous function you have acccess to the container itself.

Does this help?

1 Like

I found their explanations helpful, sorry you didn’t.

1 Like

Oh, reeeeeaaaaaally? You must be smart. Of course you can pinpoint the file (and the line number) where the magic happens, right? :slight_smile:

But guess what? Now I can. It’s here, look.

Did you intentionally use the word “magic”? If so, you are on the right track.

1 Like