Sarder Iftekhar
Sarder Iftekhar

Reputation: 11

Replace values of a csv file

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

Upvotes: 0

Views: 640

Answers (1)

Barmar
Barmar

Reputation: 781741

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!";
}

Upvotes: 1

Related Questions