Laravel 4 mass assignment guarded not work

痞子三分冷 提交于 2019-12-22 01:18:57

问题


I wonder what wrong in my code that I can't protected 2 input username and password

In my controller:

class AccountsController extends \BaseController {

...

public function store()
    {
        $date = new \DateTime;
        $input['updated_at']=$date;
        $input['created_at']=$date;
        $input['username']=Input::get("username", "");
        $input['password']=Input::get("password", "");
        $input['sex']=Input::get("sex", "");
        $input['dob']=Input::get("dob", "");
        $input['dob']= date("Y-m-d", strtotime($input['dob']));

        $v=Validator::make($input, Account::$register_rules);
        $input['password']=Hash::make($input['password']);
        if($v->passes()){
            DB::table('accounts')->insert($input);

        }
        //return Redirect::route('text.index');
    }

...

}

In my model:

class Account extends \Eloquent {
    protected $guarded = array('username', 'password');

    public static $register_rules=array(
                'username'   => 'required|min:4|max:20|unique:accounts',
                'password'   => 'required|alpha_num|min:6',
                'sex'       =>  'required|in:f,m',
                'dob'       => 'required|date_format:Y-m-d'
            );
}

In my app/view

...


{{ Form::open(array('route'=>'account.store')) }}
            <table>
                <tr>
                    <td>{{ Form::label('username', 'Username') }}</td>
                    <td>{{ Form::text('username') }}</td>
                </tr>
                <tr>
                    <td>{{ Form::label('password', 'Password') }}</td>
                    <td>{{ Form::password('password') }}</td>
                </tr>
                <tr>
                    <td>{{ Form::label('confirm_password', 'Confirm Password') }}</td>
                    <td>{{ Form::password('confirm_password', array('id'=>'confirm_password')) }}</td>
                </tr>
                <tr>
                    <td>{{ Form::label('sex', 'Sex') }}</td>
                    <td>
                        {{ Form::radio('sex', 'f', true) }}{{ Form::label('Female') }}
                        {{ Form::radio('sex', 'm') }}{{ Form::label('Male') }}
                    </td>
                </tr>
                <tr>
                    <td>{{ Form::label('dob', 'Date of Birth') }}</td>
                    <td>
                        {{Form::text('dob', '', array('id' => 'dob'))}}
                    </td>
                </tr>

                <tr>
                    <td></td>
                    <td>{{ Form::submit('Register', array('id' => 'submit')) }}</td>
                </tr>

            </table>
        {{ Form::close() }}

...

Even though I defined guarded these two fields they are still saved in the database.


回答1:


Actually you are not using Eloquent ORM and hence the following code guards mass assignment of Eloquent models, for example using Model::create(Input::all()) method you may create a new Account in the database like:

$account = Account::create(Input::all());

In your case, you are not using Eloquent model, instead you are using insert method using DB::('accounts')->insert($input) which is a feature of Query builder class (It's an instance of Illuminate\Database\Query\Builder).

So, if you use the Eloquent ORM then the features of Eloquent will be used. In this case, use of Model::save() is not a mass assignment but create() uses the mass assignment because when creating a new model, you may pass an array of attributes to the model constructor. These attributes are then assigned to the model via mass-assignment and create accepts an array of attributes and then initializes the model using new static($attributes), for example, this is the create method:

public static function create(array $attributes)
{
    $model = new static($attributes);
    $model->save();
    return $model;
}

So, if you manually initiate a model using something like this:

$account = new Account(Input::all()); // Mass assignment through constructor
$account->save();

This will be a mass assignment. In this case you need to create the Account model by extending the Eloquent like this (You already have one):

class Account extends Eloquent {

    // Protect mass assignment
    protected $guarded = array('username', 'password');

    //...
}

You may read more about Mass Assignment on Laravel website.




回答2:


You are not using the Eloquent ORM. If you don't use the ORM you can't expect any of its features to be used.

DB::table('accounts')->insert($input);

Should be

$account = new Account($input);
$account->save():
// This is mass assigning model attributes

Now you will see that your guarded attributes are properly guarded. It is recommended that you do not pass raw input data into a model that has guarded attributes set without defining them either as fillable or making sure you specifically sanitise the data.

So your code would become something similar to the below.

$model = new Account();

$model->username = Input::get('username', '');
//  etc ...

$validator = Validator::make($model->toArray(), $rules);

if ( ! $validator->fails() )
    $model->save();


来源:https://stackoverflow.com/questions/24221287/laravel-4-mass-assignment-guarded-not-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!