PHP CSV file issues(part 2) - php

continue on PHP duplicate staffID
code
$data[0] = 0001,Ali,N,OK
$data[1] = 0002,Abu,N,OK
$data[2] = 0003,Ahmad,N,OK
$data[3] = 0004,Siti,Y,Not OK. Only one manager allowed!
$data[4] = 0005,Raju,Y, Not OK. Only one manager allowed!
I write it as following:
for($i = 0; $i < 5; $i++)
{
$data[i] = $staffID[$i].','.$staffname[$i].','.$ismanager[$i].','.$remark[$i];
}
Next I go to write csv file.
$file_format = "staffreport.csv";
$file = fopen($file_format,"w");
foreach($data as $line)
{
$replace = str_replace(",","|", $line);
fputcsv($file, array($replace));
echo $replace.'<br />';
}
fclose($file);
output (echo $replace)
0001|Ali|N|OK
0002|Abu|N|OK
0003|Ahmad|N|OK
0004|Raju|Y|Only one manager allowed!
0005|Siti|Y|Only one manager allowed!
In CSV file (staffreport.csv)
0001|Ali|N|OK
0002|Abu|N|OK
0003|Ahmad|N|OK
"0004|Siti|Y|Only one manager allowed!"
"0005|Raju|Y|Only one manager allowed!"
Why my csv file have double quote("")? How do I solve it?

change this bit like so.
for($i = 0; $i < 5; $i++)
{
$data[i] = array($staffID[$i],$staffname[$i],$ismanager[$i],$remark[$i]);
}
fputcsv wants an array of columns it will then insert the separators and quote marks as needed.
fputcsv usually uses commas for separators, if you want pipes: do this:
fputcsv($file, $line,'|');
why the quotes? probably because of the spaces.
if you must avoid the quotes,
fputcsv($file, $line,'|','');
hope that helps.

Related

looping through txt file to use specific part of a string

I am new to Php and can't seem to figure this out no matter how much I've googled.
So I've opened the txt file (which consists of multiple lines of this type of string unique Identifier IMEI in bold:
Rx:00:39:54 06/09/2015:+RESP:GTEPS,210101,863286020022449,,8296,01,1,3,0.0,0,1031.1,29.367950,-30.799161,20150906003710,,,,,,2857.9,20150906003710,8038$) There are different strings with different IMEIs but i only want to use a specific one.
My question is, how do I extract/only use the string with the same Unique identifier and then loop through those to use in another function?
My function has different cases and each case has different calculations, so I'll need to loop through the txt file (with e.g. 863286020022449 as Identifier, ignoring other identifiers/IMEIs) in order to use the string in my function as below:
This is my starter function:
function GetParam($unknownFunction, $numberCommas) {
$returnString = "";
$foundSting = 0;
$numberFound = 0;
$len = strlen($unknownFunction);
for ($i = 0; $i < $len; ++$i) {
if ($Rawline[$i] == ",") {
++$numberFound;
if ($numberFound > $numberCommas)
break;
if ($numberFound == $numberCommas)
$foundSting = 1;
}
else if ($foundSting == 1) {
$returnString .= $unknownFunction[$i];
}
}
return $returnString;
echo $returnString;
}
$i = strpos($unknownFunction, ":GT");
$p = substr($unknownFunction, $i+3,3);
$Protocol = GetParam($unknownFunction, 1);
//this switch reads the differences in the message types (e.g. HBD- in this case is a heartbeat message type and would thus have a different amount of commas in the string and has different definitions of the characters within the commas)
switch ($p) {
case 'HBD':
//+ACK:GTHBD,220100,135790246811220,,20100214093254,11F0$
//This is an example of an HBD message
$result2["Type"] = 'Heart beat';
$IMEI = GetParam($unknownFunction, 2);
$mDate = GetParam($unknownFunction, 4);
$mDate = substr($mDate,0,4).'-'.substr($mDate,4,2).'-
'.substr($mDate,6,2).'
'.substr($mDate,8,2).':'.substr($mDate,10,2).':'.substr($mDate,12,2);
break;
This is the biggest problem I am facing at the moment and when I print the different lines, it indicates the correct IMEI but it does not loop through the whole file to use each string that belongs to that IMEI.
Your assistance would be greatly appreciated.
Thank you so much.
Example of input file:
Rx:00:00:00 28/02/2018:+RESP:GTFRI,3C0103,862045030241360,,14067,11,1,1,29.7,320,151.1,30.949307,-29.819685,20180227235959,0655,0001,013A,87B6,00,35484.1,01500:51:31,,,100,220101,,,,20180228000000,3461$
Rx:00:00:01 28/02/2018:+RESP:GTERI,380201,869606020047340,gv65,00000002,14076,10,1,1,119.0,119,24.3,18.668516,-34.016808,20180227235955,0655,0001,00F7,2DC9,00,98912.0,02235:20:25,0,100,220101,0,0,20180227235958,FF20$
Rx:00:00:03 28/02/2018:+RESP:GTERI,380201,869606020162990,,00000002,12912,10,1,1,0.0,230,1127.3,30.846671,-27.674206,20180227235956,0655,0001,013E,88B0,00,106651.1,03546:44:42,0,100,210101,0,0,20180227235959,6190$
Rx:00:00:03 28/02/2018:+ACK:GTHBD,450102,865084030005340,gb100,20180228000003,CC61$
Rx:00:00:03 28/02/2018:+RESP:GTERI,380201,869606020115980,,00000002,13640,10,1,1,12.1,353,1663.1,28.580726,-28.162208,20180227235957,,,,,,37599.6,02422:07:24,0,100,220101,0,0,20180228000000,1937$
Rx:00:00:04 28/02/2018:+RESP:GTERI,380502,869606020276840,gv65,00000002,12723,10,1,1,0.0,106,1232.8,22.878013,-27.951762,20180227235952,0655,0001,0204,63C5,00,13808.9,00778:32:20,0,100,210100,0,0,20180228000002,2C50$
Rx:00:00:04 28/02/2018:+RESP:GTERI,380502,869606020274530,gv65,00000002,12683,10,1,1,0.0,91,1213.7,24.863444,-28.174319,20180227235956,0655,0001,0203,69F1,00,9753.2,00673:49:21,0,100,210100,0,0,20180228000003,8AC7$
Rx:00:00:05 28/02/2018:+ACK:GTHBD,380201,863286023083810,,20180228000003,0D87$
Rx:00:00:06 28/02/2018:+RESP:GTFRI,3C0103,862045030241360,,14086,10,1,1,34.0,327,152.0,30.949152,-29.819501,20180228000002,0655,0001,013A,87B6,00,35484.1,01500:51:36,,,100,220101,,,,20180228000005,3462$
Rx:00:00:06 28/02/2018:+ACK:GTHBD,060228,862894021626380,,20180228000007,F9A5$
Rx:00:00:07 28/02/2018:+RESP:GTERI,380201,869606020019430,,00000002,12653,10,1,1,0.0,219,1338.7,26.882063,-28.138099,20180228000002,,,,,,86473.7,05645:48:34,0,93,210101,0,0,20180228000003,0FA5$
Rx:00:00:09 28/02/2018:+ACK:GTHBD,380502,869606020233940,gv65,20180228000008,7416$
Rx:00:00:10 28/02/2018:+RESP:GTAIS,380201,869606020171710,,11,11,1,1,0.0,95,281.2,30.855164,-29.896575,20180228000009,0655,0001,0156,9A9F,00,156073.7,20180228000008,F9A4$
Each GT message means something which is why i need to extract only one specific IMEI and use the result in my function as a breakdown of what every set of numbers between the commas actually mean. The end result needs to be populated in an excel spreadsheet but that's a different issue.
Nested foreach, keeping tracking of the IMEIs you've already gone through. Or something like this.
<?php
$filename = 'info.txt';
$contents = file($filename);
foreach ($contents as $line) {
$doneAlreadyArray = array();
$IMEI = GetParam($line, 2);
foreach ($contents as $IMEIline){
$thisIMEI = GetParam($IMEIline,2);
//check if already done the IMEI previously
if (!in_array($thisIMEI, $doneAlreadyArray)){
//matching IMEIs?
if ($thisIMEI == $IMEI){
//run new function with entire $IMEIline
new_function($IMEIline);
}
}
}
//add IMEI to doneAlreadyArray
array_push($doneAlreadyArray,$IMEI);
}
?>
If I've understood your question right and you want to extract the string(line) with the same Unique identifier, this may be useful for your needs as a strating point.
The example is very basic, and use data from your question:
<?php
// Read the file.
$filename = 'input.txt';
$file = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Each item of $output will contain an array of lines:
$output = array();
foreach ($file as $row) {
$a = explode(',', $row);
$imei = $a[2];
if (!array_key_exists($imei, $output)) {
$output[$imei] = array();
}
$output[$imei][] = $row;
}
// Then do what you want ...
foreach ($output as $key=>$value) {
echo 'IMEI: '.$key.'</br>';
foreach($value as $row) {
// Here you can call your functions. I just echo the row:
echo $row.'</br>';
}
}
?>
thank you for the feedback.
Ryan Dewberry ended up helping me.
The fix was simpler than I thought too :)
//Unknownfunction is now $line
function GetParam($line, $numberCommas) {
$returnString = "";
$foundSting = 0;
$numberFound = 0;
$len = strlen($line);
for ($i = 0; $i < $len; ++$i) {
if ($line[$i] == ",") {
++$numberFound;
if ($numberFound > $numberCommas)
break;
if ($numberFound == $numberCommas)
$foundSting = 1;
}
else if ($foundSting == 1) {
$returnString .= $line[$i];
}
}
return $returnString;
// print $returnString;
}
//this is new - makes sure I use the correct IMEI
$contents = file($fileName);
foreach ($contents as $line){
$haveData = 0;
$IMEI = GetParam($line, 2);
if ($IMEI == $gprsid){
$i = strpos($line, ":GT");
$p = substr($line, $i+3,3);
$Protocol = GetParam($line, 1);
//this is the part I struggled with as well - This is an array of all of my
//calculation
//results and in printing it out I can see that everything is working
$superResult = array();
array_push($superResult,$result2);
print_r($superResult);
}
}
Much appreciated. Thank you!

