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); });