Using fgetcsv to replace commans within numbers - php

I have the following CSV data:
"Symbol","Name","Trade Volume","Trade Value","UIN Settlement Volume ","UIN Settlement Value ","UIN Percentage Volume","UIN Percentage Value "
"786","786 INVESTMENT LIMITED","500.00"," 2,325.00 ","500.00"," 2,325.00 ","100.00 ","100.00 "
"ABL","ALLIED BANK LIMITED","15,501.00"," 981,819.00 ","10,001.00"," 629,379.00 ","64.52 ","64.10 "
"ABOT","ABBOTT LABORATORIES (PAKISTAN) LIMITED","4,043.00"," 1,730,197.34 ","3,031.00"," 1,299,214.65 ","74.97 ","75.09 "
"ACPL","ATTOCK CEMENT PAKISTAN LIMITED","40,231.00"," 2,345,598.00 ","36,131.00"," 2,107,058.00 ","89.81 ","89.83 "
"ADAMS","ADAM SUGAR MILLS LIMITED","4,091.00"," 107,544.61 ","3,091.00"," 80,669.61 ","75.56 ","75.01 "
Before splitting the w.r.t comma by using fgetcsv, I want to remove command from numbers. How can I do it?
My current code looks like the below:
while (($row = fgetcsv($file, 1000, ",")) !== FALSE) {
print("<br><b>Before</b><br>");
print_r($row);
$row = preg_replace('/([0-9]+),([0-9]+)/', '$1$2', $row);
// $row = preg_replace('/"([0-9]+),([0-9]+)(.*?)"/', '"$1$2$3"', $row);
print("<br><b>After</b><br>");
print_r($row);
$Symbol = $row[0];

Do you want to remove extra commas and spaces from numbers in all cells?
The result of fgetcsv is an array, not a string. You need to process each item
while (($row = fgetcsv($file, 1000, ",", "\"")) !== FALSE) {
echo "<br><b>Before</b><br>" . PHP_EOL;
print_r($row);
$row = array_map(function($el) {
if (preg_match("/^[. ,0-9]+$/", $el)) {
$el = preg_replace("/,/", "", trim($el));
}
return $el;
},
$row);
echo "<br><b>After</b><br>" . PHP_EOL;
print_r($row);
$Symbol = $row[0];
}

Related

PHP Parsing file into Array of Array

I have a file with many rows,each row have the following format:
1519382994.85#MSG#Something went wrong
So, for each row i have three field divided by #. A number, a message type and a string.
Now i want to read the file and split the contents.
I made it in this way:
//Opening the logger file
$myfile = file_get_contents("operations.txt", "r") or die("Unable to open file!");
$rows = explode("\n", $myfile);
$num_rows = count($rows);
$fieldList = array();
//Parsing rows using '#'
foreach ($rows as $row => $data) {
$row_data = explode('#', $data);
array_push($fieldList, (string)$row_data[0]);
array_push($fieldList, (string)$row_data[1]);
array_push($fieldList, (string)$row_data[2]);
}
The code is working well but i'd like to have an array of array and this kind of data:
0: Array [ "112323.76", "MSG", "Hello"]
1: Array [ "453435.78", "MSG", "Bye"] etc..
I tryed with this code but i'm doing something wrong.
$last=0;
$result = array();
for ($i = 0; $i < $num_rows; $i++) {
array_push($result, (string) $fieldList[$last], (string) $fieldList[$last+1],(string) $fieldList[$last+2]);
//echo $fieldList[$last].'<br>';
//echo $fieldList[$last+1].'<br>';
//echo $fieldList[$last+2].'<br>';
$last=$last+3;
}
I'm a newbie in PHP someone can help me please and tell me what i'm doing wrong? Tanx a Lot for your time
You could probably make use of the built-in fgetcsv:
array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "\\" ]]]] )
This could look like:
$rows = [];
if (false !== ($handle = fopen("path/to/file", "r")))
{
while (false !== ($row = fgetcsv($handle, 1000, ",")))
{
array_push($rows, $row);
}
fclose($handle);
}
Don't know if it would be a lot faster, but looks a lot easier to me. The main benefits of this over file() and explode() are:
There is no need to have the entire file in RAM at once, processing could be done one row at a time.
it is easy to support other "Character Seperated Values" type files where fields may be quoted ($enclosure)
Just needed some modifications in your code. Added comments to modified lines-
$myfile = file_get_contents("operations.txt", "r") or die("Unable to open file!");
$rows = explode("\n", $myfile);
$num_rows = count($rows);
$finalFieldList = array(); // new array
//Parsing rows using '#'
foreach ($rows as $row => $data) {
$fieldList = array(); // temporary array
$row_data = explode('#', $data);
array_push($fieldList, (string)$row_data[0]);
array_push($fieldList, (string)$row_data[1]);
array_push($fieldList, (string)$row_data[2]);
array_push($finalFieldList, $fieldList); // it will push to final array containing all 3 values
}

