简体   繁体   English

PHP比较数组值以进行验证

[英]PHP Compare Array Values for Validation

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 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: 我想做的是通过$blueprint运行$data并确保以下内容:

  1. If the $data key/value pair matches a $blueprint key/value pair, $data 'sk/v is valid 如果$data键/值对与$blueprint键/值对匹配,则$data data'sk / v有效
  2. If the $data key/value pair matches a $blueprint key and a value from the nested array, $data 'sk/v is valid 如果$data键/值对与$blueprint键和嵌套数组中的值匹配,则$data data'sk / v有效
  3. If the $data array omits a key/value pair which exists in $blueprint , $data 'sk/v may still be valid if it is not located in the $required array 如果$data数组省略了$blueprint中存在的键/值对,则$data data'sk / v如果不在$required数组中,则可能仍然有效。
  4. If the $data array supplies a key/value pair which does not exist in $blueprint , $data 'sk/v is invalid 如果$data阵列提供一个密钥/值对不存在于$blueprint$data “SK / v是无效
  5. If the $data key from a key/value pair matches a $blueprint value without a defined key, $data 'sk/v can still be valid. 如果键/值对中的$data键与没有定义键的$blueprint值匹配,则$data data'sk / v仍然有效。 However, if the $blueprint has both a key and value defined, $data 'sk/v must meet the requirements of rule 1 to be valid. 但是,如果$blueprint同时定义了键和值,则$data data'sk / v必须满足规则1的要求才有效。
  6. I'd like to impose a character limit on several of the $blueprint k/v where if a $data 'sk/v exceeds this character limit, $data sk/v is not valid 我想对$blueprint k / v施加字符限制,如果$data data'sk / v超出此字符限制,则$data sk / v无效

If a $data 'sk/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? 如果$data data'sk / v无效,那么我想以某种方式将错误与该特定k / v相关联,以描述其无效的原因(超出字符限制,常规错误等)。也许该错误将在第三阵?

I've looked into array_intersect_assoc but not sure if this is beyond the scope of that function. 我已经研究了array_intersect_assoc但是不确定这是否超出了该函数的范围。 Also, there will be a good amount of values in the $blueprint , so I need something as versatile as possible. 另外, $blueprint中将有大量的值,因此我需要尽可能多用途的东西。

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? 我最好单独验证每个k / v吗?

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. 现在,剩下的我真的需要知道您如何处理格式错误的数据等。但是,如果您的数据现在通过了这两项测试,并且您以自己认为合适的方式进行响应,则应该清楚地遍历数组并使用array_search()验证array_search()filter_var()来检查长度。

Truth be told, that's not that difficult per se, its just complex. 说实话,这本身并不困难,只是复杂。 You can use the array_map function to simplify the mapping; 您可以使用array_map函数简化映射。 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(). 您要使用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;
  }
}

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. #6您免费获得,因为它绝不在任何意义上。

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. 编辑:这是检查$ blueprint是否具有$ data未定义键的循环。 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.
    }
}

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. 不应太难,因为您已经对需求有很好的描述-只需将其翻译成PHP。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM