Skip to content
Advertisement

Laravel/PHP: is there a limit on number of arguments passed to closure function

When I was trying to override the default password reset function, I ran into some weird issue with closure.

        $response = $this->broker()->reset(
            // the 3rd variable $pwAge has to be passed via use()
            $this->credentials($request), function ($user, $password) use($pwAge) {
                $this->resetPassword($user, $password, $pwAge);
            }
        );

The 3rd variable $pwAge has to be passed to the closure via

use($pwAge)

if passed along side with the first two arguments as this:

        $response = $this->broker()->reset(
            $this->credentials($request), function ($user, $password, $pwAge) {
                $this->resetPassword($user, $password, $pwAge);
            }
        );

I will get the following error when this function is called:

SymfonyComponentDebugExceptionFatalThrowableError
Too few arguments to function AppHttpControllersAuthResetPasswordController::AppHttpControllersAuth{closure}(), 2 passed in vendorlaravelframeworksrcIlluminateAuthPasswordsPasswordBroker.php on line 96 and exactly 3 expected 

What am I missing here? Please advise, thanks.

Advertisement

Answer

The limit to the number of arguments in a closure is limited to amount of arguments provided to the function when it is called.

Whatever is calling that function (PasswordBroker.php in this case) provides a $user and $password; it has no knowledge of the $pwAge variable, and certainly does not know that it should pass it to the function.

You are able to use the variable by adding it to the scope of the closure using use ($pwAge).

Consider the following pseudo-code example:

function doSomething($cb) {
  $result = doSomeStuff();
  cb($result);
}

doSomething(function ($result) {
  doSomethingElse($result);
});

For me, actually seeing that the closure was being called somewhere else helped me understand that I have no control over the parameters being passed to the closure. It’s completely dependent on the code that calls it.

So if the closure needs extra “parameters”, you just need to put them in scope:

doSomething(function ($result) use ($importantData) {
  doSomethingElse($result, $importantData);
});
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement