Write CSV To File Without Enclosures In PHP
Asked Answered
L

14

64

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

Lousewort answered 25/11, 2009 at 23:31 Comment(6)
I think you need the quotes.. what if there is a newline character or comma in there and they are not quote delimited?Bring
Quotes are there for your benefit. It's a good practice to use them; that's why they are the default.Battista
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.Flowery
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 situationCarlton
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]Haste
I made it to get no delimiters by specifying chr(0) as delimiter in the last argumentSennit
C
77

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");
Corron answered 15/12, 2009 at 3:7 Comment(4)
Dunno why I didn't go to this first. Thanks!Lousewort
Because CSV libraries handle cases that your simple implode solution doen't, like scaping the separator character (, in your case).Caddoan
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 : 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.Dugger
fputs(...) is an alias function, consider using fwrite(...) instead.Intemperance
J
11

works with chr() function:

fputcsv($f,$array,',',chr(0));
Judenberg answered 14/11, 2012 at 10:16 Comment(4)
chr(0) create null char who is display in utf8 like ^@Warr
I doubt this is a good idea. You're actually writing a "\0". Mostly invisible until it comes back to bite you.Forebear
Notepad on Windows will open a file with "\0" characters with the wrong encoding, leading to garbage characters shown on screen.Intact
What about you delete this very wrong answer which is sitting here since 9 years?Triplane
T
6

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

Thermo answered 31/3, 2017 at 9:4 Comment(2)
That was the one I was looking for. Thanks m8!Jink
Actually, chr(127) still shows as a character in the file so it isn't ideal. DamnMarilyn
T
3
<?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',
);
Tildy answered 4/8, 2016 at 22:36 Comment(1)
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?Twannatwattle
L
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 :).

Lousewort answered 5/12, 2009 at 1:19 Comment(0)
G
1

Doesn't this work?

fputcsv($fp, split(',', $line),',',' ');
Gallego answered 25/11, 2009 at 23:41 Comment(2)
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!Lousewort
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.Heirship
T
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.

Tradespeople answered 25/11, 2009 at 23:37 Comment(0)
A
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));

?>
Arable answered 26/11, 2009 at 0:21 Comment(0)
O
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 ');
Oration answered 23/8, 2018 at 8:41 Comment(0)
D
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)

Duda answered 17/7, 2019 at 9:2 Comment(0)
R
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.
Rachellerachis answered 17/11, 2020 at 13:41 Comment(2)
Did you intend chr(0) and chr(197) ? I solved this issue with the first one.Sennit
yes, chr0 for chr(0) and so on...Rachellerachis
C
-1

chr(0) also worked for me:

 fputcsv($fp, $aLine, $sDelimiter, chr(0));
Chemisorption answered 11/12, 2015 at 13:32 Comment(1)
I think it work's because your editor don't show you the null char, but it's still thereBroadcaster
S
-1

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, ',', '');

Samuella answered 6/6, 2022 at 13:43 Comment(1)
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 placeFraction
L
-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!!!

Lousewort answered 26/11, 2009 at 0:40 Comment(3)
Hmm... are you sure it's not gonna put a bunch of stealth nulls in the csv file? :s Also, I think it's 'chr(0)' --!Flowery
Puts NULL for me. Not the ideal solution.Absonant
car(0) really??Triplane

© 2022 - 2024 — McMap. All rights reserved.