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
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");
works with chr() function:
fputcsv($f,$array,',',chr(0));
fputcsv($file, $data, ';', chr(127));
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 :).
<?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',
);
Doesn't this work?
fputcsv($fp, split(',', $line),',',' ');
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.
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));
?>
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 ');
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)
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.
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, ',', '');
chr(0) also worked for me:
fputcsv($fp, $aLine, $sDelimiter, chr(0));
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!!!
I want to split a TSV string. The structure is:
abc\tdef\tghi\tjklm
where \t is a tab character.
If I use preg_split to split such string $i
$field=preg_split("/\t/", $i);
$field[3] is jklm.
However, if I have another string
abc\tdef\t\t
$field[3] is not a valid index.
How can I force empty fields into $field, such that all $field arrays would have an equal number of indexes?
If your problem just for extracting Tab Separator Value data, you can use built
in php function (fgetcsv()). It is more stable than use our own function. Please try this
if (($handle = fopen("test.csv", "r")) !== FALSE) {
// extract csv using tab delimiter
while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) {
print_r($data);
}
fclose($handle);
}
Like this?
$str ="abc\tdef\t\t";
Var_dump(explode("\t", $str));
https://3v4l.org/7qOPJ
I am converting a Delimited FLAT file to CSV and it has some data which as comma in between them. For eg the product name Iphone 6splus, 32 gb. Since this a description of the product and can have special characters also. How do i escape the comma as because of this fputcsv is considering this data as a new line. which is wrong. I am using
$handle = fopen("data.txt", "r");
$lines = [];
$row_count=0;
if (($handle = fopen("data.txt", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) {
if($row_count>0)
{
$lines[] = $data;
}
$row_count++;
}
fclose($handle);
}
$fp = fopen('example.csv', 'w');
foreach ($lines as $line) {
fputcsv($fp, split('\*\*', $line));
}
fclose($fp);
I need to escape the value before i start converting the data and store into csv
Enclose the field in quotes, e.g.
field1_value,field2_value,"field 3,value",field4, etc...
To encode a quote, use ", a single quote symbol in a field will be encoded as "", and the whole field will become """". So if you see the following in e.g. Excel:
---------------------------------------
| regular_value |,,,"| ,"", |""" |"|
---------------------------------------
the CSV file will contain:
regular_value,",,,""",","""",","""""""",""""
A comma is simply encapsulated using quotes, so , becomes ",".
A command and quote needs to be encapsulated and quoted, so "," becomes """,""".
I have a CSV file which contains words in english followed by Hindi words. I am trying to read the CSV file and do some further processing with it. The csv file looks like so:
Vice President-1 ????? ?????? ????
Vice President-2 ? ? ?
Vice President-3 ? ? ?
Secretary ? ? ?
How to read this file in php with Hindi words i also insert that word in database , and retrive
move_uploaded_file($_FILES['file']['tmp_name'],$target_path);
$file = fopen("$target_path", "r");
while (($data = fgetcsv($file, 8000, ",")) !== FALSE)
{
}
I had a similar problem with hebrew and found out getcsv() functions don't work well with non english UTF-8.
Here is my solution (parsing csv manually):
$data = 'some csv string';
$data_arr = preg_split("/((\r?\n)|(\r\n?))/", $data);
while ($line = array_shift($data_arr))
{
$row = array();
$line = preg_match_all('/"[^"]+"|[^,]+/', $line, $matches);
$line = $matches[0];
//your code here
}
I have a file that looks like this:
1028806~HDR~20110815~15-AUG-2011~C~23:10~~~~~~~
1028806~DTL~C3914A~HWP-C3914A~1000949~A~LASERJET MAINT KIT 8100/N/DN~HEWLETT PACKARD~2659~12~0~0~475.75~658.75~0~3~Y~2~~2~475.75~5~~~009088336~~3179~10.60~N~8.25~8.50~20.50~~088698601976~44103109~6A~20030627~NNY~~A~S~~~~~~N~~~~~~20.50~8.50~8.25~~~~~~~~~~~~~~~~
1028806~DTL~70023301~OKI-70023301~1002121~A~OKILAN 6020E+ 10/100BASE-TX ETHERNET EXT~OKI PRINTING SOLUTIONS~2703~0~0~0~55.17~80.00~0~0~Y~0~~0~55.17~0~~~009117000~~2160~2.79~N~8.00~8.75~14.00~~000000180016~44101700~ACC-IMPACT~19950723~NNY~~A~S~~~~~~N~~~~~~14.00~8.75~8.00~~~~~~~~~~~~~~~~
1028806~DTL~PRO7T~APC-PRO7T~1003150~A~Professional-grade Protection for Computers and Electronics~AMERICAN POWER CONVERSION~20664~7~0~0~21.60~36.00~0~0~Y~0~~0~21.60~7~~~008112000~~4400~2.00~N~1.90~6.90~12.40~~731304000181~39121610~SURG~19950723~NNY~~A~S~~~~~~N~~~~~~12.40~6.90~1.90~~~~~~~~~~~~~~~~
1028806~DTL~PER7~APC-PER7~1003418~A~Surge suppressor ( external ) / 7 output connector(s)~AMERICAN POWER CONVERSION~20664~496~50~0~9.30~15.25~0~3~Y~86~~363~9.30~44~~~008118000~~4400~1.85~N~2.10~6.90~11.50~~731304000112~39121610~SURG~20011025~NNY~~A~S~~~~~~N~~~~~~11.50~6.90~2.10~~~~~~~~~~~~~~~~
1028806~DTL~PRO7~APC-PRO7~1003761~A~APC SurgeArrest Professional - Surge suppressor ( external ) - AC 120 V - 7 outp~AMERICAN POWER CONVERSION~20664~88~0~0~17.59~30.00~0~0~Y~12~~52~17.59~24~~~008112000~~4400~1.95~N~2.25~7.50~12.25~~731304000174~39121610~SURG~19950723~NNY~~A~S~~~~~~N~~~~~~12.25~7.50~2.25~~~~~~~~~~~~~~~~
I need to use a script to read certain parts of each line (the bold parts):
1028806~DTL~C3914A~HWP-C3914A~1000949~A~LASERJET MAINT KIT 8100/N/DN~HEWLETT PACKARD~2659~12~0~0~475.75~658.75~0~3~Y~2~~2~475.75~5~~~009088336~~3179~10.60~N~8.25~8.50~20.50~~088698601976~44103109~6A~20030627~NNY~~A~S~~~~~~N~~~~~~20.50~8.50~8.25~~~~~~~~~~~~~~~~
The file has over 300k items so going through manually is not an option, so how can I get a script to read only these parts when I don't know how long the part # and descriptions are? While ignoring all the other ~ characters.
Thanks
fgetcsv() can help here, a little more memory-conservative than loading the whole file up at once and explode()'ing all the lines into a giant array.
if (($handle = fopen("/path/to/file", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "~")) !== FALSE) {
echo $data[2] . " " . $data[6];
}
}
fclose($handle);
Looks like you can explode on tilde:
$fields = explode('~', $line);
$part_num = $fields[2];
$desc = $fields[6];
// read the file
$lines = file('file.txt');
// loop through each line
foreach($lines as $line){
// separate the parts by the ~ delimiter up to the second bold part
// ignoring the rest of ~
$parts = explode('~', $line, 7);
echo $parts[2]; // output first bold part
echo $parts[6]; // output second bold part
}