Skip to content

Add ability to validate arrays explicitly #739

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

Add ability to validate arrays explicitly #739

wants to merge 1 commit into from

Conversation

KaneCohen
Copy link
Contributor

Ok, this is a fork of my other PR (#255) related to Validator.

This PR introduces additional special characters: "[]". Square brackets now are going to be an indicator that certain attribute must be validated as an array of items. And works like that:

$input = array('tags' => array('foo', 'bar', 'baz'));

$val = Validator::make($input, array('tags[]' => 'required|alpha'));

As you can see, we have an attribute tags[] in the rules set. What it does, is it tells to the Validator that tags attribute is an array and each of it's items have to be validated against "required" and "alpha" rules.

But what if we didn't specify that tags is an array?

$val = Validator::make($input, array('tags' => 'required|alpha'));

We'll get an exception.


Now, one important not related to array validation with exists rule?

$input = array('tags' => array('foo', 'bar', 'baz'));

$val = Validator::make($input, array('tags[]' => 'exists:tags_table,name'));
// In this scenario Validator will go through every item in the array chacking it agains the DB.

$val = Validator::make($input, array('tags' => 'exists:tags_table,name'));
// In this scenario Validator will make only one query with "WHERE IN" clause

Also, now you can mix rules:

$input = array('tags' => array('foo', 'bar', 'baz'));

$val = Validator::make($input, array(
    'tags[]' => 'required|alpha'
    'tags'   => 'exists:tags_table,name'
));

As you can see, you can use tags[] to validate every item in the array against certain rules, while you can also have tags checking certain rules (exists) over the array as a whole.

P.S.: I'm not adding extra commit here, but i'm wondering if getSize method should return array length if value is an array. I guess that's for the Issue or another PR.
P.P.S: Alternatively to [], maybe used *. And even more: post.*.title - validate only title from the array of posts. Requires array_get or getValue rewrite.

@RSully
Copy link
Contributor

RSully commented Mar 28, 2013

While I agree this would be a nice thing to have there is one part that confuses me. Initially you said validating against tags would cause an exception, but the only way to validate existence without tons of queries is with tags rather than tags[].

What about something like array('tags' => 'required|array') or similar?

@KaneCohen
Copy link
Contributor Author

@RSully,

Initially you said validating against tags would cause an exception, but the only way to validate existence without tons of queries is with tags rather than tags[].

That's why you'll have to have two separate rules. One validates every item, the other validates whole array:

$val = Validator::make($input, array(
    'tags[]' => 'required|alpha'
    'tags'   => 'exists:tags_table,name'
));

Exception on tags will be only if tags input is an array. What i'm saying is - Validator works exactly as it did before, only addition is [] which will tell to Validator to validate every item of the array.


What about something like array('tags' => 'required|array') or similar?

Initially i was contemplating idea of using rule as an indicator for the array, but discarded it for one reason - how would Validator know when to apply per item rule and per array rule in cases of several rules (besides exists)? For example: min:3|max:10|numeric|exists:tags_table,id. Rules are used not only to validate, but also return to the user set of errors guiding them at what's wrong with their input.

And besides that there might be issues with custom rules:

$input = array('tags' => array('foo', 'bar', 'baz'));
$val = Validator::make($input, array(
    'tags'   => 'required|min:3|my_custom_rule|array'
));

What if my_custom_rule check has it's own complex DB query? In this case it'll be applied to each item individually even though user might not want it to.

With this PR you can apply different rules either to whole array (DB queries in most cases, i'd guess) and conventional rules like alpha, numeric etc. to each item individually.

@taylorotwell
Copy link
Member

I don't like this. Feels really hacky.

@KaneCohen
Copy link
Contributor Author

Ok. I'll think of some other way around it without extra characters.

@KaneCohen KaneCohen mentioned this pull request Mar 28, 2013
@KaneCohen KaneCohen mentioned this pull request May 9, 2013
@KaneCohen KaneCohen deleted the val2 branch February 22, 2014 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants