cut csv and save in array - php

I have a csv file, build in this format:
| id | keyword | description | more ... |
| 1 | myKeyword | MyDescription | some stuff |
| 2 | | | some stuff |
| 3 | myKeyword | MyDescription | some stuff |
right now, I want to create a small PHP script, which reads only the first three columns and save these afterwards in an array. For that, i looked up fgetcsv but that didn't do the trick. Then I tried somehting like this:
$csv = array_map('str_getcsv', file('myFile.csv'));
but that wasn't it, either.
The file i got is pretty messy and this is why I have to check if keywords and descriptions even exists (more like they are not '').
My output array should be something like:
$array[0][0] = 1
$array[0][1] = MyKeyword
$array[0][2] = MyDescription
$array[1][0] = 3
$array[1][1] = MyKeyword
$array[1][2] = MyDescription
Thank you already in advance

Okay, nevermind, i got it.
I found a pretty good solution in the phpdoc of fgetcsv
<?php
function get2DArrayFromCsv($file,$delimiter) {
if (($handle = fopen($file, "r")) !== FALSE) {
$i = 0;
while (($lineArray = fgetcsv($handle, 4000, $delimiter)) !== FALSE) {
for ($j=0; $j<count($lineArray); $j++) {
$data2DArray[$i][$j] = $lineArray[$j];
}
$i++;
}
fclose($handle);
}
return $data2DArray;
}
?>

Read the CSV line by line, and split the lines by your delimiter, and append the resultant arrays to a result array.
array1 = array();
$handle = fopen("file.csv", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
array1 = array_merge(array1, explode('|',$line);
}
}
fclose($handle);

You could first parse everything with:
using the function str-getcsv using its options (delimiters and enclosure). The "basic" function may not be able to catch the syntax of your csv file as there is no real standard for it.
or if you think it worths it, using this parser class
Then, you may either drop the undesired elements of your table or just ignore them. I hope it will help you a bit.

Related

Value of previous row in CSV import via PHP

I'm importing data from a CSV via PHP.
On some lines of the CSV, column 1 has a value, and on other lines it does not have a value. Column 2 always has a value.
If column 1 is empty and column 2 has a value, I would like column 1 to use the previous value in column 1. For example
|-------|-------|
| Col 1 | Col 2 |
|-------|-------|
| A | 2 |
| B | 5 |
| C | 3 |
| | 1 |
| D | 7 |
Would return
A2
B5
C3
C1
D7
I can use prev() on an array, but as $data[0] is a string I can't use prev()
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if ($i > 0) {
if ($data[0]=='' && $data[1]!=='') {
echo prev($data[0]).$data[1]'<br/>';
} else {
echo $data[0].$data[1]'<br/>';
}
}
$i++;
}
Banging my head against a wall for hours now, so I'd love a pointer!
This should work as long as the first row is not empty...
$x = null;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if ($i > 0) {
$x = $data[0] == '' ? $x : $data[0];
// this is like: if $data[0] is empty then use $x else say $x is $data[0].
// Like that you can keep track of the previous value.
// If there is one overwrite with the new one else keep the old value
echo $x.$data[1]'<br/>';
}
$i++;
}
You can store previous value in the variable and use that
$previousColumn1 = '';
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if ($i > 0) {
if ($data[0]=='' && $data[1]!=='') {
echo $previousColumn1.$data[1]'<br/>';
} else {
$previousColumn1 = $data[0];
echo $data[0].$data[1]'<br/>';
}
}
$i++;
}
As has been mentioned, just storing the previous value and overwriting it any time a new value is given will do the job. It will assume that if the first row is blank that the $prev value you provide outside the loop will be used...
$prev = '';
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$prev = $data[0]?:$prev;
echo $prev.$data[1].PHP_EOL;
}
This uses the short form of ?: to say if there is a value for $data[0] - then use it, otherwise use $prev.

PHP probleme while remove columns in csv

