Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Suxipo's avatar

Add array size check to validation

hi, I have a voting system where each user has to vote vote for a number of choices out of a given set of choices, i.e. select 5 out of 10 people by checking on 5 checkboxes coressponding to 5 pepople that user wants to vote for. So my system has to check to make sure the user checks exactly on 5 checkboxes, no more, no less before saving the votes into the database.

I've been trying to figure out how to get this to work with Laravel's validation capability with no luck. Here is what my request looks like:

class SubmitVoteRequest extends Request
{    
    public function authorize()
    {
        return true; 
    }
    public function rules()
    {
        $votes = Request::get('vote');        
        $count = count($votes);                     
        $limit = 5;        
        $rules[$count] = $limit;        
        return $rules;        
    }
}

Here is part of the controller code:

public function StoreVote(Requests\SubmitVoteRequest $request){        
        $votes = Request::get('vote');        
        //Something to perform if validation passes
}

And here is the top of the error page I get when I try to submit:

ErrorException in Validator.php line 424: Invalid argument supplied for foreach()

    in Validator.php line 424
    at HandleExceptions->handleError('2', 'Invalid argument supplied for foreach()', '/var/www/html/tchc-eval/vendor/laravel/framework/src/Illuminate/Validation/Validator.php', '424', array('attribute' => '0', 'rules' => '5')) in Validator.php line 424
....

I am sure there is something in my SubmitVoteRequest code but can't figure out how.

Please help

Thank you

0 likes
9 replies
pmall's avatar
public function rules()
{
    return [
        'vote' => 'array|max:5',
    ];
}
1 like
Suxipo's avatar

@pmall,

Thank you for your help! Since I need to set number of votes must be exact 5, here is what works for me:

public function rules()
    {
        return ['vote'=>'array|size:5'];       
    }

However I still have 1 more problem. The number of votes is not fixed, but varies from time to time and is calculated from another variable. So it must be a variable. So I pass the variable like following and this one works:

public function rules()
    {
        $limit = 2; 
        
        return ['vote'=>'array|size:$limit'];        
    }

However, how can I pass such variable in custom error message? Tried this but didnt work:

public function messages()
    {
        $limit = 2; 
        
        return ['vote.size'=>'Your number of votes must be $limit'];
    }   
1 like
pmall's avatar

It should. What do your mean by it doesn't work ?

Suxipo's avatar

@pmall,

it gives this validation error message "Your number of votes must be $limit" while I expect it should be "Your number of votes must be 5" if $limit = 5.

And I must retract from previous post that this code does not actual work:

public function rules()
    {
        $limit = 2; 
        
        return ['vote'=>'array|size:$limit'];        
    }

because it will always result in validation error message no matter how checboxs are checked, even the number of checkboxs checked match the $limit value.

Oh 1 more question: How can I force at least 1 checkbox is checked because currently even with

public function rules()
    {
         return ['vote'=>'array|size:5'];        
    }

no validation error will be shown if no checkbox is checked

Suxipo's avatar

ok I got some progress. The following code allows me to achieve the following requirements:

  • At least 1 checkbox must be checked
  • Variable can be passed to validation rule and validation error message.
public function rules()
    {
        $limit = 5;              
        return ['vote'=>['required','array','size:'.$limit]];       
    }
    
    public function messages()   
    {               
        return ['vote.size'=>'Required number of votes must be :size'];        
        return ['vote.required'=>'You must vote for someone'];
    }   

However, 2 problems arise:

  • When I change the validation error message to unicode (such as Vietnamese), the error message is empty.
  • I am able to customize the error message for the vote.size, but the vote.required error message doesn't change with above code, it keeps using the default message which is "The vote field is required."
pmall's avatar
pmall
Best Answer
Level 56
return ['vote.size'=>'Required number of votes must be :size'];        
return ['vote.required'=>'You must vote for someone'];

Hey you return two things in this function ! Do this :

return [
    'vote.size'=>'Required number of votes must be :size',
    'vote.required'=>'You must vote for someone',
];
Suxipo's avatar

@pmall

Great! thank you for pointing that out!

Do you have any idea why validation error wouldn't accept unicode message and display only empty error? This wouldn't work:

public function messages()   
    {               
        return [            
            'vote.size'=>'Không được roài',
            'vote.required'=>'Phải vote cho ai đó nhé',
        ];
    }    
EventFellows's avatar

Just as a quick alternative to your $variable question above

Instead of your string handling with single quote return ['vote'=>['required','array','size:'.$limit]];

You can also do keep the variable within double quote return ['vote'=>['required','array',"size:$limit"]];

Especially for longer string combinations it often makes a much cleaner readability.

Suxipo's avatar

@EventFellows

Thanks for the tip. It's always good to know different methods to achieve same result

Please or to participate in this conversation.