PHP Сравнить значения массива для проверки - PullRequest
0 голосов
/ 02 декабря 2010

Хорошо, у меня довольно индивидуальный вопрос, так что терпите меня.

У меня есть два набора данных, которые я хочу сравнить с множеством различных возможностей.

$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'
             );

Я хочу запустить $data через $blueprint и убедиться в следующем:

  1. Если пара ключ / значение $data соответствует паре ключ / значение $blueprint, k / v $data является действительным
  2. Если пара ключ / значение $data совпадает с ключом $blueprint и значением из вложенного массива, k / v $data является действительным
  3. Если в массиве $data отсутствует пара ключ / значение, существующая в $blueprint, k / v $data может все еще быть действительным, если он не находится в массиве $required
  4. Если массив $data предоставляет пару ключ / значение, которой нет в $blueprint, k / v $data недопустимо
  5. Если ключ $data из пары ключ / значение соответствует значению $blueprint без определенного ключа, k / v $data все еще может быть действительным. Однако, если в $blueprint определены ключ и значение, k / v для $data должно соответствовать требованиям правила 1, чтобы быть действительным.
  6. Я бы хотел наложить ограничение на количество символов для нескольких $blueprint k / v, где, если k / v $data превышает это ограничение на число символов, $data s k / v недопустимо

Если $data 'sk / v недопустимо, я бы хотел как-то связать ошибку с этим конкретным k / v, описывающую, почему она недопустима (превышен предел символов, общая ошибка и т. Д.). Возможно, ошибка определиться в третьем массиве?

Я изучил array_intersect_assoc, но не уверен, выходит ли это за рамки этой функции. Кроме того, в $blueprint будет много значений, поэтому мне нужно что-то настолько универсальное, насколько это возможно.

Я думаю, что это правильно, мой мозг как будто растаял, когда я писал это, поэтому, пожалуйста, не стесняйтесь спрашивать, если запутался. Мне лучше проверять каждый к / в индивидуально?

Давайте посмотрим, кто там мозговой.

Ответы [ 5 ]

2 голосов
/ 02 декабря 2010

Я внес одно изменение в ваш пример кода.Кажется проще, если вы превращаете имя в ключ, а не в числовое значение.

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

Теперь это работает для ряда ваших правил.В первую очередь проверяется наличие необходимых ключей, и что никаких дополнительных ключей вне требуемого и чертежа не существует.

# 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
}

Теперь для остальных мне действительно нужно знать, как вы реагируете на искаженные данные и т. Д., Но если ваши данные сейчаспроходит эти два теста, и вы отвечаете так, как считаете нужным, вам должно быть ясно, что нужно проходить через массив и проверять, используя array_search() и filter_var() для проверки длины.

1 голос
/ 02 декабря 2010

Я чувствую себя немного глупо, но вот метод грубой силы.# 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: Это цикл для проверки, есть ли у $ blueprint ключ, который не определен $ data.Вероятно, должен быть переключатель, чтобы убедиться, что это вообще необходимо (в предыдущем блоке) перед запуском.

foreach ($blueprint as $k => $v) {
    if (empty($data[$k])) {
        // (6) Data doesn't have a required key from blueprint.
    }
}
1 голос
/ 02 декабря 2010

По правде говоря, это не так сложно само по себе, это просто сложно. Вы можете использовать функцию array_map , чтобы упростить отображение; это будет выглядеть так:

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);

Посетите справочную страницу для получения более подробной информации. На этот раз вы можете быть безумцем:)

1 голос
/ 02 декабря 2010

Вы хотите использовать in_array (). Он будет искать значения вашего массива и находить разные значения, например.

foreach($data as $key => $val) {
  $check = in_array($val, $blueprint);
  if($check === false) {
    print("invalid");
    die;
  }
}
0 голосов
/ 02 декабря 2010

Да, вам, вероятно, придется кодировать его самостоятельно, так как я не думаю, что есть какая-то внутренняя функция, которая может это сделать.Не должно быть слишком сложно, так как у вас уже есть хорошее описание ваших требований - просто переведите его на PHP.

...