Validate or remove for extra fields in laravel

半世苍凉 提交于 2020-07-31 20:15:47

问题


It's posible to validate request with rules for additional fields, or remove that fields from request?

Simple example, I have FormRequest object with rules:

public function rules() {
        return [
            'id' => 'required|integer',
            'company_name' => 'required|max:255',
        ];
    }

And when I get post request with any other fields I want to get error/exception in controller or I want to get only id and company_name fields, with no any others. It's exist any feature in laravel with that, or I must make it in my way?


回答1:


Your post request with laravel has more stuff than just your form input so you need to check Request to see what is inside.

To get only the fields you want you can use:

$request->only(['fieldname1', 'fieldname2', 'fieldname3']);

or

$request->except(['fieldnameYouDontWant1', 'fieldnameYouDontWant2', 'fieldnameYouDontWant3']);

to exclude the ones you don't want.




回答2:


To remove key from request in Laravel, use:

$request->request->remove('key')



回答3:


Since Laravel 5.5 you can do this in your controller:

public function store(StoreCompanyRequest $request)
{
    Company::create($request->validated());
}

The validated() function returns only the fields that you have validated and removes everything else.




回答4:


You can use except method of request which will give you fields except for the given fields

$request = $request->except('your_field');

if you want to remove multiple fields from request you can pass array of the fields

$request = $request->except(['field_1','field_2',...])

Reference: Laravel requests




回答5:


Things get a little trickier when you start getting into nested array element validations, especially if wildcards are involved. Put this in your custom Request class, and inject it into your controller method. Should cover all cases.

public function authorize()
{
    //Dot notation makes it possible to parse nested values without recursion
    $original = array_dot($this->all());
    $filtered = [];
    $rules = collect($this->rules());
    $keys = $rules->keys();
    $rules->each(function ($rules, $key) use ($original, $keys, &$filtered) {
        //Allow for array or pipe-delimited rule-sets
        if (is_string($rules)) {
            $rules = explode('|', $rules);
        }
        //In case a rule requires an element to be an array, look for nested rules
        $nestedRules = $keys->filter(function ($otherKey) use ($key) {
            return (strpos($otherKey, "$key.") === 0);
        });
        //If the input must be an array, default missing nested rules to a wildcard
        if (in_array('array', $rules) && $nestedRules->isEmpty()) {
            $key .= ".*";
        }

        foreach ($original as $dotIndex => $element) {
            //fnmatch respects wildcard asterisks
            if (fnmatch($key, $dotIndex)) {
                //array_set respects dot-notation, building out a normal array
                array_set($filtered, $dotIndex, $element);
            }
        }
    });

    //Replace all input values with the filtered set
    $this->replace($filtered);

    //If field changes were attempted, but non were permitted, send back a 403
    return (empty($original) || !empty($this->all()));
}



回答6:


I have a new solution for this, create a new function in your form request class:

public function onlyInRules()
{
    return $this->only(array_keys($this->rules()));
}

Then in your controller, call $request->onlyInRules() instead of $request->all()




回答7:


I did it by override method validate() in FormRequest class.

abstract class MyFormRequest extends FormRequest {
    public function validate() {
        foreach ($this->request->all() as $key => $value) {
            if (!array_key_exists($key, $this->rules())) {
                throw new ValidationException("Field " . $key . " is not allowed.");
            }
        }
        parent::validate();
    }
}

I think it's not best way, but it's works. I should upgrade it to show info about all wrong fields at once :)




回答8:


Starting form Laravel 5.5 you can call validate method right on Request e.g.

class YourController extends Controller
{

    public function store(Request $request) {

      $cleanData = $request->validate([
        'id' => 'required|integer',
        'company_name' => 'required|max:255',
      ]);

      // Now you may safely pass $cleanData right to your model
      // because it ONLY contains fields that in your rules e.g

      $yourModel->create($cleanData);
  }
}



回答9:


$request->validated(); 

will return only the validated data.

In your controller method:

public function myController(ValidationRequest $request) {
    $data = $request->validated();
}



回答10:


You can do it through your controller. You can send only two or certain fields to database. Use $request->only() instead of $request->all() and pass a array of data you want to save in database. Your controller's store() method should look like this:

public function store(Request $request)
{
    ModelName::create($request->only(['id','company_name']));
    return redirect('RouteName');
}



回答11:


Unfortunately the majority of answers here have missed the point of the original issue. That being, you want to specify the fields that need validating in your FormRequest class, and then in your controller do:

Something::create($request->validated());

However, it might be that you want to validate a particular field, but not pass it to the create method in your controller. The problem with doing $request->only() or $request->except() is that you have to repeat the fields from your FormRequest class, or repeat them in the $guarded property of your model.

Unfortunately the only way I found to do what you want was as follows:

Something::create(collect($request->validated())->forget('field_you_dont_want')->toArray());



来源:https://stackoverflow.com/questions/35327679/validate-or-remove-for-extra-fields-in-laravel

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