i have a small problem with my fwrite().
$txt=fopen("$directory","w");
if (($handle = fopen("$directory", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
$num = count($data);
...
...
There are no problem if i write:
fwrite($txt, "Hello;");
fwrite($txt, "Test fwrite;");
The output in the .csv file is like this:
Hello | Test fwrite
The problem appears when I have a variable contains the delimiter character, but I do not want fwrite consider it as a delimiter.
I have try to use chr(59), but the problem is not solved.
For example:
$var = "hello;test;hello;";
fwrite($txt, "Test fwrite;");
fwrite($txt, "$var;");
fwrite($txt, "Hello;");
The output of i would like to have is:
Test fwrite | hello;test;hello | Hello
Is possible do this without change the character delimiter ( ; )??
Thanks!
Easier done via fputcsv.
If your field contains the delimeter character you have to enclose the value (by default with double quotes).
e.g.
"abc;def";"x";"y";"z"
Related
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 am trying to read a file one word at a time. So far I have been able to use fgets() to read line by line or up to a certain amount of bytes, but that is not what I am looking for. I want one word at a time. up to the next white space, \n, or EOF.
Does anyone know how to do this in php. In c++ I just use the 'cin >> var' command.
you can do this by
$filecontents = file_get_contents('words.txt');
$words = preg_split('/[\s]+/', $filecontents, -1, PREG_SPLIT_NO_EMPTY);
print_r($words);
this will give you array of words
For some replies in this topic: I say this: Do not reinvent the wheel.
In PHP use:
str_word_count ( string $string [, int $format [, string $charlist ]] )
format:
0 = Return only the number of words;
1 = Return an array;
2 = Return an associative array;
charlist:
Charlist are characters which you consider a word.
Function.str-word-count.php
[CAUTION]
Nobody know anything about the size of your file content, if your file contents is big, exists many flexible solutions.
(^‿◕)
You would have to use fgetc to get a letter at a time until you hit a word bountry then do something with the word. Example
$fp = fopen("file.txt", "r");
$wordBoundries = array("\n"," ");
$wordBuffer = "";
while ($c = fgetc($fp)){
if (in_array($c, $wordBountries)){
// do something then clear the buffer
doSomethingWithBuffer($wordBuffer);
$wordBuffer = "";
} else {
// add the letter to the buffer
$wordBuffer.= $c;
}
}
fclose($fp);
You can try fget() function which read file line by line and when you get one line from file you use explode() to extract word from line which separated by space.
Try this code:
$handle = fopen("inputfile.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
$word_arr = explode(" ", $line); //return word array
foreach($word_arr as $word){
echo $word; // required output
}
}
fclose($handle);
} else {
// error while opening file.
echo "error";
}
I'm importing a CSV using the fgetcsv() function, which is working all good.
However, when I take a look at the data in the database, I see black diamonds with question marks. This isn't too much of an issue when echoing the data back out again, as they don't appear, but when I want to use one of the CSV fields as a MySQL date, it isn't recognised as a date and is stored as 0000-00-00.
e.g.
I think this issue is something to do with encoding of the CSV? Can anyone offer any advice?
Thanks!
Edit: if it helps here is my import script, and the encode type is ASCII according to mb_detect_encoding
<?php
include 'config.php';
include 'opendb.php';
ini_set("auto_detect_line_endings", true);
$row = 0;
$tmpName = $_FILES['csv']['tmp_name'];
if (($handle = fopen($tmpName, "r")) !== FALSE) {
$num = count($data);
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
$noQuotes = str_replace("\"", '', $data);
$originalDate = $noQuotes[1];
//$delivery_date = date('Y-m-d', strtotime($originalDate));
$parts = explode('/', $originalDate);
$delivery_date = $parts[2] . '-' . $parts[1] . '-' . $parts[0];
$row++;
$import="INSERT into dispatch (delivery_note_number, delivery_date, dispatch_date, customer_delivery_date, delivery_line, produce, variety, quantity, pallets, count, depot, customer, grower, haulier, status)
values ('$noQuotes[0]', '$delivery_date', '$noQuotes[2]', '$noQuotes[3]', '$noQuotes[4]', '$noQuotes[5]', '$noQuotes[6]', '$noQuotes[7]', '$noQuotes[8]', '$noQuotes[9]', '$noQuotes[10]', '$noQuotes[11]', '$noQuotes[12]', '$noQuotes[13]', '$noQuotes[14]')";
echo $import;
mysql_query($import) or die(mysql_error());
}
//header("location:list_dispatch.php?st=recordsadded");
fclose($handle);
}
?>
If your database is using a different character encoding than the CSV file, it is possible the data should converted first.
One way to perform this is using the mb_convert_encoding() function.
Also useful, mb_detect_encoding() should be able to detect the character encoding for a given input string.
Someone found a solution on a another forum:
Those are NUL characters (ASCII code 0x00), replace them like this:
$string = str_replace(chr(0), '', $string);
fputcsv($f, $array, ' ', chr(0));
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
}