I have a space separated csv file. I am trying to read using following method:
$file = fopen('/var/www/html/my.csv', 'r');
while (($line = fgetcsv($file,0,"\t")) !== FALSE) {
$header_count = 0;
// $final_data = array();
if ( $count == 0 )
{
foreach ($line as $data) {
$header[$header_count] = $data;
$header_count++;
}
}
else
{
// print_r($line);
foreach ($line as $data) {
$final_data[$count-1][$header[$header_count]] = $data;
$header_count++;
}
}
$count++;
}
The file looks like:
id created ad
410699345585 11:12:29+05:30 ag:6061734588280
...
But, the reading output gives:
["��id"]=>
as id index. What am I doing wrong?
Related
I've got a csv file which contains product datas and prices from two distributors.
There are 67 keys in this file.
Now I want to search all EANs in this file which are twice available and then get the cheapest price.
After that delete the other higher price product line.
The CSV has a key for my merchant.
I made a test csv for easier view:
artno;name;ean;price;merchant
1;ipad;1654213154;499.00;merchant1
809;ipad;1654213154;439.00;merchant2
23;iphone;16777713154;899.00;merchant2
90;iphone;16777713154;799.00;merchant1
After the script runs through, the csv should look like (writing to new file):
artno;name;ean;price;merchant
809;ipad;1654213154;439.00;merchant2
90;iphone;16777713154;799.00;merchant1
I played around with fgetcsv, looping through the csv is not a problem, but how I can search for the ean in key 2?
$filename = './test.csv';
$file = fopen($filename, 'r');
$fileline = 1;
while (($data = fgetcsv($file, 0, ";")) !== FALSE) {
if($fileline == "1"){ $fileline++; continue; }
$search = $data[2];
$lines = file('./test.csv');
$line_number = false;
$count = 0;
while (list($key, $line) = each($lines) and !$line_number) {
$line_number = (strpos($line, $search) !== FALSE) ? $key : $line_number;
$count++;
}
if($count > 2){
echo "<pre>",print_r(str_getcsv($lines[$line_number], ";")),"</pre>";
}
}
I think this is what you are looking for:
<?php
$filename = './test.csv';
$file = fopen($filename, 'r');
$lines = file('./test.csv');
$headerArr = str_getcsv($lines[0], ";");
$finalrawData = [];
$cheapeastPriceByProduct = [];
$dataCounter = 0;
while (($data = fgetcsv($file, 0, ";")) !== FALSE) {
if($dataCounter > 0) {
$raw = str_getcsv($lines[$dataCounter], ";");
$tempArr = [];
foreach( $raw as $key => $val) {
$tempArr[$headerArr[$key]] = $val;
}
$finalrawData[] = $tempArr;
}
$dataCounter++;
}
foreach($finalrawData as $idx => $dataRow ) {
if(!isset($cheapeastPriceByProduct[$dataRow['name']])) {
$cheapeastPriceByProduct[$dataRow['name']] = $dataRow;
}
else {
if(((int)$dataRow['price'])< ((int)$cheapeastPriceByProduct[$dataRow['name']]['price'])) {
$cheapeastPriceByProduct[$dataRow['name']] = $dataRow;
}
}
}
echo "<pre>";
print_r($finalrawData);
print_r($cheapeastPriceByProduct);
I just added $finalData data array to store the parsed data and associated all rows with their header key counterpart then you can compare and filter data based on your criteria.
I have tree arrays with different lengths, and I want to display each array in a column of my csv file. That's the php script file I am using but no success; I got the data duplicated.
The attempt I tried was to feed empty cells with an empty string so that I can have 3 columns with the same lengths.
$categories = get_categories( $args );
$categories_level_1 = array();
$categories_level_2 = array();
$categories_level_3 = array();
foreach ($categories as $cat ) {
$cat_level =count( get_ancestors($cat->term_id, 'category') );
if($cat_level == 0){
$categories_level_1[] = $cat;
}else{
if($cat_level == 1){
$categories_level_2[] = $cat;
}elseif($cat_level == 2){
$categories_level_3[] = $cat;
}
}
}
fputcsv($file, array(utf8_decode('Catégories level 1')));
$i=0;
foreach ($categories_level_1 as $category) {
$i++;
$categorie_name = array(rw_mb_convert_encoding($category->name));
fputcsv($file, $categorie_name );
print_flush("\n liine created");
}
while( $i < count($categories_level_2)){
$i++;
fputcsv($file, array(" "));
print_flush("\n liine vide created");
}
fclose($file);
$newCsvData = array();
foreach ($categories_level_2 as $cat) {
if (($handle = fopen($csv_file_path, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$data[] = rw_mb_convert_encoding($cat->name);
$newCsvData[] = $data;
}
fclose($handle);
}
}
$handle = fopen($csv_file_path, 'w');
foreach ($newCsvData as $line) {
fputcsv($handle, $line);
}
fclose($handle);
I should get my columns with the folowwing structure :
But in reality that's the result I got :
I would like to convert a csv file that has duplicate contents and i would like to sum the quantity and extract the price without sum it.
file.csv :
code,qty,price
001,2,199
001,1,199
002,2,159
002,2,159
Actual php that sum the quantiy and get a result with unique value and total qty.
<?php
$tsvFile = new SplFileObject('file.csv');
$tsvFile->setFlags(SplFileObject::READ_CSV);
$tsvFile->setCsvControl("\t");
$file = fopen('file.csv', 'w');
$header = array('sku', 'qty');
fputcsv($file, $header, ',', '"');
foreach ($tsvFile as $line => $row) {
if ($line > 0) {
if (isset($newData[$row[0]])) {
$newData[$row[0]]+= $row[1];
} else {
$newData[$row[0]] = $row[1];
}
}
}
foreach ($newData as $key => $value) {
fputcsv($file, array($key, $value), ',', '"');
}
fclose($file);
?>
the result for this is:
code,qty
001,3
002,4
and i would like to add price, but without sum it.
The result i need is:
code,qty,price
001,3,199
002,4,159
I haven't tested this yet, but I think this is what you are looking for:
<?php
$tsvFile = new SplFileObject('file.csv');
$tsvFile->setFlags(SplFileObject::READ_CSV);
$tsvFile->setCsvControl("\t");
$file = fopen('file.csv', 'w');
$header = array('sku', 'qty');
fputcsv($file, $header, ',', '"');
foreach ($tsvFile as $line => $row) {
if ($line > 0) {
if(!isset($newData[$row[0]])) {
$newData[$row[0]] = array('qty'=>0, 'price'=>$row[2]);
}
$newData[$row[0]]['qty'] += $row[1];
}
}
foreach ($newData as $key => $arr) {
fputcsv($file, array($key, $arr['qty'], $arr['price']), ',', '"');
}
fclose($file);
?>
To start with, there's a nice function on the PHP page str_getcsv which will help you end up with a more legible array to work with:
function csv_to_array($filename='', $delimiter=',') {
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE) {
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
This is purely for legibility sake but now comes the code which would allow you to work over the array.
$aryInput = csv_to_array('file.csv', ',');
$aryTemp = array();
foreach($aryInput as $aryRow) {
if(isset($aryTemp[$aryRow['code'])) {
$aryTemp[$aryRow['code']['qty'] += $aryRow['qty'];
} else {
$aryTemp[$aryRow['code']] = $aryRow;
}
}
In the above code, it simply:
Loops through the input
Checks whether the key exists in a temporary array
If it does, it just adds the new quantity
If it doesn't, it adds the entire row
Now you can write out your expectant csv file :)
I would like to convert a CSV to Json, use the header row as a key, and each line as object. How do I go about doing this?
----------------------------------CSV---------------------------------
InvKey,DocNum,CardCode
11704,1611704,BENV1072
11703,1611703,BENV1073
---------------------------------PHP-----------------------------------
if (($handle = fopen('upload/BEN-new.csv'. '', "r")) !== FALSE) {
while (($row_array = fgetcsv($handle, 1024, ","))) {
while ($val != '') {
foreach ($row_array as $key => $val) {
$row_array[] = $val;
}
}
$complete[] = $row_array;
}
fclose($handle);
}
echo json_encode($complete);
Just read the first line separately and merge it into every row:
if (($handle = fopen('upload/BEN-new.csv', 'r')) === false) {
die('Error opening file');
}
$headers = fgetcsv($handle, 1024, ',');
$complete = array();
while ($row = fgetcsv($handle, 1024, ',')) {
$complete[] = array_combine($headers, $row);
}
fclose($handle);
echo json_encode($complete);
I find myself converting csv strings to arrays or objects every few months.
I created a class because I'm lazy and dont like copy/pasting code.
This class will convert a csv string to custom class objects:
Convert csv string to arrays or objects in PHP
$feed="https://gist.githubusercontent.com/devfaysal/9143ca22afcbf252d521f5bf2bdc6194/raw/ec46f6c2017325345e7df2483d8829231049bce8/data.csv";
//Read the csv and return as array
$data = array_map('str_getcsv', file($feed));
//Get the first raw as the key
$keys = array_shift($data);
//Add label to each value
$newArray = array_map(function($values) use ($keys){
return array_combine($keys, $values);
}, $data);
// Print it out as JSON
header('Content-Type: application/json');
echo json_encode($newArray);
Main gist:
https://gist.github.com/devfaysal/9143ca22afcbf252d521f5bf2bdc6194
For those who'd like things spelled out a little more + some room to further parse any row / column without additional loops:
function csv_to_json_byheader($filename){
$json = array();
if (($handle = fopen($filename, "r")) !== FALSE) {
$rownum = 0;
$header = array();
while (($row = fgetcsv($handle, 1024, ",")) !== FALSE) {
if ($rownum === 0) {
for($i=0; $i < count($row); $i++){
// maybe you want to strip special characters or merge duplicate columns here?
$header[$i] = trim($row[$i]);
}
} else {
if (count($row) === count($header)) {
$rowJson = array();
foreach($header as $i=>$head) {
// maybe handle special row/cell parsing here, per column header
$rowJson[$head] = $row[$i];
}
array_push($json, $rowJson);
}
}
$rownum++;
}
fclose($handle);
}
return $json;
}
So I have a CSV file that looks like this:
12345, Here is some text
20394, Here is some more text
How can I insert this into an array that looks like so
$text = "12345" => "Here is some text",
"20394" => "Here is some more text";
This is what I currently had to get a single numerical based value on a one tier CSV
if ($handle = fopen("$qid", "r")) {
$csvData = file_get_contents($qid);
$csvDelim = "\r";
$qid = array();
$qid = str_getcsv($csvData, $csvDelim);
} else {
die("Could not open CSV file.");
}
Thanks for the replies, but I still see a potential issue. With these solutions, wouldn't the values store in this way:
$array[0] = 12345
$array[1] = Here is some text 20394
$array[2] = Here is some more text
If I tried this on the example csv above, how would the array be structured?
You can use fgetcsv() to read a line from a file into an array. So something like this:
$a = array();
$f = fopen(....);
while ($line = fgetcsv($f))
{
$key = array_shift($line);
$a[$key] = $line;
}
fclose($f);
var_dump($a);
Assuming that the first row in the CSV file contains the column headers, this will create an associative array using those headers for each row's data:
$filepath = "./test.csv";
$file = fopen($filepath, "r") or die("Error opening file");
$i = 0;
while(($line = fgetcsv($file)) !== FALSE) {
if($i == 0) {
$c = 0;
foreach($line as $col) {
$cols[$c] = $col;
$c++;
}
} else if($i > 0) {
$c = 0;
foreach($line as $col) {
$data[$i][$cols[$c]] = $col;
$c++;
}
}
$i++;
}
print_r($data);
If you are reading a file I can recommend using something like fgetcsv()
This will read each line in the CSV into an array containing all the columns as values.
http://at2.php.net/fgetcsv
$csv_lines = explode('\n',$csv_text);
foreach($csv_lines as $line) {
$csv_array[] = explode(',',$line,1);
}
edit - based on code posted after original question:
if ($handle = fopen("$qid", "r")) {
$csvData = file_get_contents($qid);
$csvDelim = "\r"; // assume this is the line delim?
$csv_lines = explode($csvDelim,$csvData);
foreach($csv_lines as $line) {
$qid[] = explode(',',$line,1);
}
} else {
die("Could not open CSV file.");
}
With your new file with two columns, $qid should become an array with two values for each line.
$csvDelim = ",";
$qid = str_getcsv($csvData, $csvDelim);
$text[$qid[0]] = $qid[1];