Tiago Castro
Tiago Castro

Reputation: 421

How can I read and remove line from CSV file with PHP?

I have a big csv file that contains an column with emails. I need to create a script that read this csv file, send an email and than remove the row. Is it possible to do without creating an temp file? If in case I store it on the database, would it be the best way to do this?

My code:

if (($handle = fopen("emails.csv", "r")) !== FALSE) {
 while (($line = fgetcsv($handle, 1000, ",")) !== FALSE) {
       $mail->parseTextandSendMail($line);
      //Need to remove the $line
  $row++;
 }
fclose($handle);

Thanks

Upvotes: 3

Views: 3788

Answers (1)

Don't Panic
Don't Panic

Reputation: 41820

It occurred to me that it could work if you read lines from the end of the file instead of the beginning. I got some help from here figuring out how to do that, and incorporated some of the code from an answer there into a function that seeks backward from the end of the file to the beginning of the last line.

function lineStart($file) {
    $position = ftell($file);
    while (fgetc($file) != "\n") {
        fseek($file, --$position);
        if ($position == 0) break;
    }
    return $position;
}

With that function, you can repeatedly read the last line end then truncate the file to the length indicated by the file position at the beginning of that line.

$file = fopen('emails.csv', 'r+');       // open for read/write

fseek($file, -1, SEEK_END);              // move to end of file

while (fstat($file)['size']) {
    lineStart($file);                    // move to beginning of line
    $line = fgetcsv($file);
    $mail->parseTextandSendMail($line);  // do your email thing
    ftruncate($file, lineStart($file));  // truncate from beginning of line
}

fclose($file);

I don't know if I think this is generally a good idea (a database seems like it would be much easier to deal with), but I just wanted to figure out if there was a way to accomplish it, and this does seem to work in my limited testing.

Upvotes: 5

Related Questions