Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enclosing every field with double quotes in CSV file using PHP?

I need to put all strings and number with double quotes in CSV file using PHP.

How can I create CSV file from PHP in all data within double quotes ?

I am using this code to generate CSV - I am using codeigniter framework

$array = array(
    array(
     (string)'XXX XX XX',
     (string)'3',
     (string)'68878353',
     (string)'',
     (string)'[email protected]',
    ),
);

$this->load->helper('csv');
array_to_csv($array, 'blueform.csv'); 

Output I am getting:

"XXX XX XX",3,68878353,,[email protected]

Expected Output:

"XXX XX XX","3","68878353","","[email protected]"

Code of array_to_csv

if (!function_exists('array_to_csv')) {
    function array_to_csv($array, $download = "") {
        if ($download != "") {   
            header('Content-Type: application/csv');
            header('Content-Disposition: attachement; filename="' . $download . '"');
        }

        ob_start();
        $f = fopen('php://output', 'w') or show_error("Can't open php://output");
        $n = 0;
        foreach ($array as $line) {
            $n++;
            if (!fputcsv($f, $line)) {
                show_error("Can't write line $n: $line");
            }
        }
        fclose($f) or show_error("Can't close php://output");
        $str = ob_get_contents();
        ob_end_clean();

        if ($download == "") {
            return $str;
        } else {
            echo $str;
        }
    }
}

Thank you in advance

like image 524
Anudeep GI Avatar asked Jul 22 '15 09:07

Anudeep GI


2 Answers

When building a CSV in PHP, you should use the fputcsv function available from PHP 5

From the documentation, there's the following parameters:

int fputcsv ( resource $handle , array $fields [, string $delimiter = "," [, string $enclosure = '"' [, string $escape_char = "\" ]]] )

In that you have:

  • the file resource you're writing to
  • The data to put into the CSV
  • The delimiter (the commas usually)
  • The string enclosure (this is the bit you want for your quotes)
  • Escape string (so if your data contains the enclosure character, you can escape it to avoid it looking like a new field)

As the defaults for that are , for the delimiter, and " for the enclosure, you'll not need to add more. That will correctly cover the strings. The numbers are a different matter. There's a work around on this SO question which I found after typing most of this and then having issues with numbers still :

Not happy with this solution but it is what I did and worked. The idea is to set an empty char as enclosure character on fputcsv and add some quotes on every element of your array.

function encodeFunc($value) {
    return "\"$value\"";
}

fputcsv($handler, array_map(encodeFunc, $array), ',', chr(0));
like image 74
gabe3886 Avatar answered Sep 18 '22 23:09

gabe3886


You could use the implode() function to make the code above even more simple:

$delimiter = ';';
$enclosure = '"';
$linefeed  = "\n";

$lines = array();
// traversing data, one row at a time
foreach ($data as $row) {
    $arr = array();
    // traversing row, col after col
    foreach ($row as $col => $val) {
        // MySQL-style escaping double quotes
        $val = str_replace('"','""',$val);
        // wrapping each value in double quotes
        $arr[] = sprintf('%s%s%s',$enclosure,$val,$enclosure);
    }
    // generating formatted line and storing it
    $lines[] = implode($delimiter,$arr);
}
// join each lines to have the final output
$output = implode($linefeed,$lines);
echo $output;
like image 39
Yannoff Avatar answered Sep 16 '22 23:09

Yannoff