2014-11-26 5 views
0

У меня есть подпрограмма в моем коде, которая вычисляет различия между двумя массивами, чтобы создать инструкцию SQL UPDATE.array_diff() странное поведение

Как только начинается процедура, я создаю копию входного массива, чтобы манипулировать ею, в то время как входной файл остается нетронутым. Когда я готов создать инструкцию UPDATE, я вычисляю разницу между ними, используя модифицированный массив как ведущий.

В каждом тесте, в котором я работал, оба массива были заполнены парами ключ = значение, и все значения были строками, даже если они являются целыми числами в базе данных (поведение PDO), и до сих пор все работало безупречно.

Но прямо сейчас я нашел что-то странное. Две различные действия, в двух разных контроллеров, но с той же логикой производят различные различия:

Это один работает, как ожидалось:

$input = array(
    'tid' => '3', 
    'enabled' => '1' 
); 

$modified = array(
    'tid' => '3', 
    'enabled' => 0, 
    'modified' => '2014-11-26 15:17:55' 
}; 

$diff = array(
    'enabled' => 0, 
    'modified' => '2014-11-26 15:17:55' 
); 

$ вход является результатом запроса. $ изменен - это копия первого массива, обработанного методами класса. Когда я готов создать оператор, $ diff вычисляется для того, чтобы отправить PDO (или другому драйверу) правильную инструкцию.

Здесь работает array_diff(). tid индекс присутствует в обоих массивах, и он игнорируется. включен, простой флаг включения/выключения, отличается и включен. Представление datetime тоже.

Но посмотрите переменные этого другого случая:

$input2 = array(
    'sid' => '1', 
    'finished' => '0' 
); 

$modified2 = array(
    'sid' => '1', 
    'finished' => 1, 
    'modified' => '2014-11-26 15:21:58' 
); 

$diff2 = array(
    'modified' => '2014-11-26 15:21:58' 
); 

так же, как и раньше, но с разными названиями полей. sid проигнорирован, но завершен тоже игнорируется, хотя он не должен, потому что его нет в $ input.

Заменив array_diff() на array_diff_assoc(), как и ожидалось, все работает, но почему?

ответ

3

Из docs:

массива array_diff (массив $ массив1 массив $ array2 [, массив $ ...])

Сравнивает array1 против одного или нескольких других массивов и возвращает значения в массиве 1, которые отсутствуют ни в одном из других массивов.

В вашем примере, $modified2 есть запись «закончена», которая имеет значение 1. Но $input2 также имеет значение 1 для ключа «ИДС». Таким образом, использование array_diff($modified2, $input2) приведет к удалению каждой записи со значением 1, независимо от того, что это за ключ.

Используя array_diff_assoc, он будет проверять только, есть ли у $input2 запись «закончена» => 1, а это не так, поэтому запись не будет удалена.

+0

Да, сэр! Я не знаю, как раньше этого не замечал. Это жара, я могу обвинить погоду. –

Смежные вопросы