为什么array_diff()给Array提供字符串转换错误?

时间:2013-11-07 07:55:47

标签: php arrays multidimensional-array array-difference

我得到以下行的数组到字符串转换错误:

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

此处,$arr是从JSON文件解码的数组。使用is_array()函数,我能够验证两个参数都是数组。有人能指出我的问题

$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>";
}

9 个答案:

答案 0 :(得分:30)

根据它:

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

你的一个数组是多维的。

array_diff仅检查n维数组的一维。当然,您可以使用array_diff($array1[0], $array2[0]);

检查更深层次的维度

答案 1 :(得分:16)

是的,严格的答案是因为&#34;你的一个数组是多维的。&#34;

另一个有用的注释可能是 - ,具体取决于您进一步解析实际差异的需求 - 考虑首先使用以下方法测试数组:

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

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

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

所有这些选项都将比较整个数组树,而不仅仅是顶层。

答案 2 :(得分:9)

由于array_diff只能处理一个维度,因此您可以:

答案 3 :(得分:6)

根据函数的PHP文档

  

注意:   当且仅当(字符串)$ elem1 ===(字符串)$ elem2时,两个元素被认为是相等的。用文字表示:当字符串表示相同时。

有关更多信息,请参阅http://php.net/manual/en/function.array-diff.php

答案 4 :(得分:2)

您可以在array_diff() documentation中看到:

  

当且仅当(string)$ elem1 ===,两个元素才被认为是相等的   (字符串)$ elem2。换句话说:当字符串表示形式为   一样。

因此,您似乎无法将此函数与多维数组一起使用,或者实际上无法将任何不能转换为字符串的值使用。这是因为该函数会将值强制转换为string进行比较。

您可以编写自己的函数来递归检查数组是否有差异-实际上,以下内容来自上面链接的文档的注释。

您可以看到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; 
}

答案 5 :(得分:1)

我遇到了同样的错误,并为php找到了以下错误报告:

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

  

一些用于比较多个数组中元素的array_ *函数   这样做(字符串)$ elem1 ===(字符串)$ elem2。

     

如果$ elem1或$ elem2是一个数组,那么数组到字符串的通知是   抛出。

     

可以抛出此函数的两个函数示例是array_intersect()   和array_diff()。

     

如果不希望这些函数将数组与其他数组一起使用   作为值,这应该在文档页面上提到。

该报告描述了为什么php在比较多维数组时会抛出错误。

答案 6 :(得分:1)

在尝试从今天的5.3到PHP 7.3的平台升级时,请注意这一点...由于我存储了此值以备后用,所以我想确保自己不会“部分地”结束序列化的数组,可能会破坏下游数据。

感谢kenorb让我走上正确的道路(我对您的回答表示支持)。以下对我来说很好用。

代码:

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

输出:

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

)

答案 7 :(得分:1)

这是我针对类似问题的解决方案。我想比较两个关联数组并返回更改后的值,但是某些元素是数组。因此,如果我使用

array_diff_assoc

,它给我“数组到字符串错误”。我的函数还将比较数组中的元素,如果有区别,它将返回数组元素。这项工作仍在进行中,未经广泛测试。 例如:

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

如果运行:: test,它将返回:

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

答案 8 :(得分:0)

那我的解决方案呢?

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