62

Is there a native function or solid class/library for writing an array as a line in a CSV file without enclosures? fputcsv will default to " if nothing is passed in for the enclosure param. Google is failing me (returning results for a whole bunch of pages about fputcsv), and PEAR's libraries do more or less the same things as fputcsv.

Something that works exactly like fputcsv, but will allow the fields to remain unquoted.

currently: "field 1","field 2",field3hasNoSpaces

desired: field 1,field 2,field3hasNoSpaces

Derek Reynolds
  • 3,473
  • 3
  • 25
  • 34
  • 7
    I think you need the quotes.. what if there is a newline character or comma in there and they are not quote delimited? – alex Nov 25 '09 at 23:34
  • 1
    Quotes are there for your benefit. It's a good practice to use them; that's why they are the default. – Scott C Wilson Apr 07 '12 at 18:17
  • 8
    I disagree; if you have control of the input data you may wish to omit the enclosures, particularly if you may be exporting all numeric/filtered string data to an archaic reader. The other thing is tab separated files: Don't need enclosures. –  Jun 26 '12 at 18:33
  • 2
    If you're generating a CSV to be used to upload data to a poorly built app the quotes may interfere with the sql.. as is my situation – I wrestled a bear once. Oct 11 '13 at 08:18
  • fputcsv appears to have a bug that causes this sort of thing: 3StartssWithNum,"StartsWithAlpha", "notherStartsWAlpha", etc. The enclosure char is not the issue. The inconsistency is. [PHP ver 5.6] – ReverseEMF Dec 09 '19 at 21:11
  • I made it to get no delimiters by specifying `chr(0)` as delimiter in the last argument – ManuelJE Dec 16 '21 at 16:44

14 Answers14

75

The warnings about foregoing enclosures are valid, but you've said they don't apply to your use-case.

I'm wondering why you can't just use something like this?

<?php
$fields = array(
    "field 1","field 2","field3hasNoSpaces"
);
fputs(STDOUT, implode(',', $fields)."\n");
hrvoj3e
  • 2,512
  • 1
  • 23
  • 22
oops
  • 5,539
  • 1
  • 18
  • 10
  • 2
    Dunno why I didn't go to this first. Thanks! – Derek Reynolds Dec 15 '09 at 22:23
  • 2
    Because CSV libraries handle cases that your simple implode solution doen't, like scaping the separator character (`,` in your case). – jgomo3 Feb 08 '16 at 22:43
  • 7
    This is the best way to replace fputcsv without enclosures. I would make a small suggestion to improve this answer - use documented argument order for [implode](http://php.net/manual/en/function.implode.php) : `implode(string $glue, array $pieces)` to avoid confusion with people who are new to PHP and don't know this PHP "feature" of reversed arguments. – hrvoj3e Dec 16 '16 at 11:25
  • 1
    `fputs(...)` is an alias function, consider using `fwrite(...)` instead. – Mr. Jo Jul 15 '21 at 07:55
11

works with chr() function:

fputcsv($f,$array,',',chr(0));
6

fputcsv($file, $data, ';', chr(127));

Raul Duran
  • 538
  • 5
  • 5
2

Well car(0) didn't work out as the NULL value will most likely choke most csv parsers.

I ended using fputcsv() to build the initial file, then went through and removed all quotes. Elegant? Maybe not, but it got the job done :).

Derek Reynolds
  • 3,473
  • 3
  • 25
  • 34
2
<?php       
    
$filename = "sample.csv";
$handle = fopen($filename, 'w+');
fputcsv($handle, ['column 1','column 2']);
$data = ['sample','data'];

fputs($handle, implode(',', $data)."\n");

// or

fwrite($handle, implode(',', $data)."\n");

fclose($handle);
$headers = array(
    'Content-Type' => 'text/csv',
);
Erenor Paz
  • 3,061
  • 4
  • 37
  • 44
zeros-and-ones
  • 4,227
  • 6
  • 35
  • 54
  • Spot on! Why people are always looking for some nifty one-liner that makes the code hard to maintain instead of relying on basic built-in functions to do it the right way? – wp78de Jul 08 '22 at 22:15
1

Doesn't this work?

fputcsv($fp, split(',', $line),',',' ');
Arthur Frankel
  • 4,695
  • 6
  • 35
  • 56
  • Split will be a deprecated function and this doesn't necessarily solve my issue with enclosures. Unfortunately spaces aren't considered a legit character at least as far as this function is concerned. Thanks though! – Derek Reynolds Nov 25 '09 at 23:47
  • Assuming the extra space isn't a problem, it seems he's looking for *no* enclosure; however, using a space seems like the logical thing to try. – Tim Lytle Nov 25 '09 at 23:48
