too long

I am having trouble with form validation for checkboxes.

Here is the checkbox code:

<div class="form-group">
    <div class="checkbox checkbox-danger checkbox-inline">
        <input type="checkbox" name="defect[]" value="{$ng_id}">
    </div>
</div>

If I just do something like this then it echo's out whatever I select.

foreach($_POST['defect'] as $defects) {
echo $defects;
}

I have tried to use the empty function on its own as well as this:

if(empty($defects) || count($defects) < 1) {

but I just keep getting the error:

Undefined index: defect

</div>

A posted array is usually not set if nothing was ticked.

You can do the following check if you want to also check it's an array:-

if(@!is_array($_POST['defect'])){
    // Error
} else {
    foreach($_POST['defect']){
        // do stuff
    }
}

This is suppressing the warning using @ otherwise you would get the "not defined" error.

If you want to avoid that you could just do:

if(!isset($_POST['defect'])){
   // Now check it's an array and has a count > 0
}

.. but in addition you still need to ensure it's an array and has a count greater than zero. The advantage with suppressing the warning in this specific instance is that you know it's an array PLUS you know there must be a value in it otherwise no array would have been passed in from the POST. It's one of those rare moments where suppressing the warning saves you doing 2 additional IF checks to avoid other warnings.You HAVE to check it's an array otherwise you will get the "invalid foreach" warning...

Problem is that when you do not select any of checkboxes, no variable named defect is sent. Simply create hidden field before any checkbox with empty value to always send it.

<input type="hidden" name="defect[]" value="">

And in PHP side:

if (!empty($_POST['defect']) && count($_POST['defect']) > 1) {
    // all ok
} else {
    // show error
}