Why array_diff() gives Array to string conversion error?

PhpArraysMultidimensional ArrayArray Difference

Php Problem Overview


I get array to string conversion error for the following line:

$diff = array_diff($stockist, $arr);

Here, $arr is an array decoded from a JSON file. Using the is_array() function I was able to verify that both parameters are arrays. Can someone point me the problem

$stockist = array();
while (!feof($file_handle)) {

    $line_of_text = fgetcsv($file_handle);
    $query = "SELECT * FROM reorderchart WHERE medicine = '"
        . trim($line_of_text[3])
        . "' ORDER BY medicine";
    $result = mysql_query($query);

    if (trim($line_of_text[2]) - trim($line_of_text[1]) <= 0) {
        
        while ($row = mysql_fetch_array($result)) {

            $file = "results.json";
            $arr = json_decode(file_get_contents($file),true);
            $pharmacy = trim($row['Medicine']);

            if (isset($stockist[$pharmacy])) {
                    
                $medicine = $stockist[$pharmacy];
                $medicine[] = trim($row['Stockist']);
                $stockist[$pharmacy] = $medicine;

            } else {

                $medicine = array();
                $medicine[] = trim($row['Stockist']);
                $stockist[$pharmacy] = $medicine;
            }
        }
    }
}
$diff = array();
$diff = array_diff_assoc($stockist,$arr);
ksort($diff);
foreach ($diff as $key => $value) {

    echo "<table align='center' border='1'>";
    echo "<tr><td align = 'center'> <font color = 'blue'> $key</td></tr>";
    
    foreach($value as $key1 => $value1) {

        echo "<tr><td align ='center'>$value1</td></tr><br>";
    }
    echo "</table>";
}

Php Solutions


Solution 1 - Php

According to it:

php -r 'array_diff(array("a" => array("b" => 4)), array(1));'
PHP Notice:  Array to string conversion in Command line code on line 1
PHP Stack trace:
PHP   1. {main}() Command line code:0
PHP   2. array_diff() Command line code:1

One of your arrays is multidimensional.

array_diff only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using array_diff($array1[0], $array2[0]);

Solution 2 - Php

Yes, the strict answer is because "One of your arrays is multidimensional."

Another useful note might be - depending on your needs of further parsing the actual differences - consider first testing your arrays with:

$diff = strcmp(json_encode($stockist), json_encode($arr));

or

$diff = strspn(json_encode($stockist) ^ json_encode($arr), "\0");

or

$diff = xdiff_string_diff(json_encode($stockist), json_encode($arr));

All these options will compare the entire array tree, not just the top level.

Solution 3 - Php

Since array_diff can only deals with one dimension, you can either:

Solution 4 - Php

According to PHP documentation for the function

> Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same.

For more information refer to http://php.net/manual/en/function.array-diff.php

Solution 5 - Php

You can see in the array_diff() documentation that:

> Two elements are considered equal if and only if (string) $elem1 === > (string) $elem2. In other words: when the string representation is the > same.

So it looks like you can't use this function with multi dimensional array, or in fact any value that cannot be converted to a string. This is because the function will cast values to a string to do the comparison.

You can write your own function to recursively check arrays for a difference - in fact the following is from the comments of the docs linked above.

You can see the comment here.

function arrayRecursiveDiff($aArray1, $aArray2) { 
    $aReturn = array(); 
   
    foreach ($aArray1 as $mKey => $mValue) { 
        if (array_key_exists($mKey, $aArray2)) { 
            if (is_array($mValue)) { 
                $aRecursiveDiff = arrayRecursiveDiff($mValue, $aArray2[$mKey]); 
                if (count($aRecursiveDiff)) { $aReturn[$mKey] = $aRecursiveDiff; } 
            } else { 
                if ($mValue != $aArray2[$mKey]) { 
                    $aReturn[$mKey] = $mValue; 
                } 
            } 
        } else { 
            $aReturn[$mKey] = $mValue; 
        } 
    } 
   
    return $aReturn; 
}

Solution 6 - Php