I use the php script below to remove some columns from a csv, order them new and save it as new file.
And it works for the file i made it for.
Now i need to do the same with another csv but i don't know whats wrong. I always get a comma befor the data in the first column.
This is what i have, but it doesn't really work.
<?php
$input = 'http://***/original.csv';
$output = 'new.csv';
if (false !== ($ih = fopen($input, 'r'))) {
$oh = fopen($output, 'w');
while (false !== ($data = fgetcsv($ih))) {
// this is where you build your new row
$outputData = array($data[4], $data[0]);
fputcsv($oh, $outputData);
}
fclose($ih);
fclose($oh);
}
The original.csv looks that:
subproduct_number barcode stock week_number qty_estimate productid variantid
05096470000 4024144513543 J 3 6 35016
ae214 848518017215 N 23 0 7 35015
05097280000 4024144513727 J 1 32 34990
The seperator is ';'. The same seperator is used in the file that is working
But here it will be go wrong because my saved new.csv looks like this:
subproduct_number barcode stock week_number qty_estimate productid variantid
,05096470000 4024144513543 J 3 6 35016
,ae214 848518017215 N 23 0 7 35015
,05097280000 4024144513727 J 1 32 34990
But what i need is a new csv that looks like this:
qty_estimate subproduct_number
3 05096470000
0 ae214
1 05097280000
As you can see, i need only the 5. column ($data[4]) as first and the first column ($data[0]) as the second one.
I hope someone can point me in the reight direction.
Thanks
You can do so:
while (false !== ($data = fgetcsv($ih))) {
$data = explode(';', $data[0]);
$outputData = array($data[4], $data[0]);
fputcsv($oh, $outputData, ';');
}

How to sort CSV table data in PHP by a specific column?

Here's the CSV table:
-------------------------
| Name | Age | Favorite |
-------------------------
| John | 30 | Apple |
-------------------------
| Bill | 25 | Grape |
-------------------------
| Ann | 40 | Orange |
-------------------------
Now, using strictly PHP, is there anyway to sort only the "Favorite" by ascending order of "Age"? An expected output would be something like this:
25 Grape
30 Apple
40 Orange
I've been using fgetcsv to echo them onto the document, but they are not not sorted by ascending age, of course. Is there anyway to throw these in an array or something, sort by age, and then echo?
To open up your CSV file:
function readCSV($file)
{
$row = 0;
$csvArray = array();
if( ( $handle = fopen($file, "r") ) !== FALSE ) {
while( ( $data = fgetcsv($handle, 0, ";") ) !== FALSE ) {
$num = count($data);
for( $c = 0; $c < $num; $c++ ) {
$csvArray[$row][] = $data[$c];
}
$row++;
}
}
if( !empty( $csvArray ) ) {
return array_splice($csvArray, 1); //cut off the first row (names of the fields)
} else {
return false;
}
}
$csvData = readCSV($csvPath); //This is your array with the data
Then you could use array_multisort() to sort it on a value.
<?php
// Obtain a list of columns
foreach ($csvData as $key => $row) {
$age[$key] = $row['volume'];
$favorite[$key] = $row['edition'];
}
// Sort the data with age first, then favorite
// Add $csvData as the last parameter, to sort by the common key
array_multisort($age, SORT_ASC, $favorite, SORT_ASC, $csvData);
?>

PHP How can I combine two CSVs based on common fields in a rows of each csv?