PHP CSVImporter

I had a script called CSVimporter V3 for PHP that I used to run on a website and it worked fine. A couple of years later I've now dug out the same script to use on another project, all works okay except the CSV files are being read as one long line, as opposed to header row and multiple lines.
Here is part of the script.
Any ideas why it would be being read as a long line?
<?php
// Reference session variable for short-hand
$f = &$_SESSION['csv_file'];
// Open file - fp = file pointer
if (!$fp = #fopen($f, 'r')) {
error(L_ERROR_PREVIEW_NO_FILE);
} else {
// Array to store each row to be inserted
$batch = array();
// Row counter
$rc = 0;
// Work out starting row
switch ($_SESSION['csv_first_row']) {
case 'data':
$start_row = 0;
break;
default:
$start_row = 1;
}
// Get contents, while below preview limit and there's data to be read
while ($data = fgetcsv($fp, 1024, delimiter_to_char($_SESSION['csv_delimiter']))) {
if ($rc < $start_row) {
// Incremement counter
$rc++;
// Go to next loop
continue;
} else {
// Array to store data to be inputted
$values = array();
// Loop data
for ($i = 0; $i < count($data); $i++) {
// If data is wanted, put data into array
if (array_key_exists($i, $column_index)) {
$values[$column_index[$i]] = $data[$i];
}
}
// Sort array into correct order by index
ksort($values);
// Join values together and store in array
$batch[] = '("' . implode('", "', str_replace('"', '\"', $values)) . '","'.$accti.'","'.$impt.'")';
}
}
}
// Close the file
fclose($fp);
I added this at the top of the code and it all works now!
ini_set('auto_detect_line_endings', true);

nokia csv file import issue in php

Title,"First name","Middle name","Last name","address"
Mr.,"prince","M","Kachhadiya","A-42,AdarshNagar-2
 c.g Road,
"
Address field have value like "A-42,AdarshNagar-2
 ChhpraBhatha Road," this value have comma(,) in between and csv file default field separator is comma(,) so it will assume A-42 and AdarshNagar-2
 c.g Road as different field value.
