简体   繁体   English

从 CSV 文件中删除行

[英]Remove Line From CSV File

I have .csv file with 4 columns.我有 4 列的 .csv 文件。 What's the easiest way to remove a line identical with the id of the first column?删除与第一列的 id 相同的行的最简单方法是什么? Here's where I got stuck:这是我卡住的地方:

if($_GET['id']) {
    $id = $_GET['id'];
    $file_handle = fopen("testimonials.csv", "rw");

    while (!feof($file_handle) ) {
        $line_of_text = fgetcsv($file_handle, 1024);    
        if ($id == $line_of_text[0]) {
            // remove row
        }
    }
    fclose($file_handle);
}

Unfortunately, databases were not a choice.不幸的是,数据库不是一种选择。

$table = fopen('table.csv','r');
$temp_table = fopen('table_temp.csv','w');

$id = 'something' // the name of the column you're looking for

while (($data = fgetcsv($table, 1000)) !== FALSE){
    if(reset($data) == $id){ // this is if you need the first column in a row
        continue;
    }
    fputcsv($temp_table,$data);
}
fclose($table);
fclose($temp_table);
rename('table_temp.csv','table.csv');

I recently did a similar thing in for a newsletter unsubscription, heres my code: 我最近做了一个类似的事情,通讯取消订阅,继承我的代码:

$signupsFile = 'newsletters/signups.csv';
$signupsTempFile = 'newsletters/signups_temp.csv';
$GLOBALS["signupsFile"] = $signupsFile;
$GLOBALS["signupsTempFile"] = $signupsTempFile;


function removeEmail($email){
    $removed = false;
    $fptemp = fopen($GLOBALS["signupsTempFile"], "a+");
    if (($handle = fopen($GLOBALS["signupsFile"], "r")) !== FALSE) {
        while (($data = fgetcsv($handle)) !== FALSE) {
        if ($email != $data[0] ){
            $list = array($data);
            fputcsv($fptemp, $list);
            $removed = true;
        }
    }
    fclose($handle);
    fclose($fptemp);
    unlink($GLOBALS["signupsFile"]);
    rename($GLOBALS["signupsTempFile"], $GLOBALS["signupsFile"]);
    return $removed;
}

this uses the temp file method of writing out the csv line by line to avoid memory errors. 这使用临时文件方法逐行写出csv以避免内存错误。 Then once the new file has been created, it deletes the original and renames the temp file. 然后,一旦创建了新文件,它就会删除原始文件并重命名临时文件。

You can modify this code so that it looks for an ID instead of an email address eg: 您可以修改此代码,以便查找ID而不是电子邮件地址,例如:

$id = $_GET['id'];  
$fptemp = fopen('testimonials-temp.csv', "a+");
if (($handle = fopen('testimonials.csv', "r")) !== FALSE) {
    while (($id= fgetcsv($handle)) !== FALSE) {
    if ($id != $data[0] ){
        $list = array($data);
        fputcsv($fptemp, $list);
    }
}
fclose($handle);
fclose($fptemp);
unlink('testimonials.csv');
rename('testimonials-temp.csv','testimonials.csv');

You can do: 你可以做:

$new = '';
while (!feof($file_handle))
{
    $line_of_text = fgetcsv($file_handle, 1024);    
    if ($id != $line_of_text[0])
    {
         $new .= implode(',',$line_of_text) . PHP_EOL;
    }
}

basically you running threw each line and check if the id does NOT match the id sent in the get parameter, if it does not then it writes the line to the new container / variable. 基本上你运行扔每一行,并检查ID 匹配在GET参数发送的ID,如果它那么它写入行至新的容器/变量。

And then rewrite the $new value to the file, this should work ok: 然后将$new值重写为该文件,这应该可以正常工作:

  • How big is the file 文件有多大
  • Do you have a CSV Header on line 0 ? 你在第0行有一个CSV标题吗?

I have found a solution, that does not need to copy the file.我找到了一个解决方案,不需要复制文件。

$file = 'testimonials.csv'
// open two handles on the same file
$input = fopen($file ,'r'); // read mode
$output = fopen($file, 'c'); // write mode

if($input !== FALSE && $output !== FALSE) { // check for error
    while (($data = fgetcsv($input, $CSVLIMIT, $sep)) !== FALSE) {
        if(reset(data) == $id) {
            continue;
        }
        fputcsv($output, $data, $sep);
    }

    // close read handle
    fclose($input);
    // shorten file to remove overhead created by this procedure
    ftruncate($output, ftell($output));
    fclose($output);
}

Note: only one of those fopen commands could fail, leaking the handle for the second one.注意:只有其中一个 fopen 命令可能会失败,从而泄漏第二个命令的句柄。 It would be good, to check both handles independetly and close them on a error.独立检查两个句柄并在出错时关闭它们会很好。

$id = $_GET['id'];
if($id) {
    $file_handle = fopen("testimonials.csv", "w+");
    $myCsv = array();
    while (!feof($file_handle) ) {
        $line_of_text = fgetcsv($file_handle, 1024);    
        if ($id != $line_of_text[0]) {
            fputcsv($file_handle, $line_of_text);
        }
    }
    fclose($file_handle);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM