8

我有 4 列的 .csv 文件。删除与第一列的 id 相同的行的最简单方法是什么?这是我卡住的地方:

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);
}

不幸的是,数据库不是一种选择。

4

5 回答 5

7
$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');
于 2013-04-19T11:52:52.287 回答
2

我最近为取消订阅时事通讯做了类似的事情,这是我的代码:

$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;
}

这使用临时文件方法逐行写出 csv 以避免内存错误。然后,一旦创建了新文件,它就会删除原始文件并重命名临时文件。

您可以修改此代码,使其查找 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');
于 2012-01-19T18:58:03.567 回答
1
$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);
}
于 2010-11-01T18:50:22.557 回答
0

你可以做:

$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;
    }
}

基本上,您运行 throws 每一行并检查 id 是否与 get 参数中发送的 id 不匹配,如果不匹配,则将该行写入新容器/变量。

然后将值重写$new到文件中,这应该可以正常工作:

  • 文件有多大
  • 你有在线的 CSV 标题0吗?
于 2010-11-01T18:50:53.610 回答
0

我找到了一个解决方案,不需要复制文件。

$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);
}

注意:这些 fopen 命令中只有一个可能会失败,从而泄漏第二个命令的句柄。最好独立检查两个句柄并在错误时关闭它们。

于 2021-12-07T11:21:24.737 回答