0

This is what I use to put standard CSV into an array...

function csv_explode($delim=',', $str, $enclose='"', $preserve=false){
        $resArr = array();
        $n = 0;
        $expEncArr = explode($enclose, $str);
        foreach($expEncArr as $EncItem){
                if($n++%2){
                        array_push($resArr, array_pop($resArr) . ($preserve?$enclose:'') . $EncItem.($preserve?$enclose:''));
                }else{
                        $expDelArr = explode($delim, $EncItem);
                        array_push($resArr, array_pop($resArr) . array_shift($expDelArr));
                        $resArr = array_merge($resArr, $expDelArr);
                }
        }
        return $resArr;
} 

You can then output whatever you want in a foreach loop.

jjclarkson
  • 5,890
  • 6
  • 40
  • 62
0

The downside with a CSV file with no enclosures means an errant comma in user input will munge the row. So you'll need to remove commas before writing a CSV row.

The tricky part with handling CSV is parsing enclosures, which makes the PHP & PEAR CSV functions valuable. Essentially you're looking for a file that is comma-delimited for columns and newline-delimited for rows. Here's a simple starting point:

<?php
$col_separator= ',';
$row_separator= "\n";

$a= array(
 array('my', 'values', 'are', 'awes,breakit,ome'),
 array('these', 'values', 'also', "rock\nAND\nROLL")
);

function encodeRow(array $a) {
 global $col_separator;
 global $row_separator;
 // Can't have the separators in the column data!
 $a2= array();
 foreach ($a as $v) {
  $a2[]= str_replace(array($col_separator, $row_separator), '', $v);
 }
 return implode($col_separator, $a2);
}

$output= array();
foreach ($a as $row) {
 $output[]= encodeRow($row);
}

echo(implode($row_separator, $output));

?>
leepowers
  • 37,828
  • 23
  • 98
  • 129
0

I use tricky way to remove double quote, but only in Linux

....
fputcsv($fp, $product_data,"\t");
....
shell_exec('sed -i \'s/"//g\' /path/to/your-file.txt ');
Ansyori
  • 2,807
  • 3
  • 29
  • 37
0

Whats wrong with good old fwrite()?

function encloseString($field){
    return ($field) ? '"' . $field . '"' : null;
}

$delimiter = ';';
$data = ["data_field_1", "data_field_2", "data_field_3"];

$fp = fopen("some-file.csv", 'w');

for($i = 0;$i<100000;$i++) {
    fwrite($fp, implode($delimiter, array_map('encloseString', $data) . "\n");
}

fclose($fp);

(Obviously you need to make sure the data in $data is escaped first)

Matthew Fedak
  • 772
  • 9
  • 16
0

Chose the solution depends on your application. For some case own code for csv is needed. In case 1 (See result chr0), case 2 (chr127) and case 3 (chr127) the data will be modified(bad thing). Instead use something like this, thanks @oops:

<?php
$fields = array("field 1","field 2","field3hasNoSpaces");
fputs(STDOUT, implode(',', $fields)."\n");
  • case 1. fputcsv($f, $array, $delimiter, car(0)) See result chr0
  • case 2. fputcsv($f, $array, $delimiter, car(127)) chr127
  • case 3. fputcsv($f, $array, $delimiter, ' ') onespace
  • case 4. Own code (s.above inspired by oops or Ansyori or zeros-and-ones ) produces better results.
Jaja
  • 662
  • 7
  • 15
0

This is an old question but as I was struggling with this as well, I thought it would be good to let anyone who is looking for something like this know than you can just pass empty string in the enclosure param of fputcsv and it will not use any enclosure at all.

i.e.

fputcsv($file, $array, ',', '');

  • 2
    Passing an empty string for the `enclosure` parameter throws the "enclosure must be a character" error, which is the very reason the author posted the question in the first place – Oliver Maksimovic Oct 27 '22 at 08:56
-1

chr(0) also worked for me:

 fputcsv($fp, $aLine, $sDelimiter, chr(0));
Shahzad Barkati
  • 2,532
  • 6
  • 25
  • 33
jb7AN
  • 77
  • 1
  • 6
-3

Figured it out. By passing in the ascii code for Null to the car() function it seems to work just fine.

fputcsv($f, $array, $delimiter, car(0))

Thanks for the answers everyone!!!

Derek Reynolds
  • 3,473
  • 3
  • 25
  • 34