how can i resolve it?
My Php Code:
while (($data = fgetcsv($handle, 0, ",")) !== FALSE) {
// Code for parse csv data
}
use fgetcsv() to read from a file . Refer http://www.w3schools.com/php/func_filesystem_fgetcsv.asp
Title,"First name","Middle name","Last name","address"
Mr.,"prince","M","Kachhadiya","A-42,AdarshNagar-2 c.g Road,"
//You can't split the strings using CSV functions so better do some manual work
//All csv values are quoted with double quotes so split the string like this
//**If file size is minimum use this function**
$data = file_get_contents('<file_path>');
$parsed_string = explode('",', $data);
$cnt = count($parsed_string);
for($i=0; $i<$cnt; $i++)
{
$value = substr($parsed_string,1);
}
//**If file size is maximum use this**
$file = fopen("<file path>","r");
while(! feof($file))
{
$data = fgets($file);
$parsed_string = explode('",', $data);
$cnt = count($parsed_string);
for($i=0; $i<$cnt; $i++)
{
$value = substr($parsed_string,1);
}
}
fclose($file);

what's the code meaning?

$file = fopen("test.txt","r");
while($line = fgets($file)) {
$line = trim($line);
list($model,$price) = preg_split('/\s+/',$line);
if(empty($price)) {
$price = 0;
}
$sql = "UPDATE products
SET products_price=$price
WHERE products_model='$model'";
// run the sql query.
}
fclose($file);
the txt file like this:
model price
LB2117 19.49
LB2381 25.99
1, what's the meaning of list($model,$price) = preg_split('/\s+/',$line);
i know preg_split like explode, but i don't know what't the parameter meaning of the above line
2, how to skip the first record.
it's taking the results of the preg_split and assigning them to the vars $model and $price. You're looking at a parsing algorithm. Sorry if this is not enough. I have a hard time understanding the question as it is written.
Also, if I read this correctly, there is no need to skip line 1 unless you have an item with the model defined as "model" in the database.
But if you wanted to for some reason, you could add a counter...
$i = 0;
while($line = fgets($file)) {
if($i > 0)
{
$line = trim($line);
list($model,$price) = preg_split('/\s+/',$line);
if(empty($price)) {
$price = 0;
}
$sql = "UPDATE products
SET products_price=$price
WHERE products_model='$model'";
// run the sql query.
}
$i++;
}
That is a language construct that allows you to assign to multiple variables at once. You can think of it as array unpacking (preg_split returns an array). So, when you do:
<?php
list($a, $b) = explode(".","a.b");
echo $a . "\n";
echo $b . "\n";
You will get:
a
b
Having less elements in list than the array is ok, excess elements in array are ignored, but having insufficent elements in array will give you an undefined index error. For example:
list($a) = explode(".","a.b"); // ok
list($a,$b,$c) = explode(".","a.b") // error
I don't know if you meant that by skip the first record but...
$file = fopen("test.txt","r"); // open file for reading
$first = true;
while($line = fgets($file)) { // get the content file
if ($first === true) { $first = false;}//skip the first record
else{
$line = trim($line); // remove the whitespace before and after the test
// not in the middle
list($model,$price) = preg_split('/\s+/',$line); // create two variable model and price, the values are from the preg_split \s means whitespace, tab and linebreak
if(empty($price)) { // if $price is empty price =0
$price = 0;
}
$sql = "UPDATE products // sql update
SET products_price=$price
WHERE products_model='$model'";
// run the sql query.
}
}
fclose($file); //close the file

how should i parse the csv file in php when the delimiter varies?

It seems that the delimiter of csv file edited and saved by OpenOffice Excel is ";" while microsoft office excel is ",", how should i write a program to parse the csv file no matter which delimiter it uses?
I'm using this function in one of my apps to determine which separator is used:
function get_separator( $csvstring, $fallback = ';') {
$seps = array(';',',','|',"\t");
$max = 0;
$separator = false;
foreach($seps as $sep){
$count = substr_count($csvstring, $sep);
if($count > $max){
$separator = $sep;
$max = $count;
}
}
if($separator) return $separator;
return $fallback;
}
It basically checks which separator occurs at most and returns it. It works without problems for about two years now
Use SplFileObject::getCsvControl method.
Example usage:
<?php
$csvFileObject = new SplFileObject($_FILES["csv"]["tmp_name"]);
list($delimiter, $enclosure) = $csvFileObject->getCsvControl();
$lines = fopen($_FILES["csv"]["tmp_name"], 'r');
if($lines) {
while (($line = fgetcsv($lines, 4096, $delimiter, $enclosure)) !== false) {
//do something
}
}
Reference: http://php.net/manual/en/splfileobject.getcsvcontrol.php
fgetcsv() allows you to specify the delimiter as the third argument.
As for automatically detecting, there are some interesting answers for this question.

Categories