aspirinemaga
aspirinemaga

Reputation: 3947

Comparing two arrays in PHP foreach

What's the best way to compare both two arrays to each other in a foreach loop ?

I have two arrays, which one holds a boolean values and other one represents the real values.

First one of the arrays is some sort of configuration file where I tell what field is a required one TRUE or an optional FALSE:

$rules = array(
    'fieldname1' => TRUE,
    'fieldname2' => FALSE,
    'fieldname3' => TRUE,
    'fieldname4' => TRUE,
    'fieldname5' => FALSE,
    'fieldname6' => FALSE,
    'fieldname7' => TRUE,
    'fieldname8' => TRUE
);

And the other array which holds incoming data to be worked out:

$fields = array(
    'fieldname1' => 'some value',
    'fieldname3' => 'some value',
    'fieldname4' => 'some value',
    'fieldname7' => 'some value',
    'fieldname8' => 'some value'
);

How do I make a check in foreach() loop, so the $fields array is going to compare each of its fieldnameX or (keys/indexes) with the other array named $rules ?

For example: $rules['fieldname1'] is required as it have a bool TRUE. So in foreach($fields as $field), the $field named fieldname1 should not be empty, null or false, if so, show an error.

This is a function I did so far which is not doing exactly what I want:

private function check_field_required_exist( $fields )
{
    // Read rules from config to work with them accordingly
    $rules = config_item('flow.format')[$fields['format']];

    // Run throught the rules
    foreach( array_keys($rules) as $field )
    {
        // Check wheter key existance is failed
        if( !array_key_exists($field, $fields) )
        {
            // Checking failed, terminate the process
            die('Required field: "'. $field .'" for requested format: "'.$fields['format'].'" does not exists.');
        }
    }

    // Everything is alright
    return TRUE;
}

Upvotes: 0

Views: 3464

Answers (5)

user2766829
user2766829

Reputation: 54

// Goes through all the rules
foreach($rules as $key => $value) 
{
  // access all fields that are marked as required i.e key set as TRUE
  if ($value) 
  {
    //for those whose value is TRUE, check whether the corresponding field is set or
    // whether it is empty (NULL,false)
    if(!isset($fields[$key]) || empty($fields[$key]))
    {
      die('Required field does not exist');
    }
  }
}

Upvotes: 2

Patrick
Patrick

Reputation: 881

USING PHP Array Functions:

$rules = array('name' => TRUE, 'phoneNumber' => TRUE, 'age' => FALSE);
$submittedFields = array( 'name' => 'aspirinemaga', 'age' => 38, 'phoneNumber' => '');

$requiredFields = array_keys(array_filter($rules));
$validFields = array_keys(array_filter($submittedFields));

$missingFields = array_diff($requiredFields, $validFields);

Given

$rules = array('name' => TRUE, 'phoneNumber' => TRUE, 'age' => FALSE);
$submittedFields = array( 'name' => 'aspirinemaga', 'age' => 38, 'phoneNumber' => '');

PhoneNumber is wrong here.

$requiredFields = array_keys(array_filter($rules));

This gives you the keys of all rule elements that are TRUE.

$validFields = array_keys(array_filter($submittedFields));

Same here, your definition of what's ok is the same as php truth table for boolean conversion. If you have a more advanced check, you could pass a function name into array_filter (see below).

$missingFields = array_diff($requiredFields, $validFields);

This will get you all the fieldNames that exist in $requiredFields but are not in $validFields.

More advanced validation

$rules = array('name' => 'MORE_THAN_3', 'phoneNumber' => TRUE, 'age' => 'POSITIVE');
$submittedFields = array( 'name' => 'aspirinemaga', 'age' => 38, 'phoneNumber' => '');

$requiredFields = array_keys(array_filter($rules));

function validateField($key, $value){

    // get the rule (assuming no submittedFields that have no rule)
    $rule = $rules[$key];
    
    switch($rule){
        case 'MORE_THAN_3': return strlen($value) > 3; break;
        case 'POSITIVE': return $value > 0; break;
    }

    // in case of TRUE/FALSE
    return TRUE;       
}

$validFields = array_keys(array_filter("validateField", $submittedFields, ARRAY_FILTER_USE_BOTH));
$missingFields = array_diff($requiredFields, $validFields);

If you wanted to do a more advanced validation, you can integrate that nicely into above solution.

Say you wanted name to be more than 3 characters and age to be positive. Write it into your rules:

$rules = array('name' => 'MORE_THAN_3', 'phoneNumber' => TRUE, 'age' => 'POSITIVE');
$submittedFields = array( 'name' => 'aspirinemaga', 'age' => 38, 'phoneNumber' => '');

Required Fields are still the same (to check if one is missing).

$requiredFields = array_keys(array_filter($rules));

Now your validate function would be something like:

function validateField($key, $value){

    // get the rule (assuming no submittedFields that have no rule)
    $rule = $rules[$key];
    
    switch($rule){
        case 'MORE_THAN_3': return strlen($value) > 3; break;
        case 'POSITIVE': return $value > 0; break;
    }

    // in case of TRUE/FALSE
    return TRUE;       
}

Pass that into array_filter and add to ARRAY_FILTER_USE_BOTH Flag:

$validFields = array_keys(array_filter("validateField", $submittedFields, ARRAY_FILTER_USE_BOTH));

And your missing Fields stays the same.

$missingFields = array_diff($requiredFields, $validFields);

This will only work in PHP 5.6+ (because ARRAY_FILTER_USE_BOTH). Not tested, should work.

Upvotes: 0

dadarya
dadarya

Reputation: 313

$requiredField = array();
foreach($rules as $key=>$value) {
    if($value == true && (!isset($fields[$key]) || $fields[$key] == "" )) {
        $requiredField[] = $key;
    }
}
if(count($requiredField) > 0) {
    echo implode(',',$requiredField)." Are Required";
    die;
}

Upvotes: 0

Loufylouf
Loufylouf

Reputation: 699

I think that you can play around with the array functions in PHP. First thing I would do is to apply array_filter on your rules array. That way, you will only keep the TRUE values (and their indexes, since array_filter keep the index/value association). Then I would use array_intersect_key to keep only the fields of interest in your fields var. And again array_filter with a custom callback to perform the verification you want to do.

Upvotes: 1

Seunhaab
Seunhaab

Reputation: 540

foreach ($fields as $field => $value)
{
    if (array_key_exists($field, $rules) && $rules[$field] === true)
    {
        if (!$value || $value == "" || $value === null)
        {
            die(); // return false;
        }
    }
}
return true;

Upvotes: 1

Related Questions