【问题标题】:PHP Comparing two CSV files and highlight the differencePHP比较两个CSV文件并突出差异
【发布时间】:2014-06-15 23:31:17
【问题描述】:

我想比较两个 CSV 文件并突出显示差异。目前我有一个小脚本,可以读取 CSV 文件并将内容打印到浏览器上。这些文件的列号结构相同,但某些行中的值不同,我想强调这种差异,但不确定从哪里开始:

PHP 代码:

<?php
$file = fopen("try.csv","r");
$file2 = fopen("try2.csv", "r");

if(! feof($file)){

    while($data = fgetcsv($file))
    {
        foreach($data as $element){
            echo $element.'   ';
        }

        echo '<br />';


    }
}

echo '<br />';
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>New File<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";
echo '<br />';

if(! feof($file2)){

    while($data = fgetcsv($file2))
    {
        foreach($data as $element2){
            echo $element2.'   ';
        }

        echo '<br />';


    }
}


fclose($file);
?>

知道变量$element 和$element2 保存CSV 内容我怎样才能找到差异......?

【问题讨论】:

    标签: php csv


    【解决方案1】:

    fgetcsv 为当前行返回一个数组,因此如果内存不是问题,您可以拉入第一个 csv 的行并将每一行存储在一个数组中,如$csv_1,然后第二个为@ 987654324@,然后使用array_udiff 查找不重叠的行。

    function row_compare($a, $b)
    {
        if ($a === $b) {
            return 0;
        }
    
        return (implode("",$a) < implode("",$b) ) ? -1 : 1;
    }
    
    $file1 = new SplFileObject("try.csv");
    $file1->setFlags(SplFileObject::READ_CSV);
    
    $file2 = new SplFileObject("try2.csv");
    $file2->setFlags(SplFileObject::READ_CSV);
    
    foreach ($file1 as $row) {
        $csv_1[] = $row;
    }
    
    foreach ($file2 as $row) {
        $csv_2[] = $row;
    }
    
    $unique_to_csv1 = array_udiff($csv_1, $csv_2, 'row_compare');
    $unique_to_csv2 = array_udiff($csv_2, $csv_1, 'row_compare');
    
    $all_unique_rows = array_merge($unique_to_csv1,$unique_to_csv2);
    
    foreach($all_unique_rows as $unique_row) {
        foreach($unique_row as $element) {
            echo $element . "   ";
        }
        echo '<br />';
    }
    

    【讨论】:

    • 您好,当我尝试您的回答时,我收到多个此错误:Notice: Array to string conversion in /Applications/MAMP/htdocs/Comp/test.php on line 15
    • 您是否要回显$all_unique_rows?这是不允许的,因为 echo 输出的值可以转换为字符串(非标量变量不能)。尝试print_r($all_unique_rows) 或者如果您要为用户输出,则需要一个用于外部行数组的 foreach 循环和一个用于获取该行的每个字段的值的内部 foreach 循环。更新了答案以使这一点更清楚。
    • 非常感谢..据我所知,这显示了所有没有变化的唯一行..?
    • 我假设两个独立的 CSV 可能具有重叠数据。这将输出数组$unique_to_csv1 中file1 独有的行(因此它们出现在file1 中,而不是file2 中),并将输出数组$unique_to_csv2 中file2 独有的行。如果您需要指出找到了唯一行的文件,我会跳过array_merge 步骤并处理带有一些标题的第一个数组,例如“这些行是文件1 但不是文件2”,然后是第二个数组的相反。
    • 另外,我最初错误地认为array_diff 将处理数组数组并将子数组视为变量(因此它将行简单比较为没有更深入地研究数组内容),但事实证明它只返回一个空数组。所以我更新了使用array_udiff 的答案,它使用回调,回调中的比较使用implode 将行数组转换为长字符串。在任何情况下,它都不会突出显示在 CSV 之间更改了哪些字段,只是表明整个行是唯一的。
    【解决方案2】:

    这段代码需要我一些时间,但现在,它可以是最简单的吗?

    $filename="nomes.csv"; //lista completa 
    $base="track.opened.csv"; //mark if it is on here 
    $NOWcodes = array();
    
    $file = fopen($base, 'r'); //registred opened 
    while (($line = fgetcsv($file)) !== FALSE) { array_push($NOWcodes, $line[0]);  }
    fclose($file);
    
    $file = fopen($filename, 'r'); //all nomes 
    while (($line = fgetcsv($file)) !== FALSE) {
    
    if(!in_array($line[0],$NOWcodes)){$inscrito='yellow;';}
    else{$inscrito='#9999ff;';} 
    
    echo '<span style="background-color: '.$inscrito.'" title="'.$line[0].'">'.$line[2].'</span><br>'; }
    fclose($file);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-08
      • 2013-06-17
      • 2016-12-24
      • 1970-01-01
      • 2017-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多