Convert a CSV to JSON and change specific key values into Boolean or string using PHP

Is there a way I can change specific key values into boolean or string. The conversion changes all the Data into string. For example the Key value "Date" should be an integer instead of a string.
<?php
function csvToJson($fname) {
if (!($fp = fopen($fname, 'r') )) {
die("Can't open file");
}
$key = fgetcsv($fp, "1024", ",");
$json = array();
while ($row = fgetcsv($fp, "1024", ",")) {
$json[] = array_combine($key, $row);
}
fclose($fp);
foreach ( $json as $k=>$v ) {
$json[$k]['dateRequested'] = $json[$k]['DATE'];
$json[$k]['assignedAgent'] = $json[$k]['AGENT'];
$json[$k]['finalCompanyName'] = $json[$k]['COMPANY NAME'];
unset($json[$k]['DATE']);
unset($json[$k]['AGENT']);
unset($json[$k]['COMPANY NAME']);
}
return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
?>
<?php
$json_data = csvToJson("lms.csv");
?>
Try this:
while ($row = fgetcsv($fp, "1024", ",")) {
// here $row contains all the columns in it in a numeric array
// Means 0 => first column of csv, 2 => second column of csv and so on
// you can convert any specific column value like
$json[] = array($row[0], setype($row[0], "string"), and so on);
}
You can do like this:
$json[$k]['dateRequested'] = (int)($json[$k]['DATE']);
$json[$k]['assignedAgent'] = $json[$k]['AGENT'];
$json[$k]['finalCompanyName'] = $json[$k]['COMPANY NAME'];
Sample usage :
$int = (int)(123);
$bool = (bool)(1);
$string = (string)(1234);
var_dump($int);
var_dump($bool);
var_dump($string);

Using PHP to display items on page

I have a document called subjects.txt in the following format:
DateCreated,Subject,Link
18.10.2015,"Math",http: //address.html
17.10.2015,"English",http: //address.html
18.10.2015,"English",http: //address.html
19.10.2015,"Science",http: //address.html
17.10.2015,"Math",http: //address.html
The file contains URLs of sites created based on a school subject. There can be more than one site for a subject.
The goal is to use PHP to open, read, and display the contents of the file in the following format:
Math
Link 1
Link 2
English
Link 1
Link 2
Science (because there's only one link, the name of the subject is the
link)
So far I've been able to open and read the file:
$file = "./subjects.txt";
$subjects = file_get_contents($file);
I'm having trouble trying to determine how to go about writing the file in specified format.
I've tried using explode to separate the elements with "," - however I don't know where to go from there.
Your input file looks to be in Comma-separated values (CSV) format. PHP has a built-in fgetcsv function designed to make reading CSV data from a file easy.
<?php
$file = './subjects.txt';
$fh = fopen($file, 'r');
if ($fh === false) {
die("Can not read {$file}");
}
$data = array();
while (($row = fgetcsv($fh, 1000, ',')) !== false) {
if ($row[0] === 'DateCreated') {
// Ignore the column header row
continue;
}
list($date, $subject, $link) = $row;
if (!isset($data[$subject])) {
$data[$subject] = array();
}
$data[$subject][] = $link;
}
fclose($fh);
foreach ($data as $subject => $links) {
// TODO: output each subject here
}
Here is another version
<?php
$file = "./subjects.txt";
$h = fopen($file, "r");
if($h !== false) {
$subjects = [];
$data = [];
while(!feof($h)) {
if($line = trim(fgets($h))) {
$line = explode(",", $line);
if(!in_array("DateCreated",$line)) {
array_push($subjects, $line);
}
}
}
fclose($h);
foreach ($subjects as $subject) {
if(!isset($data[$subject[1]])) {
$data[$subject[1]] = [];
}
$data[$subject[1]][] = $subject[2];
}
foreach ($data as $subject => $links) {
if(count($links) == 1) {
echo "<p>$subject</p>\n";
} else {
$i = 1;
echo "<p>$subject</p>\n";
echo "<ul>\n";
foreach ($links as $link) {
echo "<li>link$i</li>\n";
$i++;
}
echo "</ul>\n";
}
}
}
?>
The problem using file_get_contents() is that retrieves all the file contents into $subjects.
You have to use a different approach. For example fgets():
$fp = fopen("./subjects.txt", "r");
if ($fp){
while (($line = fgets($fp)) !== false){
// So here you can treat each line individually.
// You can use explode (";", $line) for example if the line is not empty
}
}
fclose($fp);
Using fgets() will allow you to parse each of the file's lines individually.
As stated doing this with a database would be much easier probably 3 lines of code. Here's one approach you could use though.
$data = '18.10.2015,"Math",http: //address.html
17.10.2015,"English",http: //address1.html
18.10.2015,"English",http: //address2.html
19.10.2015,"Science",http: //address3.html
17.10.2015,"Math",http: //address4.html';
preg_match_all('~^(.*?),"(.*?)",(.*?)$~m', $data, $fields);
array_multisort($fields[2], SORT_STRING, $fields[1], $fields[3]);
$lastcat = '';
foreach($fields[2] as $key => $cat) {
if($cat != $lastcat) {
echo $cat . "\n";
}
$lastcat = $cat;
echo $fields[3][$key] . "\n";
}
Output:
English
http: //address1.html
http: //address2.html
Math
http: //address4.html
http: //address.html
Science
http: //address3.html
The array_multisort is how the categories are grouped.
Here's a regex101 demo of what that regex is doing. https://regex101.com/r/wN3nB2/1
Update for single record check (only ran 1 test on it):
$data = '18.10.2015,"Math",http: //address.html
17.10.2015,"English",http: //address1.html
18.10.2015,"English",http: //address2.html
19.10.2015,"Science",http: //address3.html
17.10.2015,"Math",http: //address4.html';
preg_match_all('~^(.*?),"(.*?)",(.*?)$~m', $data, $fields);
array_multisort($fields[2], SORT_STRING, $fields[1], $fields[3]);
$lastcat = '';
foreach($fields[2] as $key => $cat) {
if((empty($fields[2][($key +1)]) && $cat != $lastcat)|| ($cat != $lastcat && !empty($fields[2][($key +1)]) && $fields[2][($key +1)] != $cat)) {
//single record
echo $cat . $fields[3][$key] . "\n";
} else {
if($cat != $lastcat) {
echo $cat . "\n";
}
$lastcat = $cat;
echo $fields[3][$key] . "\n";
}
}

PHP get string from CSV for a duplicate entry

I have this big file containing SWIFT numbers and bank names. I'm using the following php function for reading and comparing data:
function csv_query($blz) {
$cdata = -1;
$fp = fopen(DIR_WS_INCLUDES . 'data/swift.csv', 'r');
while ($data = fgetcsv($fp, 1024, ",")) {
if ($data[0] == $blz){
$cdata = array ('blz' => $data[0],
'bankname' => $data[7]);
// 'prz' => $data[2]
}
}
return $cdata;
}
The csv files looks like that:
"20730054",1,"UniCredit Bank - HypoVereinsbank (ex VereinWest)","21423","Winsen (Luhe)","UniCredit Bk ex VereinWest",,"HYVEDEMM324","68","013765","M",1,"20030000"
"20750000",1,"Sparkasse Harburg-Buxtehude","21045","Hamburg","Spk Harburg-Buxtehude","52002","NOLADE21HAM","00","011993","U",0,"00000000"
"20750000",2,"Sparkasse Harburg-Buxtehude","21605","Buxtehude","Spk Harburg-Buxtehude","52002",,"00","011242","U",0,"00000000"
As you can see from the code, I need the first and the eight string. If the first string has no duplicates everything is ok, but if it has, most likely the eighth field of the duplicate will be empty and I get no result back. So I want to ask how to display that eighth field of the first result if the line has a duplicate.
I guess this will solve your problem :
function csv_query($blz) {
$cdata = -1;
$fp = fopen(DIR_WS_INCLUDES . 'data/swift.csv', 'r');
$counter = 0; // add this line
while ($data = fgetcsv($fp, 1024, ",")) {
if ($data[0] == $blz && !$counter) { //change this line
$cdata = array(
'blz' => $data[0],
'bankname' => $data[7]
);
$counter++; //add this line
}
}
return $cdata;
}

list values into array

I'm fairly new to php, so please excuse my ignorance here... :P
I have the following code:
<?php
$fh = fopen("../filename.csv", "r");
while (list($siteid, $sitename, $scheduled, $arecords, $crons, $sslintf, $customip, $psccjobs, $odbc, $sitesize, $dbsize, $nfssize, $fasize, $siteclass, $dbexport, $chatver, $socintf, $sitemode, $mailboxes, $mailfiles, $oesmtp) = fgetcsv($fh, 1024, ";")) {
echo "<p>$siteid, $sitename, $scheduled, $arecords, $crons, $sslintf, $customip, $psccjobs, $odbc, $sitesize, $dbsize, $nfssize, $fasize, $siteclass, $dbexport, $chatver, $socintf, $sitemode, $mailboxes, $mailfiles, $oesmtp</p>";
}
?>
I want to add each row of variables into an array...
Any Suggestions would be helpful, even if there is a better approach.
gah.... why not simply
while($row = fgetcsv($fh)) {
echo "<p>", implode(', ', $row), "</p>";
}
If you want to store each row in an array, then
$data = array();
while($row = fgetcsv($fh)) {
echo "<p>", implode(', ', $row), "</p>";
$data[] = $row;
}

Categories