It is all about closures being invoked on runtime. The point of it becomes apparent when you need to use a callback (pass a closure as callable \Closure
to another function) without immediately invoking it.
Let's look what happens inside our Slim run.
So if we simply assign a closure to a resource, like so
$app->foo = function () {
return 'invoked foo returns this string';
};
or as a Slims singleton resource
$app->container->singleton('foo', function () {
return 'invoked foo returns this string';
});
it will be invoked on each call or on our first call to it, respectively ... so
$app->foo;
will return the string invoked foo returns this string
.
Lets say that we want another function to use our callable (as some kind of middle layer) and wants to invoke it with call_user_function()
. So we don't want to pass in the invoked function (which will be passing the returned value), but rather an uninvoked closure, which we achieve by assigning the closure to a variable/resource using the protect()
method
$app->bar = $app->container->protect(function () {
return 'bar returns a callable closure';
});
And for a demonstration let's pass our $app->foo
and $app->bar
to call_user_function()
:
call_user_func($app->foo);
will throw an error
"call_user_func() expects parameter 1 to be a valid callback,
function 'invoked foo returns this string' not found or invalid function name"
because it tries to invoke the returned string, where
call_user_func($app->bar);
calls the closure saved in $app->bar
and returns its return string, like so:
"bar returns a callable closure"
I hope this example illustrates the usefulness of Slim's protect()
method.