0

I have the next code snippet:

$di = new FactoryDefault();
...
$di->setShared('mongo', function($di) use ($di) {
   return new Models\MongoDb\Manager($di);
});

The code works fine, but PHP log says:

Warning:  Missing argument 1 for {closure}() in
/var/www/merkaz.gq/public_html/v1/index.php on line 63

Any ideas ?

ramiromd
  • 2,019
  • 8
  • 33
  • 62

2 Answers2

2

Because your clousure is not called with the $di argument. Change

function($di) use ($di) {

to

function() use ($di) {
Federkun
  • 36,084
  • 8
  • 78
  • 90
  • not really; since the closure expect an argument, and then is called without it, I think that a "Missing argument" error is appropriate - php thinks: "maybe is a fault of who called the closure" – Federkun Apr 05 '16 at 22:15
  • @Federico seems to me like the closure expected *no* argument, but one was provided. – Mike Apr 05 '16 at 22:21
  • @Mike you are misunderstanding where arguments are. "Function($di)" is the the function's signature and it says that one argument must be supplied. The name "$di" in that context will match a variable of the same name inside of the function definition. That $di has no relation to your $di object at all. Just as any fn signature parameter name is irrelevant outside its definition. "use ($di)", though, DOES point to the scope outside of your closure (function). Back to signature: the argument there is supplied by the calling function! If "setShared" doesn't supply it, no one will. Hence error. – Buttle Butkus Apr 05 '16 at 22:45
  • So, you can use "use" to get any variable and put it into your closure. But the closure function parameter, whatever you call it, will be supplied magically by the calling function. See for example 'array_filter' – Buttle Butkus Apr 05 '16 at 22:50
  • @ButtleButkus Thanks for the explanation. I think got it now. So I would imagine that the line that the line that actually produces the error would be the line that executes the anonymous function in the FactoryDefault object, right? – Mike Apr 05 '16 at 22:58
  • @Mike yes. It is executing the function but it isn't supplying an argument. `use` allows you to get variables into the anonymous function (which is I think not technically a closure) from the outside scope. The anonymous function argument *can* be used if A.) the calling function supplies it or B.) the anonymous function is assigned to a variable. E.g. `$foo = function($bar) { return 'foo' . $bar}; $foo('asdf'); // returns 'fooasdf'` – Buttle Butkus Apr 05 '16 at 23:25
1

In Phalcon 2.1 you can use:

$di->setShared('mongo', function() {
   return new Models\MongoDb\Manager($this);
});
serghei
  • 3,069
  • 2
  • 30
  • 48