When I'm updating my model-bound form with

$user->update(Input::all())

My password field is re-hashed, even when it's empty. I have set my User.php class to automatically hash that field, but shouldn't it be skipped since the field is empty?

  • You should consider using accessors and mutatorshttp://laravel.com/docs/4.2/eloquent#accessors-and-mutators – Tom Bird Dec 3 '14 at 7:14

4 Answers 正确答案

You could use in this case:

Input::except('password')

so in your controller you could do it this way:

if (trim(Input::get('password')) == '') {
   $data = Input::except('password');
}
else {
   $data = Input::all();
}
$user->update($data);

However you should consider other possible issues for that. In this case if user send input with idname (and anyone can do it even if you don't have such field in your form) he could change easily other users passwords/accounts and destroy your whole data.

You should use in your User model at least:

protected $guarded = array('id');

to protect user id from being changed during mass assignment but maybe there are also some other fields you would like to protect (you should list them in $guarded array.

For me much better option in this case is using standard user updating:

$user = User::find($id);

if (trim(Input::get('password')) != '') {
   $user->password = Hash::make(trim(Input::get('password')));
} 
$user->name = Input::get('name');
// and so on - this way you know what you are changing and you won't change something you don't want to change
$user->save();

Just as Tom Bird commented, here's some code for an example.

If you use a mutator like setPasswordAttribute() method in your model then you can do this:

public function setPasswordAttribute($password)
{   
    if (!empty($password))
    {
        $this->attributes['password'] = bcrypt($password);
    }
}

This will prevent a new password from being hashed. This setPasswordAttribute() method is called a "mutator" and became available in Laravel 4.2 from what I see. http://laravel.com/docs/4.2/eloquent

Because you have sent all of the input to the user model it assumes you want to update all fields including the password even though it is an empty string, it is possible to hash an empty string.

You need to check if the password is empty and if it is use Input::except('password')

public function update($id)
{
    $register = Register::findOrFail($id);
    if (empty(Request::get('password'))) {
        $data = Request::except('password');
    } else {
        $data = Request::all();
    }
    $register->update($data);
    return redirect('register');
}

来自  https://stackoverflow.com/questions/26381051/laravel-empty-password-being-hashed-when-updating-user