如何通过行号从CSV文件中删除特定行?

4

我想通过URL参数获取的行号来删除CSV文件中的一行。

我在这里看到了一些讨论,但主要是“通过存储在第一列的ID删除一行”等等。我试图像这些讨论中的其他人一样进行操作,但它不起作用。我只改变了条件。

if (isset($_GET['remove']))
{
    $RowNo = $_GET['remove'];   //getting row number
    $row = 1;
    if (($handle = fopen($FileName, "w+")) !== FALSE)
    {
        while (($data = fgetcsv($handle, 1000, ";")) !== FALSE)
        {
//Here, I don't understand, why this condition does not work.
            if ($row != $RowNo)
            {
                fputcsv($handle, $data, ';');
            }
            $row++;
        }
        fclose($handle);
    }
}

我认为,对我来说应该也能够工作,因为只有条件发生了变化。但它并没有。它清除了整个文件。你能帮助我吗?

非常感谢您的任何建议。Daniel。


1
你同时读写同一个文件。 - Justinas
2个回答

1
如果您的 CSV 文件可以放入内存中,则可以选择以下选项:
// Read CSV to memory array
$lines = file($fileName, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);

// Remove element from array
unset($lines[$rowNo - 1]); // Validate that element exists!

// Rewrite your CSV file
$handle = fopen($fileName, "w+");

for ($i = 0; $i < count($lines); $i++) {
    fputcsv($handle, $data, ';');
}

fclose($handle);

如果您的CSV文件无法放入内存中:

使用问题中的代码,将其写入单独的文件中,稍后再用实际文件替换它:

$handle = fopen($FileName, "r");

 // Read file wile not End-Of-File
 while (!feof($fn)) {
    if ($row != $RowNo) {
        file_put_contents($FileName . '.tmp', fgets($fn), FILE_APPEND);
    }

    $row++;
}

fclose($handle);

// Remove old file and rename .tmp to previously removed file
unlink($FileName);
rename($FileName . '.tmp', $FileName);

1
你可以使用 file() 将文件加载为一系列行的数组。
然后删除该行并将文件写回。
// read the file into an array    
$fileAsArray = file($FileName);

// the line to delete is the line number minus 1, because arrays begin at zero
$lineToDelete = $_GET['remove'] - 1;

// check if the line to delete is greater than the length of the file
if ($lineToDelete > sizeof($fileAsArray)) {
    throw new Exception("Given line number was not found in file.");
}

//remove the line
unset($fileAsArray[$lineToDelete]);

// open the file for reading
if (!is_writable($fileName) || !$fp = fopen($fileName, 'w+')) {
    // print an error
    throw new Exception("Cannot open file ($fileName)");
}

// if $fp is valid
if ($fp) {
    // write the array to the file
    foreach ($fileAsArray as $line) {
        fwrite($fp, $line);
    }

    // close the file
    fclose($fp);
}

如果你有一个Unix系统,你也可以使用sed命令:
exec("sed -e '{$lineToDelete}d' {$FileName}");

记得清理命令参数,如果使用了用户输入: https://www.php.net/manual/de/function.escapeshellcmd.php

1
谢谢,它有效。我只需要在每行末尾添加“\r\n”。 - Daniel Vácha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接