0

I am generating and exporting a CSV through PHP and after some modifications from my team, now it results that inside a column, double quotation marks are being generated. I generate it through my terminal by executing this Shell script with the CakePHP Console.

/var/www/mysite.new/trunk/app/Console/cake Csv mysite.uk

The problem is that I already tried many techniques to strip them off such as: stripslashes(), str_replace(), trim()

On my last modification, I tried to apply the str_replace function.

   foreach ($persons_csv as $person_csv){
       /* The part where I get the data for stripping off the quotation marks */
        $mail = $person_csv['Person']['email'];
        $name = str_replace('"', '', $person_csv['Person']['name']);
        $surname = str_replace('"', '', $person_csv['Person']['surname']);
         /* REST OF THE CODE */

    }

Nevertheless, it only happens to surnames and names that have more than one word in which the quotations marks are being generated. Surnames and names that are consisting of one word, they appear to be fine. Still, there are some anomalies probably inside names that have whitespace and therefore double quotations marks are being generated again. I am not quite sure why this is ocurring. I can attach you two screenshots so you can have a better understanding of the problem.

enter image description here

enter image description here

If you have any idea of what it might be, it would be really appreciating. This is the rest of my code in which I am generating the CSV.

   private function addRow($row) {
            $rows_deleted = 0;
         if (!empty($row)){
            fputcsv($this->buffer, $row, $this->delimiter, $this->enclosure);
         } else {
                return false;
         }
    }

   private function renderHeaders() {
        header("Content-type:application/vnd.ms-excel");
        header("Content-disposition:attachment;filename=" . $this->filename);
    }

   private function setFilename($filename) {
        $this->filename = $filename;
        if (strtolower(substr($this->filename,   -4)) != '.csv') {
            $this->filename .= '.csv';
        }
    }

  private function render($filename = true, $to_encoding = null, $from_encoding = "auto") {
    if(PAIS) {
        if ($filename) {
            if (is_string($filename)) {
                $this->setFilename($filename);
            }
            $this->renderHeaders();
        }
        rewind($this->buffer);
        $output = stream_get_contents($this->buffer);

       $url = '/var/www/mysite.new/trunk/' .'app'.DS.'webroot'.DS.'csv'.DS.PAIS.DS.$this->filename;
        $gestor = fopen($url, "w+") or die("Unable to open file");
        if(file_exists($url)){
            file_put_contents($url, $output);
            chmod($url, 0777);
            fclose($gestor);
        } else {
            return false;
        }
    } else {
        return false;
    }
}

 public function csv_persons($persons_csv) {
    $this->array_final = [self::NAME, self::SURNAME]; 
    date_default_timezone_get('Europe/Madrid');
    $d = date("Ymd");
    $this->addRow($this->array_final);

    foreach ($persons_csv as $person_csv){
        $name = str_replace('"', '', $person_csv['Person']['name']);
        $surname = str_replace('"', '', $person_csv['Person']['surname']);

        $apos = ''';
        $pos = strpos($surname, $apos);
        if($pos !== false) {
            $surname = str_replace(''', '\'', $surname);
        }

        $arr = array();
        $arr[$this->getArrayKeyIndex($this->array_final, self::NAME)] = $name;
        $arr[$this->getArrayKeyIndex($this->array_final, self::SURNAME)] = $surname;

        $this->addRow($arr);
    }
    $filename = 'PERSON_PROFILE_' . $d;
    $this->render($filename);
}

Thanks

Oris Sin
  • 1,023
  • 1
  • 13
  • 33
  • Not sure how you generate the CSV, but have a look through https://stackoverflow.com/questions/1800675/write-csv-to-file-without-enclosures-in-php to see if there is anything in there to help. – Nigel Ren May 27 '20 at 08:15
  • I editted my post. – Oris Sin May 27 '20 at 08:31
  • What does the raw `$person_csv['Person']['name']` before any tampering contain exactly? Probably no quotes, right? What does the resulting CSV contain exactly, **as raw text**? Probably something like `...,"Kevin Sean",...`, right? Then this is all working perfectly as it's supposed to. CSV values *can* optionally be quoted, there's nothing wrong there. If Excel (?) is displaying those quotes as part of the value, that's just Excel messing up. – deceze May 27 '20 at 08:42
  • Well, the field ``$person_csv['Person']['name']`` doesn't contain any quotes at all when I take it from my database. I was having this idea that it might be Excel messing up my columns. – Oris Sin May 27 '20 at 08:46
  • So, opening the CSV in a text editor, you see `...,"Kevin Sean",...`, right? Then you need to set the correct options when opening the file in Excel. – deceze May 27 '20 at 08:51
  • My headers are NAME; SURNAME; and my content is like this: ``"Aathavan ";"Loganayagam "``. Nevertheless, as I said before there are cases in which my columns in the text editor appear like this also: ``John;Brookes;``, no quotation marks at all. My delimiter is semicolon, not commas. – Oris Sin May 27 '20 at 09:12
  • 1
    So, your CSV is a *valid CSV file*, or SSV file I suppose. There is nothing wrong there. You *want* those quotes there. You just need to tell Excel that there are quotes. Probably by opening the file using Import and selecting the correct options for the used delimiters. – deceze May 27 '20 at 09:16

1 Answers1

0

Instead of using fputcsv, try implode.

Ref: https://www.php.net/manual/en/function.implode.php

Update 1: You have to be sure that your value does not contain , (comma)

Update 2: If you are concern with the idea about that quoted text will be problem for your CSV datasheet, than you need to know that CSV is designed to that if there is any space between the value. So you don't have to worry about that. Any CSV parser will understand the quoted values properly.

Rafik Farhad
  • 1,182
  • 2
  • 12
  • 21
  • You gonna have a [Bad Time](https://i.imgflip.com/2kowy.jpg) with this should your values contain a `,`… – deceze May 27 '20 at 08:49
  • Yes, but the question author is not interested to any escaping methods, that's why I suggest this method. Look, he is checking each value for multiple values, by using implode he has to check only one `, (comma)`. Got it? – Rafik Farhad May 27 '20 at 09:04
  • At the very least you'd have to demonstrate how to handle that case with the comma… – deceze May 27 '20 at 09:09
  • @deceze Yes, I agree, I have updated the answer in a cleared form. Now it's up to the author to use it or not. Thanks. – Rafik Farhad May 27 '20 at 09:12
  • Finally, the problem was my Ubuntu's Excel. I opened it in the Excel Google Docs and was working like a charm. Thanks for all your suggestions. – Oris Sin May 28 '20 at 07:25