PHP read in specific csv file column as an array - php

I am new to PHP and would like to be able to read in a csv file which has two columns, one is the number (kind of like a ID) then the other holds a integer value. I have looked up the fgetcsv function but I have not been able to find a way to read a specific column from the csv file.
I would like to get all the values from the second column only, without the heading.
Any way of doing this?
This is what I have so far:
$file = fopen('data.csv', 'r');
$line = fgetcsv($file);
And this is some sample data from the csv file:
ID,Value
1,243.00
2,243.00
3,243.00
4,243.00
5,123.11
6,243.00
7,180.00
8,55.00
9,243.00
Any help would be appreciated.
Thanks.

fgetcsv() only reads a single line of the file at a time. You'll have to read the file in a loop to get it all:
$data = array();
while($row = fgetcsv($file)) {
$data[] = $row;
}
The heading you can skip by doing an fgetcsv once outside the loop, to read/trash the header values. And if you only want the second column, you can do:
$data[] = $row[1];
However, since you've got data in there, maybe it might be useful to keep it, plus key your new array with the ID values in the csv, so you could also have:
$data[$row[0]] = $row[1];
and then your nice shiny new array will pretty much exactly match what's in the csv, but as an array keyed by the ID field.

$csv = array_map("str_getcsv", file("data.csv", "r"));
$header = array_shift($csv);
// Seperate the header from data
$col = array_search("Value", $header);
foreach ($csv as $row) {
$array[] = $row[$col];
}
// Iterate through data set, creating array from Value column

$header = fgetcsv($h);
$rows = array();
while ($row = fgetcsv($h)) {
$rows []= array_combine($header, $row);
}

$fp = fopen($filePath, "r+");
$header = fgetcsv($fp);
while ($members = fgetcsv($fp)) {
$i = 0;
foreach ($members as $mem) {
$membersArray[ $i ][ ] = $mem;
$i++;
}
}
$newArray = array_combine($header, array_map("array_filter",$membersArray));

You can also use this class http://code.google.com/p/php-csv-parser/
<?php
require_once 'File/CSV/DataSource.php';
$csv = new File_CSV_DataSource;
$csv->load('data.csv');
var_export($csv->connect());
?>

Related

How to sort a CSV file by a column and then sort by a second column, then saving the CSV file

I'm looking to read a CSV export file with PHP. I have access to the File Path Variable called $file_path.
How would I sort the CSV export file by a specific column and then sort it again by a second column? and then save the CSV file to the same file name and file path.
UPDATE:
I got it to read the CSV, then sort it and also save it to the CSV. However, it's also sorting the headers. I am trying to use array_shift and array_unshift but when I use array_shift with a multi-layer array, I am getting an error. (unshift works fine though).
function wp_all_export_after_export($export_id, $exportObj)
{
// Check whether "Secure Mode" is enabled in All Export -> Settings
$is_secure_export = PMXE_Plugin::getInstance()->getOption('secure');
if (!$is_secure_export) {
$filepath = get_attached_file($exportObj->attch_id);
} else {
$filepath = wp_all_export_get_absolute_path($exportObj->options['filepath']);
}
$handle = fopen($filepath, 'r') or die('cannot read file');
$binNumber = array();
$category = array();
$rows = array();
$header = array();
//build array of binNumbers, Categories, and array of rows
while (false != ( $row = fgetcsv($handle, 0, ',') )) {
$binNumber[] = $row[3];
$category[] = $row[1];
$rows[] = $row;
}
fclose($handle);
$header = $rows[0];
array_shift($rows);
//sort array of rows by BinNumber & then Category using our arrays
array_multisort($binNumber,SORT_ASC, $category, SORT_ASC, $rows);
array_unshift($rows,$header);
$file = fopen($filepath,"w");
foreach ($rows as $line) {
fputcsv($file, $line);
}
fclose($file);
}
add_action('pmxe_after_export', 'wp_all_export_after_export', 10, 2);

Create key-value pair from csv php

I have a csv file like below
tl_blade_thickness,tl_blade
test1,test1
test2,test2
test3,test3
test4,test4
test5,test5
test6,test6
test7,test7
test8,test8
test9,test9
I'm trying to create a key value pair array like below.
["tl_blade_thickness"=>["test1","test2","test3",...],tl_blade=>["test1","test2","test3",...]]
I tried like this below.
$content = fopen("csv.csv", "r");
$all_rows = array();
$header = fgetcsv($content);
while ($row = fgetcsv($content)) {
$all_rows[] = array_combine($header, $row);
}
Use the first line of the file to create the keys of the array. Then push each field of the remaining lines into the corresponding element keys.
$content = fopen("csv.csv", "r");
$headers = fgetcsv($content);
$all_rows = array_fill_keys($headers, []);
while ($row = fgetcsv($content)) {
foreach ($headers as $i => $name) {
$all_rows[$name][] = $row[$i];
}
}