Came across this one while working on a platform upgrade for PHP 7.3 from 5.3 today... Since I'm storing this value for use later on, I wanted to be sure I didn't wind up with a 'partially' serialized array that may break things downstream.

Thanks kenorb for getting me onto the right path (I upvoted ur answer). The following is working nicely for me.

Code:

$a1 = [
  'foo' => 'bar',
  'bar' => [
    'test' => 'test'
  ],
  'foobar' => 'fizzbuzz'
];

$a2 = [
  'foobar' => 'fizzbuzz',
  'herp' => [
    'derp' => 'herpderp'
  ]
];

$diff = array_diff(array_map('serialize', $a1), array_map('serialize', $a2));

$multidimensional_diff = array_map('unserialize', $diff);

print_r($multidimensional_diff);

Output:

Array
(
    [foo] => bar
    [bar] => Array
        (
            [test] => test
        )

)

Solution 7 - Php

This is my solution for a similar problem. I want to compare two associative arrays and return the changed values, but some of the elements are arrays. So if I use

array_diff_assoc

, it gives me "Array to string error". My function will also compare the elements which are arrays and if there's a difference, it will return the array element. It is still a work in progress and not tested extensively. For example:

public static $example1 = [
    'id' => 1,
    'status' => 2,
    'elements' => ['test', 'example'],
    'different' => ['old' => 5, 'new' => 9]
];

public static $example2 = [
    'id' => 1,
    'status' => 3,
    'elements' => ['test', 'example'],
    'different' => ['old' => 5, 'new' => 8]
];

public static function test(){
    die(var_dump(self::udiffAssoc(self::$example1, self::$example2)));
}

public static function udiffAssoc(array $array1, array $array2)
{
    $checkDiff = function ($a, $b) use (&$checkDiff) {
        if (is_array($a) && is_array($b)) {
            return array_udiff_assoc($a, $b, $checkDiff);
        } elseif (is_array($a)) {
            return 1;
        } elseif (is_array($b)) {
            return -1;
        } elseif ($a === $b) {
            return 0;
        } else {
            return $a > $b ? 1 : -1;
        }
    };
    return array_udiff_assoc($array1, $array2, $checkDiff);
}

if you run ::test it will return:

array(2) {
    ["status"]=>
    int(2)
    ["different"]=>
    array(2) {
    ["old"]=>
    int(5)
    ["new"]=>
    int(9)
  }
}

Solution 8 - Php

I've got the same error and found the following bug report for php:

https://bugs.php.net/bug.php?id=60198

> Some of the array_* functions that compare elements in multiple arrays > do so by (string)$elem1 === (string)$elem2. > > If $elem1 or $elem2 is an array, then the array to string notice is > thrown. > > Two examples of functions that can throw this are array_intersect() > and array_diff(). > > If these functions are not expected to take arrays with other arrays > as values, this should be mentioned on the documentation pages.

That report describes, why php throws an error on comparing a multi-dimensional array.

Solution 9 - Php

What about my solution:

$diff = strcmp(serialize($arr1), serialize($arr2))

Solution 10 - Php

We're getting cast to string warning because array_diff converts the elements to string before comparing... and we've passed ints, the key is to add a wrapper object since objects can be casted to string, then when comparison is done we're returning them back to ints as below

Or-

Your can just use a library https://github.com/voku/Arrayy#diffarray-array-static its have method called diff() can compare straight integer and other data types as well

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2963765View Question on Stackoverflow
Solution 1 - PhpViacheslav KondratiukView Answer on Stackoverflow
Solution 2 - PhpE.A.TView Answer on Stackoverflow
Solution 3 - PhpkenorbView Answer on Stackoverflow
Solution 4 - PhpmaxView Answer on Stackoverflow
Solution 5 - PhpJim WrightView Answer on Stackoverflow
Solution 6 - PhpZhuRenTongKuView Answer on Stackoverflow
Solution 7 - PhpTheBlueAssasinView Answer on Stackoverflow
Solution 8 - PhpTrendfischerView Answer on Stackoverflow
Solution 9 - PhpA. FülöpView Answer on Stackoverflow
Solution 10 - PhpndotieView Answer on Stackoverflow