使用 fgets() 读取文件在每行末尾留下换行符

Reading file with fgets() leaves new line character at the end of each line

当我用制表符作为分隔符分解 .csv 文件的行时,如下所示:

// $handle = some TSV file
while (($line = fgets($handle)) !== false) {
    $fields = explode("\t",$line);
}

如果该行的最后一列为空(或者即使它不是),出于某种原因,$fields 中的最后一个元素将包含换行符 (\n)。这引起了问题,我不太明白为什么会这样,如果是正常的,如何补偿它。

csv 文件典型如下:

col1\tcol2\tcol3\n
col1\tcol2\tcol3\n
...

*\t 和 \n 是文件中真正的制表符和新行。

所以在这种情况下,如果 col3 为空,我的问题就会持续存在。如果它不为空,它甚至可能会这样做。

注意: 问题是我将每一列插入到 MySQL 数据库中,最后一列中有一个换行符。当我将此数据库导出回 CSV 时,它破坏了文件的布局。

所以现在我的问题是:

  1. 这是正常行为吗?

  2. 如果是这样,如果我不能在最后一个 $field 中换行,我该怎么办?

1。由于您使用 fgets(),是的,这是预期的行为,因为您抓住了整行,其中包括末尾的换行符。

2。您可以只使用 fgetcsv() 并将分隔符指定为制表符,例如

$handle = fopen("test.csv", "r");
if ($handle) {
    while (($data = fgetcsv($handle, 4000, "\t")) !== FALSE) {
        var_dump($data);
    }
    fclose($handle);
}

只是在这里添加一个替代解决方案:

您可以使用 file() 将您的文件放入数组中,并使用标志忽略末尾的换行符,因此您可以执行与 fgets() 类似的操作。然后 explode() 每行一个制表符,例如

$data = array_map(function($v){
    return explode("\t", $v);
}, file("yourFile.csv", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));