I have two CSVs:
1st csv is something like this:
number | color | size | animal
**1234** | black | big | cat
2nd csv is like this:
name | country | os | number | flavour | yesorno
john | world | windows | **1234** | good | yes
What I'm trying to do is to merge both CSV's (header titles and values of each row) based on matching number values:
number | color | size | animal | name | country | os | flavour | yesorno
**1234** | black | big | cat | john | world | windows | good | yes
I have been trying to use fgetcsv and used keys but I am really a newbie to php and I do not know how to that. I need to understand the logic. Could anyone please help?
Many thanks.
-- edit for better udnerstanding --
based on another question on stackoverflow, I have tryed the following code, which is not working well. The two headers from both CSV files is not merged. It is also missing all the data from a csv, it only has one row of data merged.
Code was found in another question: Merging two csv files together using php and seemed like a perfect base for what I am trying to achieve. Unfortunately the outputed csv is malformed...
<?php
// 1st section
$fh = fopen('csv1.csv', 'r');
$fhg = fopen('csv2.csv', 'r');
while (($data = fgetcsv($fh, 0, ";")) !== FALSE) {
$csv1[] = $data;
}
while (($data = fgetcsv($fhg, 0, ",")) !== FALSE) {
$csv2[] = $data;
}
// 2nd section
for ($x = 0; $x < count($csv2data); $x++) {
if ($x == 0) {
unset($csv1data[0][17]);
$line[$x] = array_merge($csv2data[0], $csv1data[17]); //header
} else {
$deadlook = 0;
for ($y = 0; $y <= count($csv1data); $y++) {
if($csv1data[$y][17] == $csv2data[$x][0]){
unset($csv1data[$y][17]);
$line[$x]=array_merge($csv2data[$x],$csv1data[$y]);
$deadlook=1;
}
}
if ($deadlook == 0)
$line[$x] = $csv2data[$x];
}
}
// 3 section
$fp = fopen('final.csv', 'w'); //output file set here
foreach ($line as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
?>
$fh = fopen('csv1', 'r');
$fhg = fopen('csv2', 'r');
while (($data = fgetcsv($fh, 0, ",")) !== FALSE) {
$csv1[]=$data;
}
while (($data = fgetcsv($fhg, 0, ",")) !== FALSE) {
$csv2[]=$data;
}
// 2nd section
for($x=0;$x< count($csv2);$x++)
{
if($x==0){
unset($csv1[0][0]);
$line[$x]=array_merge($csv2[0],$csv1[0]); //header
}
else{
$deadlook=0;
for($y=0;$y <= count($csv1);$y++)
{
if($csv1[$y][0] == $csv2[$x][0]){
unset($csv1[$y][0]);
$line[$x]=array_merge($csv2[$x],$csv1[$y]);
$deadlook=1;
}
}
if($deadlook==0)
$line[$x]=$csv2[$x];
}
}
// 3 section
$fp = fopen('final.csv', 'w');//output file set here
foreach ($line as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
In section 1
open those 2 file and put the content in an array $csv1[] and $csv2[], so $csv1[0] is the first line in csv1.csv, $csv1[1] is the second line in csv1.csv, etc, the same in $csv2[].
In section 2,
i compare the first word in every array, $csv1[x][0] and $csv2[x][0].
the first if, if($x==0), is to make the header. first, i delete the first word contractname using unset function and join $csv1[0] and $csv2[0] using array_merge function.
then, using those for i select the first word in every line from $csv2 array and compare with the first word from every line from $csv1 array. so, if($csv1[$y][0] == $csv2[$x][0]) check if those first word are the same, if those are the same string, delete it and merge those lines.
if those word arent the same, save the $csv2[x] line in $line array and continue.
In section 3,
save the content from $line array in the file.
$fromFile = fopen($REcsv,'r');
$fromFile2 = fopen($pathToFile,'r');
$toFile = fopen($reportFile,'w');
$delimiter = ';';
$line = fgetcsv($fromFile, 65536, $delimiter);
$line2 = fgetcsv($fromFile2, 65536, $delimiter);
while ($line !== false) {
while ($line2 !== false) {
fputcsv($toFile, array_merge($line2,$line), $delimiter);
$line = fgetcsv($fromFile, 65536, $delimiter);
$line2 = fgetcsv($fromFile2, 65536, $delimiter);
}
}
fclose($fromFile);
fclose($fromFile2);
fclose($toFile);

Can't read correctly from a .txt file in php

I'm trying to read from a text file that is downloaded from www.groupsort.com
The format looks like this:
Name Rank Team
Mike 1 Team 2
Charlie 5 Team 1
Joe 3 Team 1
David 21 Team 3
Also I don't know if this is related, but when I went to pico this file, it wouldn't show me clear text, it was just a bunch of garbage, but it's a .txt file. Weird?
So I want to get the usernames and store them in a variable. Shouldn't something like this work?
$file = "peopletomove.txt";
$fh = fopen($file,'r');
$MoveTSusers = array();
while (!feof($fh)) {
$line = fgets($fh);
echo $line."\n";
$name = strpos($line, " ");
$name2 = substr($line, 0, $name);
echo $name2."\n";
You have tab-separated values. So separate on tab:
while(!feof($fh)) {
$line = trim(fgets($fh));
if( !$line) continue; // blank line
list($name,$rank,$team) = explode("\t",$line);
}

Categories