CSV data to array_map and str_getcsv using delimiter

My problem is I'm unable to pass 2nd parameter to str_getcsv function.
$rows = array_map('str_getcsv', file($filePath_product_names_t), [";"]);
$header = array_shift($rows);
$csv = [];
foreach($rows as $row) {
$csv[] = array_combine($header, $row);
}
CSV structure
"25";"some text"; "also some Text"
And also getting WARNING:
array_combine(): Both parameters should have an equal number of
elements
Try this:
$rows = array_map(function($v){return str_getcsv($v, ";");}, file($filePath_product_names_t));
$header = array_shift($rows);
$csv = [];
foreach($rows as $row) {
$csv[] = array_combine($header, $row);
}
print_r($rows);
Combining the two problems, the first is that you can't pass a parameter the way you are trying in the array_map() so as in the link I posted in the comments, you can create an anonymous function to do this.
The second is that, in some cases a CSV file doesn't always have all the data for a row in the file. In this case the header row and the other rows don't have the same amount of data, so use array_pad() to add blanks to make sure they do have the same length. To combine these into the code...
$rows = array_map(function($data) { return str_getcsv($data,";");}
, file($filePath_product_names_t));
$header = array_shift($rows);
$csv = [];
foreach($rows as $row) {
$row = array_pad($row, count($header), "");
$csv[] = array_combine($header, $row);
}
print_r($csv);

Declaring different variables in foreach loop

I know the title of my question may be confusing, but I'm not quite sure how to explain what I'm trying to do concisely.
I am trying to loop through an array of CSVs and load the data into variables with differing names. In my example below, instead of $foo_data it would be $MSFT_data, $AAPL_data, and $FB_data in each loop through the $stocks array.
$stocks = array($msft, $aapl, $fb);
foreach ($stocks as $stock) {
$fh = fopen($stock, 'r');
$header = fgetcsv($fh);
$foo_data = array();
while ($line = fgetcsv($fh)) {
$foo_data[] = array_combine($header, $line);
}
fclose($fh);
}
Please let me know if you need more information.
There are two problems. The first is that you cannot get the variable name, so the script has no way to know that there is an $msft, $aapl, $fb, so you need to pass the name along with the array. The second is that you need variable variables.
Try
$stocks = array('MSFT' => $msft, 'AAPL' => $aapl, 'FB' => $fb);
foreach ($stocks as $key=>$stock) {
$fh = fopen($stock, 'r');
$header = fgetcsv($fh);
$varname = $key . '_data';
$$varname = array(); //the double $$ will set the var content as variable ($MSFT_data)
while ($line = fgetcsv($fh)) {
${$varname}[] = array_combine($header, $line);
//the {} are needed to let PHP know that $varname is the name of the variable and not $varname[].
}
fclose($fh);
}
$MSFT_data = $foo_data[0];
$AAPL_data = $foo_data[1];
$FB_data = $foo_data[2];
How does that work for you?

deleting matches from text file in php

Consider a txt file of a list of items
qqqqqq
eeeeee
dddddd
hhhhhh
dddddd
hhhhhh
999999
And some of the items in the list are duplicates. how do I output a using php a text file where anything that is duplicated is removed.
the result:
qqqqqq
eeeeee
999999
You can use array_unique
and then right the content back
$file = fopen("filename.txt", "r");
$members = array();
while (!feof($file)) {
$members[] = fgets($file);
}
fclose($file);
$unique_members = array();
$unique_members = array_unique($members);
var_dump($unique_members);
//write the content back to the file
The above solution was for removing the duplicates only and make them unique. Thanks to nhahtdh for pointing it out.
$count_members = array_count_values($members);
foreach($count_members as $key=>$value)
{
if($value == 1)
//write it to the file
}
So you will not need the array_unique stuff
Sorry again
<?php
$file = file_get_contents('file.txt'); //get file to string
$row_array = explode("\n",$file); //cut string to rows by new line
$row_array = array_count_values(array_filter($row_array));
foreach ($row_array as $key=>$counts) {
if ($counts==1)
$no_duplicates[] = $key;
}
//do what You want
echo '<pre>';
print_r($no_duplicates);
file_put_contents('no_duplicates.txt',$no_duplicates); //write to file. If file don't exist. Create it.

Categories