该函数如下所示:
public function updated (User $user)
{
if ($user->active && $user->isDirty('active')) {
$password = generatePassword();
$user->password = bcrypt($password);
$user->save();
$user->notify(
new UserWelcomeNotification(
$user->email,
$password,
new MailResource(Email::getMailInfo(23))
)
);
}
}
如您在if语句中所看到的,有一个检查用户是否处于活动状态并且数据库字段是否已更改(isDirty())。如果为真,则会生成一个新密码,使用bcrypt进行哈希处理,然后通过通知(邮件)发送给用户。
预计密码更新将再次触发该方法,但现在isDirty('active)应该返回false。这没有发生,它通过所有迭代都返回true。在达到PHP最大执行时间之后,我收到以下错误:
[Fri Jan 11 09:13:13 2019] PHP致命错误:app/src/vendor/laravel/framework/src/Illuminate/Hashing/BcryptHasher.php中超过60秒的最大执行时间
启用xdebug后,将抛出以下异常。(预期)
PHP错误:在/home/ilyas/script/clockwork/app/src/vendor/laravel/framework/src/Illuminate/Support/Collection.php第1971行中达到了256个最大函数嵌套级别,正在中止!
从这个可以轻松解决的问题中,我有两个问题。
为什么在达到最大执行时间后bcrypt会抛出错误?
为什么在此循环中每次更新后$user->isDirty('active')都返回true,尽管观察者中的最后一个更新未更新active字段?
如Mozammil所要求的那样,$user->getDirty()在第一次触发更新方法时返回这个。
array(2) {
'active' =>
bool(true)
'updated_at' =>
string(19) "2019-01-11 11:27:13"
}
从第二次返回开始直到超时时间到达:
array(3) {
'password' =>
string(60) "$2y$10$rlAbpelKnT/yp5zFhXcjwelEKkDEx5SfNJWqL1LiDltRnHYBLINmK"
'active' =>
bool(true)
'updated_at' =>
string(19) "2019-01-11 11:27:13"
}
isDirty('active')
仍然返回true的事实才是问题所在。 - Odysseedd($user->getDirty())
以便我们知道 Laravel 认为哪些值是脏的? - MozammilgetDirty()
的输出。 - OdysseeisDirty()
和wasChanged()
之间的区别。我认为$user->wasChanged('active')
可能会解决这个问题。但是,我需要自己尝试一下。 - Mozammil