开发者

PHP Compare Array Values for Validation

开发者 https://www.devze.com 2023-01-27 17:53 出处:网络
Ok, I have a pretty customized question so bear with me. I basically have two sets of data that I want to compare with a lot of different possibilities.

Ok, I have a pretty customized question so bear with me.

I basically have two sets of data that I want to compare with a lot of different possibilities.

$data  = array(
             'object'=>'ball', // Should check VALID (Rule 2)
             'color'=>'white', // VALID (Rule 2)
             'heavy'=>'no',    // VALID (Rule 1)
             'name'=>'wilson', // VALID (Rule 5)
             'funny'=>'no'     // INVALID (Rule 4)
              );

$data_2 = array(
             'object'=>'box',   // VALID (Rule 2)
             'color'=> 'blue',  // VALID (Rule 2)
             'texture'=>'hard', // VALID (Rule 1)
             'heavy'=>'yes',    // INVALID (Rule 4)
             'stupid'=>'no'     // INVALID (Rule 4)
                                // Name is INVALID because it is missing (Rule 3)

);

$required = array(
             'color'=>array('white','blue'),
             'heavy'=> 'no',
             'name'
);

$errors = array(
         'color'=>array('required'=>'Color开发者_StackOverflow社区 is Required','invalid'=>'Color invalid')
         'object'=>array('invalid'=>'Object invalid'),
         'texture'=>array('invalid'=>'Texture invalid'),
         'heavy'=>array('required'=>'Heavy is Required','invalid'=>'Heavy invalid'),
         'name'=>array('required'=>'Name is Required','max_char'=>'Name exceeds char limit',
         'invalid'=>'Invalid item provided',          
);

$blueprint = array(
                 'object'=>array('box','ball'),
                 'color'=>array('blue','white'),
                 'texture'=>'hard',
                 'heavy'=>'no',
                 'name'
             );

What I want to do is run $data through the $blueprint and make sure of the following:

  1. If the $data key/value pair matches a $blueprint key/value pair, $data's k/v is valid
  2. If the $data key/value pair matches a $blueprint key and a value from the nested array, $data's k/v is valid
  3. If the $data array omits a key/value pair which exists in $blueprint, $data's k/v may still be valid if it is not located in the $required array
  4. If the $data array supplies a key/value pair which does not exist in $blueprint, $data's k/v is invalid
  5. If the $data key from a key/value pair matches a $blueprint value without a defined key, $data's k/v can still be valid. However, if the $blueprint has both a key and value defined, $data's k/v must meet the requirements of rule 1 to be valid.
  6. I'd like to impose a character limit on several of the $blueprint k/v where if a $data's k/v exceeds this character limit, $datas k/v is not valid

If a $data's k/v is invalid, I'd then like to somehow associate an error with that particular k/v describing why it is invalid (surpassed character limit, general error etc.) Perhaps the error would be defined in a third array?

I've looked into array_intersect_assoc but not sure if this is beyond the scope of that function. Also, there will be a good amount of values in the $blueprint, so I need something as versatile as possible.

I think that this is right, my brain sort of melted while I was writing this, so please don't hesitate to ask if confused. Am I better off just validating each k/v individually?

Let's see who is the brainiac out there.


I made one change to your sample code. It seems easier if you make name into a key rather than a numerically keyed value.

$required = array(
 'color'=>array('white','blue'),
 'heavy'=> 'no',
 'name' => '', # name now a key
);

This now works for a number of your rules. Primarily checking required keys exist, and that no extra keys outside of required and blueprint exist.

# check required keys
$missing = array_diff_key($required, $data);
if($missing) {
  var_dump($missing); # react to missing keys
}

# check against all possible keys
$possible = array_merge_recursive($blueprint, $required);
$extra = array_diff_key($data, $possible);
if($extra) {
  var_dump($extra); # react to extra keys
}

Now for the rest I would really need to know how you respond to malformed data etc. but if your data now passes these two tests and you respond in the way you see fit, you should be clear to iterate through the array and validate using array_search(), and filter_var() to check lengths.


I feel sort of silly, but here's a brute force method. #6 you get for free because it's not 'in' the array in any sense.

foreach ($data as $k => $v) {
    if (empty($blueprint[$k])) {
        // (3) Data defines a key that isn't defined in blueprint.
    } else {
        if (is_array($blueprint[$k])) {
            if (in_array($v, $blueprint[$k])) {
                // (2) Data defines a valid value in a blueprint list.
            } else {
                // (also 4) Data defines a value not in a blueprint list.
            }
        } else if ($v == $blueprint[$k]) {
            // (1) Data defines a value in the blueprint.
        } else if (in_array($v, $blueprint)) {
            // (5) Data is in the blueprint without a key.
        } else {
            // (4) Data is invalid.
        }
    }
}

EDIT: This is the loop for checking if $blueprint has a key that $data doesn't define. There should probably be a toggle to make sure this is at all necessary (in the previous block) before running it.

foreach ($blueprint as $k => $v) {
    if (empty($data[$k])) {
        // (6) Data doesn't have a required key from blueprint.
    }
}


Truth be told, that's not that difficult per se, its just complex. You can use the array_map function to simplify the mapping; it would look like this:

function validate_data($data, $blueprint)
{
    // an implementation of all that stuff you wrote using lots of
    // for loops and if statements
}

array_map('validate_data', $data, $blueprint);

Check out the man page for more specifics. You can be the braniac this time :)


You want to use in_array(). It will search through the values of your array and find the different values, eg.

foreach($data as $key => $val) {
  $check = in_array($val, $blueprint);
  if($check === false) {
    print("invalid");
    die;
  }
}


Yes, you probably have to code it youself, as I don't think there is any internal function that can do this. Shouldn't be too hard as you already have a good description of your requirements - just translate it into PHP.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号