array_diff() strange behaviour

145 views Asked by At

I have a routine in my code that computes the differences between two arrays in order create an SQL UPDATE statement.

As soon the routine starts I create a copy of the input array in order to manipulate it while the input one is kept untouched. When I'm ready to create the UPDATE statement I compute the difference between them, using the modified array as leading one.

In every test I ran both arrays were filled with key=value pairs and all values were strings, even when they're integers in the database (PDO behavior) and until now everything worked flawlessly.

But right now I've found something strange. Two different actions, in two different Controllers, but with the same logic are producing different differences:

This one works as expected:

$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 is the result of a query. $modified is a copy of the first array manipulated through class methods. When I'm ready to create the statement, $diff is computed in order to send to PDO (or other driver) the correct statement.

Here, array_diff() works. the tid index is present in both array and it's ignored. The enabled, a simple on/off flag, is different and it's included. The datetime representation too.

But look the variables of this other case:

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

The same as before but with different field names. The sid is ignored but the finished is ignored too while it shouldn't because it is not present in the $input.

By replacing array_diff() with array_diff_assoc(), as expected, everything works, but why?

1

There are 1 answers

1
Shashank On BEST ANSWER

From the docs:

array array_diff ( array $array1 , array $array2 [, array $... ] )

Compares array1 against one or more other arrays and returns the values in array1 that are not present in any of the other arrays.

In your example, $modified2 has an entry 'finished' which has value 1. But $input2 also has value 1 for key 'sid'. Thus, using array_diff($modified2, $input2) will result in the removal of every entry with value 1, no matter what the key is.

Using array_diff_assoc, it will only check to see if $input2 has the entry 'finished' => 1, which it does not, so the entry will not be removed.