0

I need to find and replace all the values of rows of a CSV using PHP;

I am trying this but its replacing even the headers to 0 and row values are not doubling as it suppose to.

public function checkForNumericValues()
    {
        // Read the columns and detect numeric values
        if (($this->handle = fopen($this->csvFile, "r")) !== FALSE) 
        {
            
            $fhandle = fopen($this->csvFile,"r");
            $content = fread($fhandle,filesize($this->csvFile));

            while (($this->data = fgetcsv($this->handle, 1000, ",")) !== FALSE) 
            {
                $this->num = count($this->data);
                
                // Skipping the header
                if($this->row == 1)
                { 
                    $this->row++; 
                    continue; 
                }
                $this->row++;
                

                // Check and replace the numeric values
                for ($j=0; $j < $this->num; $j++) 
                {
                    if(is_numeric($this->data[$j]))
                    {
                        $content = str_replace($this->data[$j], $this->data[$j] * 2, $content);
                    }
                    else
                    {
                        $content = str_replace($this->data[$j], 0, $content);
                    }
                }
                break;
                // print_r($content);
            }
            $fhandle = fopen($this->csvFile,"w");
            fwrite($fhandle,$content);
            fclose($this->handle);
        }
        echo "Numeric and String values been changed in rows of the CSV!";
    }

CSV is like this: enter image description here

4
  • Why do you open the file twice? Commented Jun 9, 2021 at 20:02
  • What is the initial value of $this-row? Commented Jun 9, 2021 at 20:03
  • Why do you use class properties for things that should be temporary variables, like $this->num and $this->handle? Commented Jun 9, 2021 at 20:10
  • The break statement breaks after the first row of the file. Why? Commented Jun 9, 2021 at 20:12

1 Answer 1

1

You shouldn't update the entire $contents when you're processing each field in the CSV, just update that field. Your str_replace() will replace substrings elsewhere in the file; for instance, if the current field contains 5, you'll replace all the 5's in the file with 10, so 125 will become 1210.

You can do it correctly by replacing the element in the $this->data array. After you do that, you can then join them back into a string with implode(). Then you can keep all the updated lines in a string, which you write back to the file at the end.

You can skip the header line by calling fgets() before the while loop.

public function checkForNumericValues()
{
    // Read the columns and detect numeric values
    if (($this->handle = fopen($this->csvFile, "r")) !== FALSE) 
    {
        $output = "";
        $output .= fgets($this->csvFile); // Copy header line to output

        while (($this->data = fgetcsv($this->handle, 1000, ",")) !== FALSE) 
        {
            $this->num = count($this->data);
                
            // Check and replace the numeric values
            for ($j=0; $j < $this->num; $j++) 
            {
                if(is_numeric($this->data[$j]))
                {
                    $this->data[$j] *= 2;
                }
                else
                {
                    $this->data[$j] = 0;
                }
            }
            $output .= implode(',', $this->data) . "\n";
        }
        fclose($this->handle);
        $fhandle = fopen($this->csvFile,"w");
        fwrite($fhandle,$output);
        fclose($fhandle);
    }
    echo "Numeric and String values been changed in rows of the CSV!";
}
Sign up to request clarification or add additional context in comments.

5 Comments

thanks for the reply I am getting this error: fgets() expects parameter 1 to be resource, string given
I have added this and its fixed $stdin = fopen($this->csvFile, 'r'); $output .= fgets($stdin); I am getting extra line added into the csv with all 0's.
Only need to figure why this extra lines of 0's coming from
Maybe there's a blank line at the end of the file?
` // Skip the header if($this->row == 1){ $this->row++; continue; } $this->row++;` added this part now it works

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.