Is this a good or an acceptable way to check all form fields were completed and valid

I am using PHP 8 and want to check that all form fields have been completed ie some value has been entered in all fields when a form is submitted.

I am first checking form was submitted using

if($_SERVER['REQUEST_METHOD'] == 'POST'){

But then I need to check all fields have had something entered. I came across this code and it seems to work great - can anyone see any problems that I may not have forseen …

if(count(array_filter($_POST))==count($_POST)){

I just want to emphasize - I am not checking to see if any fields are empty, because of logical flow of script - I want to check that ALL fields are NOT empty. I want to check user has entered something in every field before they clicked submit. I have client side validation but I want to also check server side

Thanks

Hmmm. Did you try it? When called with a null callback, array_filter removes all elements with empty values. Which means, as far as I can tell by just looking at it, your === will always be true. Something like this might work:

$originalPostCount = count($_POST);
if (count(array_filter($_POST) === $originalPostCount)) {

Even that seems a bit iffy. Frankly I would validate each posted variable by itself possibly using one of the many validation libraries out there.

Actually I have been experiencing problems since I posted. I just have 3 fields and I want to ensure none are empty but I just cant seem to get the syntax right.

This was my lates (failed) attempt -

if (!empty($_POST['new_pass_1']) && !empty($_POST['new_pass_2']) && !empty($_POST['old_pass'])) {

Actually that last code seems to be working now, I think maybe my error was elsewhere :slight_smile: Thanks

Your code may check that all fields have been completed, but it’s not checking that they are valid.

2 Likes

If someone enters a space the field will be “not empty”. What you need to do is trim the entire POST array at one time and THEN check for empty.

As far as checking that all fields are not empty, you can create an array of required fields and loop over the array adding an error message to an errors array for each field that is empty. This would best be done in a function so as to be able to re-use the required fields check in other places. You would pass the required fields array as a parameter to the function.

1 Like

Thank you my friend - I appreciate that - this particular example was just ‘one small step for man’ I am addressing the other issues and validity. But thanks for the heads up!

I am aware of this and am trimming the individual POST fields (although I admit that is not obvious from my code example) but I had not considered the option to TRIM

Good idea - I will look into that - maybe something like $_POST = array_map("trim", $_POST); ? Thanks

Client-side validation is a nicety for legitimate visitors. Data submitted to your site can come from anywhere, not just your forms/links, can be set to anything, and cannot be trusted. You must trim (mainly so that you can detect if it was all white-space characters) and validate data on the server before using it. Required fields must not be an empty string. Non-required fields may be an empty string. Fields that are not empty that must have a specific format, such as email, date, time, … values, or match a specific character class, must be validated that they match the required format and character class.

By validating each field separately and setting up a unique and helpful error message for each validation error, not only will you provide a better User eXperience (UX), but your code will help you debug programming mistakes and will also help identify if/when bots start submitting data for only some of the fields, by displaying (during development) or logging (on a live/public server) all php errors.

By keeping the form data as a set, in a php array variable, you can dynamically operate (validate, build sql queries, build email bodies, write data to files, …) on the data. Trimming all the data at once involves simply applying/calling a recursive (in case any fields are an array) trim function on the set of data. Because this modifies the data, you should store the result in a different variable than $_POST (this also leaves the original data in $_POST in case some other part of your application needs the raw data values.)

1 Like

Thanks for the insights. So maybe $_POST = filter_var($_POST, \FILTER_CALLBACK, ['options' => 'trim']); would be a start ?

PHP is server-side, right? Other members can help more than I can but the ideal is to do both:

  • client-side, usually using JavaScript or WebAssembly
  • server-side to ensure the data is valid and safe

Here is a useful function that handles trim on arrays and strings.

function trim_array($input): array|string
{
    if (!is_array($input)) {
        return trim($input);
    }
    return array_map('trim_array', $input);
}
1 Like

That code will come with the same caveats as if you used empty() on every element. Mainly, that the string “0” is considered empty and would be filtered out. Thus if you have an numeric inputs where “0” is a valid value, it will fail this validation check.

I’m not keen on this as it just accepts whatever is in POST so long as it’s not empty.
What you should do is (like @benanamen and @mabismad have said) check only the specific form fields that you actually expect to receive.
So if your three inputs were unsername, email, password but the user submits foo, bar, baz so long as those contain a non-empty values, you accept it as being valid.
Of course the real answer depends on the exact nature of the inputs you have. Different input types will be validated in different ways.

1 Like

Firstly I would like to thank all those that took the time to reply and provided very useful comments and insights - BUT - to save people time, I wish to emphasize that I am not trying to fully validate anything here. At the most this is the first step in validation. I fully appreciate the need to validate server side fully and provide informative error messages. This post is purely regarding checking that fields are not empty as defined by the PHP empty() criteria. I understand that 0 will be regarded as empty as will null and false.

The question is simply regarding a step towards further validation. Having said that I fully appreciate any additional comments and feedback and always welcome information.

By definition, submitted post method form fields are strings, regardless of the actual value. Therefore, after being trimmed, an empty field will be an empty string. If you test for exactly an empty string. e.g. ==='', this will tell you if nothing was entered in the field. Forget about using empty().

I think the point you are missing is that you can and should be dynamically validating each expected field separately. @benanamen, has already posted how to do this, using a data-driven design, where you define a data structure (array) that tells general-purpose code what to do. I would suggest that the defining array be more then just for required fields, but all the information needed to validate and process each field. You also need to make this general-purpose, so that it will work for fields that are not required.

For example -

// define expected fields
$fields = [];
$fields['new_pass_1'] = ['label'=>'New Password','required'=>true];
$fields['new_pass_2'] = ['label'=>'New Password Confirmation','required'=>true];
$fields['old_pass'] = ['label'=>'Old Password','required'=>true];

// the array index is the field name.
// the label value is used when dynamically producing error messages, dynamically producing the label part of form fields, ...
// you can add other elements to this definition, e.g. other validation steps, processing type (insert, update-set term, update-where term, delete-where term, email body,...)

To dynamically validate ‘required’ fields, you would loop (foreach ($fields as $field=>$arr)) over this defining array. If the ‘required’ element exists (you could leave it out or set it to a false value for non-required fields) and is a true value, test if the current $field in the trimmed data is exactly an empty string. If it is, use the $arr['label'] element to build and add an error message to an array holding the user/validation errors, using the field name as the main array index in this error array.

1 Like

Indeed I was! Thanks for clarifying and again thanks to all.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.