请正确使用array_diff()

时间:2014-04-22 23:40:43

标签: php array-difference

我有以下代码:

$l1 = file($file1['tmp_name']);// get file 1 contents
$l2 = file($file2['tmp_name']);// get file 2 contents
$l3 = array_diff($l1, $l2);// create diff array

以下是文件: 文件1:

6974527983
6974527984
6974527985

文件2:

6974527983

$ l3应该是:

6974527984
6974527985

但是,它只是吐出文件1中的值:

6974527983
6974527984
6974527985

我设置正确吗?

更新 - 使用print_r(),我已经验证正在加载的文件被正确解析为数组: 档案1 -

Array ( [0] => 6974527983 [1] => 6974527984 [2] => 6974527985 ) 1

档案2 -

Array ( [0] => 6974527983 ) 1

所以我不相信文本文件中的换行符有任何问题。

3 个答案:

答案 0 :(得分:0)

如果每个数字都在一个新行上,您可以尝试按换行符拆分每个文件并以这种方式比较数组。

$l1 = explode("\n", file($file1['tmp_name']));
$l2 = explode("\n", file($file2['tmp_name']));
$l3 = array_diff($l1, $l2);

答案 1 :(得分:0)

使用以下示例,您可以看到array_diff()按预期工作:

$a = array(
    6974527983,
    6974527984,
    6974527985
);

$b = array(
    6974527983
);

var_dump(array_diff($a, $b));

输出:

array(2) {
  [1] =>
  int(6974527984)
  [2] =>
  int(6974527985)
}

这表明file($file2['tmp_name'])是您的问题所在。尝试:

var_dump(file($file2['tmp_name']));

检查文件的内容。

答案 2 :(得分:0)

好的,我会发一个答案,因为我认为这会解决你的问题。

在不了解文件结构的情况下,我们只能假设行结尾可能存在问题。有三种可能的行结尾:

  1. Unix:\n
  2. Windows:\r\n
  3. Classic mac:\r
  4. 我在这里看到两种可能的情况:

    1. 每个文件中的行结尾彼此不同
    2. 两个文件中的行结尾为\r(经典mac)
    3. 正如Mark Ba​​ker指出的那样,您应该使用FILE_IGNORE_NEW_LINES标志作为每个file()来电的第二个参数。据我所知,如果一个文件有Unix而另一个文件有Windows行结尾,我可以解决这个问题。

      但是,在至少有一个文件具有' \ r'行尾。在这种情况下,有一个可能有帮助的ini设置:

      ini_set('auto_detect_line_endings', true);
      

      咨询auto_detect_line_endings的文档:

        

      启用后,PHP将检查fgets()和file()读取的数据,以查看它是使用Unix,MS-Dos还是Macintosh行结束约定。

           

      这使PHP能够与Macintosh系统互操作,但默认为Off,因为在检测第一行的EOL约定时,性能会受到很小的影响,并且因为在Unix系统下使用回车符作为项目分隔符的人会体验非向后兼容的行为。

      所以,TL; DR:调试你的行结尾以确保你知道发生了什么(使用filehexdump或类似),并使用{{1的组合}和auto_detect_line_endings

      希望这会有所帮助:)