11

So, my code generates a CSV file using PHP's built-in fputcsv function.

For the delimiter, I use ',' (a comma).
For the enclosure, I use '"' (a double-quote).

However, when I try something like

fputcsv($file,array('a','b',"long string, with commas",NULL,''),',','"');

it outputs

a,b,"long string, with commas",,

but I would like it to output

"a","b","long string, with commas","",""

Is there an easy way to deal with this, or would I have to write a replacement for fputcsv?

3
  • 1
    The output is valid CSV. Your other tool is broken. Commented Sep 28, 2010 at 22:54
  • Why do you want the quotes on every field? Commented Sep 28, 2010 at 22:57
  • 1
    @Ignacio, Andrew: Apparently, hidden in a little corner of the import dialog on spreadsheet software is an option to condense multiple empty fields (a,,, => a,) and/or remove them (a,,, => a). And apparently some users have this checked and don't know it, so the easy, one-size-fits-all solution is to force each empty field to be an empty string (a,"","",""). Commented Sep 28, 2010 at 23:16

5 Answers 5

9

This is not usually a problem for CSV files.

fputcsv puts quotes around the value if it would be ambiguous. For example,

a,b,"long string, with commas",,

is not ambiguous, but,

a,b,long string, with commas,,

is, and will in most (read: all) cases be interpreted by the CSV reader as having more than 5 fields.

CSV parsers will accept string literals even without quotes around them.

If you want quotes around the values anyway, the following snippet would do that. It doesn't escape quotes inside the string - that exercise is left to the reader:

$row = '"' . implode('", "', $rowitems) . '"';

You would want to put this in a loop for all your rows.

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

3 Comments

Yeah, I know about the ambiguity, but it's really the empty parts that I need wrapped in quotes. I can live without the non-empty parts being wrapped (except for the ambiguous ones, of course).
Your comment is confusing. You want the empty parts wrapped in quotes but the non-empty parts could go without wrapping? What do you mean. The snippet posted will wrap all in quotes which should work with all CSV parsers.
Never mind. I was a tad confused. Yes, this should work. Thanks.
9

I worked around this by inserting some bogus string characters, with a space, #@ @#, and then removing them. Here's a sample implementation:

//$exported is our array of data to export
$filename = 'myfile.csv';
$fp = fopen($filename, 'w');
foreach ($exported as $line => $row) {
    if ($line > 0) {
        foreach ($row as $key => $value) {
                $row[$key] = $value."#@ @#";
        }
    }
    fputcsv($fp, $row);
}

fclose($fp);
$contents = file_get_contents($filename);
$contents = str_replace("#@ @#", "", $contents);
file_put_contents($filename, $contents);

This encloses all fields in double quotes, including empty ones

3 Comments

Although this involves open and closing the file an extra time it works well.
This also lets you set it for a specific field rather than all columns +1
little slow but the only way for this to work properly, thanks!
2

I think solution will be like this,

$order_header_arr = array("Item1", "Item2","This is Item3");
fputcsv($fp, $order_header_arr,',',' ');

remember " "[Space] Between third parameter of fputcsv

1 Comment

That is the cleanest and fastest answer
0

Any reason you can't str_replace(',,',',"",',$output); ? You'd also have to see if the last or first character is a comma and if so, replace the comma with ,""

2 Comments

That was actually my first thought, but then I'd have to intercept the file-write to a string. D:
Ah yes. Completely forgot to think about what fputcsv actually does hah. You are better off writing your own function that escapes the data and outputs it using fputs or fwrite.
0

fputcsv will not enclose all array variables in quotes. Having a numeric array value without quotes may be correct but presents a problem when a label or address program encounters a numeric defined US zip code because it will strip the leading zeros when printing. Thus 05123-0019 becomes 5123-19.

To enclose all values, whether they exist or not, in quotes I read the input file with fgetsrc and write a corrected version using fwrite. fgetsrc reads the record into array variables. Since fwrite writes a variable, you must string the array variables, enclose them in quotes and separate the array variable with a comma. Then add the record separator.

<?php
// fgetcsv - read array with fgetcsv and string into output variable 
// then write with fwrite
// $ar is the array populated from fgetcsv and $arc is the variable strung 
// with array variables enclosed in quotes and written using fwrite.
$file_in = fopen("reinOCp.csv","r") or die("Unable to open input file 
reinOCp.csv!"); 
$file_out = fopen("printLABEL.csv", "w") or die("Unable to open output file 
prtLABEL!");
while (!feof($file_in)) {  //loop through each record of the input file
    $ar=fgetcsv($file_in); //read the record into array $ar   
    if (is_array($ar)){ //this loop will string all the array values plus 
// the end of record into variable $arc and then write the variable 
        $arc = ""; //clear variable $arc  
        foreach ($ar as $value) {      
            $arc .= '"' . $value . '",'; // add the array values, enclose in 
// quotes with comma separator and store in variable $arc
        }   
        $arc .= "\n"; //add end of record to variable $arc
        fwrite($file_out, $arc) or die ("ERROR: Cannot write the file"); 
//write the record using variable $arc
    }
}
echo "end of job";
fclose($file_in);
fclose($file_out);
?>

Comments

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.