Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Update specific row in CSV file

Tags:

php

csv

Is there an effective way to update/delete specific row in CSV file? Every other method included reading contents of entire file, creating temporary file and then replacing old file with it, etc... But let's say, I have big CSV with 10000 records, so this kind of solution would be rather resource-heavy. Let's say, I am unable to use database, so writing to file is the only way of storing data. So, the question is, what would be the most effective way to do it? Thank you in advance!

like image 520
Denis Avatar asked Feb 16 '16 18:02

Denis


3 Answers

You're going to have to read the entire file. Sorry, no way around that. A CSV is a single, flat, text file with randomly sized fields and rows.

You definitely shouldn't be working directly with a CSV for database operations. You ought to pull the data into a database to work with it, then output it back to CSV when you're done.

You don't mention why you can't use a database, so I'm going to guess it's a resource issue, and you also don't say why you don't want to rewrite the file, so I'm going to guess it's due to performance. You could cache a number of operations and perform them all at once, but you're not going to get away from rewriting all or at least some portion of the file.

like image 105
Todd Grigsby Avatar answered Nov 07 '22 09:11

Todd Grigsby


Consider reading the csv line by line into a multi-dimensional array, and at a certain row make your changes. Then, export array data out to csv. Below example modifies the 100th row assuming a 6-column comma delimited csv file (0-5).

Now, if you want to delete the row, then exclude it from $newdata array by conditionally skipping to next loop iteration with continue. Alternatively, if you want to update, simple set current inner array $newdata[$i] to new values:

$i = 0;
$newdata = [];
$handle = fopen("OldFile.csv", "r");

// READ CSV
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {      

    // UPDATE 100TH ROW DATA (TO EXCLUDE, KEEP ONLY $i++ AND continue)
    if ($i == 99) {
        $newdata[$i][] = somenewvalue;          
        $newdata[$i][] = somenewvalue;   
        $newdata[$i][] = somenewvalue;  
        $newdata[$i][] = somenewvalue;
        $newdata[$i][] = somenewvalue;
        $newdata[$i][] = somenewvalue;
        $i++;
        continue;
    }  
    $newdata[$i][] = $data[0];          
    $newdata[$i][] = $data[1];    
    $newdata[$i][] = $data[2];      
    $newdata[$i][] = $data[3];    
    $newdata[$i][] = $data[4];    
    $newdata[$i][] = $data[5];
    $i++;    
}

// EXPORT CSV
$fp = fopen('NewFile.csv', 'w');    
foreach ($newdata as $rows) {
    fputcsv($fp, $rows);
}    
fclose($fp);
like image 33
Parfait Avatar answered Nov 07 '22 09:11

Parfait


Break the CSV into multiple files all in one directory. That way you still have to rewrite files, but you don't have to rewrite nearly as much.

like image 3
Parthian Shot Avatar answered Nov 07 '22 07:11

Parthian Shot