programing

array_diff()가 어레이에서 문자열 변환 오류를 발생시키는 이유는 무엇입니까?

nicescript 2022. 10. 10. 18:49
반응형

array_diff()가 어레이에서 문자열 변환 오류를 발생시키는 이유는 무엇입니까?

다음 행에서 어레이에서 문자열로 변환 오류가 발생합니다.

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

이에 따르면:

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차원 배열의 1차원만 체크합니다.물론, 다음을 사용하여 더 깊은 치수를 확인할 수 있습니다.array_diff($array1[0], $array2[0]);

예, 엄격한 답변은 "어레이 중 하나가 다차원"이기 때문입니다.

또 다른 유용한 주의사항은 실제 차이를 더 해석해야 하는 필요에 따라 다음과 같은 방법으로 어레이를 테스트하는 것입니다.

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

이 모든 옵션은 최상위 수준뿐만 아니라 어레이 트리 전체를 비교합니다.

부터array_diff는, 1 차원만을 취급할 수 있습니다.다음 중 하나를 선택할 수 있습니다.

  • 다음과 같은 방법으로 다차원 어레이를 1차원으로 변환할 수 있습니다.

    • 다차원 배열 평탄화. 예:

      while ($arr) {
        list($key, $value) = each($arr); 
        is_array($value) ? $arr = $value : $out[$key] = $value;
        unset($arr[$key]);
      }
      // Now $out is flatten version of $arr.
      
    • 어레이를 시리얼화합니다.예:

      $results = array_diff(array_map('serialize',$a2), array_map('serialize',$a1)); 
      
  • 커스텀 재귀형 함수를 사용합니다.

함수에 대한 PHP 설명서에 따라

참고: 두 요소는 (string) $elem1 === (string) $elem2인 경우에만 동일하게 간주됩니다.단어: 문자열 표현이 동일한 경우.

상세한 것에 대하여는, http://php.net/manual/en/function.array-diff.php 를 참조해 주세요.

array_diff() 매뉴얼에는 다음과 같은 내용이 기재되어 있습니다.

두 요소는 (문자열) $elem1 === (문자열) $elem2인 경우에만 동일하게 간주됩니다.즉, 문자열 표현이 동일한 경우.

따라서 이 함수는 다차원 배열이나 문자열로 변환할 수 없는 값에는 사용할 수 없는 것으로 보입니다.이는 함수가 값을 캐스트하기 때문입니다.string비교할 수 있습니다.

어레이의 차이를 재귀적으로 체크하기 위해 독자적인 함수를 작성할 수 있습니다.실제로 아래는 위에 링크된 문서의 코멘트입니다.

댓글은 여기서 보실 수 있습니다.

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.3에서 PHP 7.3 플랫폼 업그레이드 작업 중 우연히 발견...나중에 사용할 수 있도록 이 값을 저장하기 때문에 다운스트림에서 문제가 발생할 수 있는 '부분적인' 직렬 어레이를 사용하지 않도록 하고 싶었습니다.

올바른 길로 인도해 준 Kenorv에게 감사합니다(답변을 상향 투표했습니다).아래가 나에게 잘 통한다.

코드:

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

)

이것은 비슷한 문제에 대한 저의 해결책입니다.두 개의 연관 배열을 비교하여 변경된 값을 반환하려고 하는데 일부 요소는 배열입니다.그래서 만약에 제가

array_diff_assoc

"Array to string error" 라고 표시됩니다.또한 이 함수는 어레이인 요소를 비교하고 차이가 있을 경우 어레이 요소를 반환합니다.그것은 아직 진행 중인 작업이고 광범위하게 테스트되지 않았다.예를 들어 다음과 같습니다.

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

같은 에러가 발생하고, 다음의 php 에 관한 버그 리포트를 발견했습니다.

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

여러 어레이의 요소를 비교하는 array_* 함수 중 일부는 (string)$elem1 === (string)$elem2로 그렇게 합니다.

$elem1 또는 $elem2가 배열일 경우 배열에서 문자열로의 알림이 느려집니다.

이를 슬로우할 수 있는 함수의 2가지 예로는 array_intersect()와 array_diff()가 있습니다.

이러한 함수가 다른 어레이를 포함한 어레이를 값으로 사용할 것으로 예상되지 않는 경우 매뉴얼 페이지에 기재해야 합니다.

이 보고서에서는 왜 php가 다차원 배열을 비교할 때 오류를 발생시키는지 설명합니다.

솔루션:

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

비교하기 전에 array_diff가 요소를 문자열로 변환하기 때문에 문자열 경고로 캐스트됩니다.ints를 전달했습니다.중요한 것은 오브젝트를 문자열에 캐스트할 수 있기 때문에 래퍼 오브젝트를 추가하는 것입니다.그리고 비교가 완료되면 아래와 같이 ints로 되돌립니다.

아니면...

라이브러리 https://github.com/voku/Arrayy#diffarray-array-static 를 사용하면 됩니다.이것은 diff() 라고 하는 메서드를 가지고 있기 때문에, 스트레이트 정수와 다른 데이터 타입도 비교할 수 있습니다.

언급URL : https://stackoverflow.com/questions/19830585/why-array-diff-gives-array-to-string-conversion-error

반응형