Laravel/PHP: существует ли ограничение на количество аргументов, передаваемых функции закрытия

#php #laravel #closures

Вопрос:

Когда я пытался переопределить функцию сброса пароля по умолчанию, я столкнулся с какой-то странной проблемой с закрытием.

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

3-я переменная $pwAge должна быть передана для закрытия через

 use($pwAge)  

если передать вместе с первыми двумя аргументами, как это:

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

При вызове этой функции я получу следующую ошибку:

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

Что я здесь упускаю? Пожалуйста, посоветуйте, спасибо.

Ответ №1:

Ограничение на количество аргументов в закрытии ограничено количеством аргументов, предоставляемых функции при ее вызове.

Что бы ни вызывало эту функцию ( PasswordBroker.php в данном случае), оно предоставляет $user и $password ; оно не знает о $pwAge переменной и, конечно, не знает, что оно должно передать ее функции.

Вы можете использовать переменную, добавив ее в область использования закрытия use ($pwAge) .

Рассмотрим следующий пример псевдокода:

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

Для меня на самом деле то, что закрытие вызывалось где-то в другом месте, помогло мне понять, что я не контролирую параметры, передаваемые закрытию. Это полностью зависит от кода, который его вызывает.

Поэтому, если для закрытия требуются дополнительные «параметры», вам просто нужно поместить их в область действия:

 doSomething(function ($result) use ($importantData) {  doSomethingElse($result, $importantData); });