array_diff() странное поведение

В моем коде есть подпрограмма, которая вычисляет различия между двумя массивами, чтобы создать оператор SQL UPDATE.

Как только процедура запускается, я создаю копию входного массива, чтобы манипулировать им, пока входной не трогается. Когда я готов создать оператор 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'
);

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

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

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

$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(), как и ожидалось, все работает, но почему?

1 ответ

Решение

Из документов:

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

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

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

С помощью array_diff_assoc, он будет только проверять, если $input2 имеет запись 'finish' => 1, чего нет, поэтому запись не будет удалена.

Другие вопросы по тегам