1

I have a CSV file called employee_data.csv. It contains employee records formatted like so:

JANE WILLIAMS,6/8/1998,55846874E,4323
PETER JONES,15/01/1982,56897547Q,1234
JAMES O'BRIEN,09/05/2001,25689514W,3432

I want to delete a selected row within the csv file. To achieve this, I will simply copy the 2 rows within the csv file that I do not want to delete to a new_employee_data.csv file and delete the old one.

<?php
$dataSrc = "persistence/employee_data.csv";
$dataDest = "persistence/new_employee_data.csv";

$dataFile = fopen($dataSrc, "r") or die("Unable to open file!");
$outFile = fopen($dataDest, "w") or die("Unable to open file!");

$i=0;  //index for the array
    while(!feof($dataFile)) {
    $csv = fgetcsv($dataFile); //read a line from the CSV file
    //$csv = [ANE WILLIAMS,6/8/1998,55846874E,4323];
    //add check to remove row
    print_r($csv);
        if($csv[2] == '55846874E') continue; //skip to next itteration

        fputcsv($outFile, $csv);
}

fclose($dataFile);
fclose($outFile);
?>

The code above takes the contents of $dataFile and writes it to $outFile line by line, if the 3rd column = '55846874E' it will skip writing that line. The csv array contains the rows within the employee_data.csv file.

The elements in the $csv array are as follows.

Array ( [0] => JANE WILLIAMS [1] => 6/8/1998 [2] => 55846874E [3] => 4321 )
Array ( [0] => PETER JONES [1] => 15/01/1982 [2] => 56897547Q [3] => 1234 ) 
Array ( [0] => JAMES O'BRIEN [1] => 09/05/2001 [2] => 25689514W [3] => 8475 ) 

It removes the first row of the file - JANE WILLIAMS,6/8/1998,55846874E,4323

Now in the new_employee_data.csv is the two undeleted records.

"PETER JONES",15/01/1982,56897547Q,1234
"JAMES O'BRIEN",09/05/2001,25689514W,8475

This is exactly what I want it to do however I received this warning when I run it in the browser:

fputcsv() expects parameter 2 to be array, boolean given in line 25

It's having a problem with fputcsv($outFile, $csv); and I've no idea why, any suggestions of how to fix this?

2
  • Per the php docs: fgetcsv() returns NULL if an invalid handle is supplied or FALSE on other errors, including end of file. Which tells me that it most likely reached the end of the file Commented Feb 17, 2018 at 3:03
  • Hi again, thanks for posting this as a separate question, I was on my way home and had to do some running ... lol sorry Commented Feb 17, 2018 at 3:05

1 Answer 1

2

I would change the while loop So instead of

while(!feof($dataFile)) {
    $csv = fgetcsv($dataFile); 

like this

while(false !== ($csv = fgetcsv($dataFile))){

You can see an example of this usage on the PHP website here

What probably happens is there is a extra return at the end of the file, so the feof doesn't catch it, and then you get boolean false for the fgetcsv. For example like this (where \n is a new line):

JANE WILLIAMS,6/8/1998,55846874E,4323\n
PETER JONES,15/01/1982,56897547Q,1234\n
JAMES O'BRIEN,09/05/2001,25689514W,3432\n
\n
\eof

So we can combine these (so you wont need the line under the while loop) and just get the data from the same place we do the loop condition, this way when it returns false it will just drop the loop. It's important to be careful with the number of = in this as a single one is assignment and the !== is strict type comparison. So we can break this down a bit and in English what this says.

  • pull a row and process it with fgetcsv setting $csv to it's value, parentheses get priority
  • if $csv is boolean false then the loop condition is false an it ends. So basically if false(boolean) not equal to the result of fgetcsv($dataFile) then it's true otherwise it's false.

It would work basically the same like this

while($csv = fgetcsv($dataFile)){

I tend to like the long hand version, because it's easier to see that we are assigning and not comparing. For example you could glance at the above version and then think it should be == instead of = so the first version just makes that a bit more obvious. Putting the false on the left hand side is basically done for the same reason (and because it's essentially a constant, so putting it on the left avoids mistakes like below false = $csv wont work).

Misplacing an = in a condition can actually be one of the harder bugs to figure out, because it's completely legal. So that is kind of a "pro tip" to put function calls and constants on the left when doing comparison.

hope that helps!

Sign up to request clarification or add additional context in comments.

3 Comments

It was a problem within my file which was the reason it wasn't working!,Your logic was spot on, Thanks very much, great help.
Sure, I work with CSV files everyday for the last 5 years, I use SplFileObject class now, but pretty much same diff. I just like the class because it has line seeking, for files with a dynamic number of headers it can be nice because you can do $fileObj->seek($num_headers)
extra return at the end of the file was what pointed me to fixing the issue as there was an empty line at the end of the file. Removing that empty line fixed the issue for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.