Display array with array_search - php

I have an array of csv elements and I want to retrieve the key of the column 'Due Date' (the result is 10) and display the array at the column 10. However, it doesn't display the result but it will show the column 1 and I don't know why.
Code:
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
$value = array_search('Due Date', $line);
print_r($line[$value]);
}

Just do it like this so you can easily get the column number 10:
$var = array();
while($row = fgetcsv($yourFile)) {
$var[] = $row;
}
//Get Column 10
$var[] = $row[9];
Edit:
<?php
$valueOfSearch = "YOUR VALUE OF SEARCH";
$linesOfCsv = file('YOUR PATH.csv');
$lineNumberOfCSV = false;
while (list($key, $line) = each($linesOfCsv) and !$lineNumberOfCSV) {
$lineNumberOfCSV = (strpos($line, $valueOfSearch) !== FALSE);
}
if($lineNumberOfCSV){
//Add YOUR CONDITION
}
?>

Open the fine and take csv values inside an array and close the file. After that try your logic.
So to get value you can use:
$file = 'file.csv';
$line = array();
$file = fopen($file,"r");
while(! feof($file))
{
$line = fgetcsv($file);
}
fclose($file);
$key = array_search('Due Date', $line);
print_r($line[$key]);

Related

PHP CSV duplicate values

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.

Add 2 new column header and contents in csv file using php

I've an existing csv file with following values
column1 column2
Fr-fc Fr-sc
Sr-fc Sr-sc
I want to add 2 new columns in it and achieve the following format
column1 column2 column3 column4
Fr-fc Fr-sc 1 2
Sr-fc Sr-sc 1 2
If I use following code it inserts same column header value in column data for the newly created columns
$a = file('amit.csv');// get array of lines
$new = '';
foreach($a as $line){
$line = trim($line);// remove end of line
$line .=";column3";// append new column
$line .=";column4";// append new column
$new .= $line.PHP_EOL;//append end of line
}
file_put_contents('amit2.csv', $new);// overwrite the same file with new data
How I can achieve the above?
Instead of reinventing the wheel, you can use php's inbuilt csv functions fgetcsv and fputcsv respectively to ease your work. First read in each row with fgetcsv and store the data in a multidimensional array:
$delimiter = "\t"; //your column separator
$csv_data = array();
$row = 1;
if (($handle = fopen('test.csv', 'r')) !== FALSE) {
while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
$csv_data[] = $data;
$row++;
}
fclose($handle);
}
Next edit the rows to add the extra columns using array_merge:
$extra_columns = array('column3' => 1, 'column4' => 2);
foreach ($csv_data as $i => $data) {
if ($i == 0) {
$csv_data[$i] = array_merge($data, array_keys($extra_columns));
} else {
$csv_data[$i] = $data = array_merge($data, $extra_columns);
}
}
Finally use fputcsv to enter each row into the csv.
if (($handle = fopen('test.csv', 'w')) !== FALSE) {
foreach ($csv_data as $data) {
fputcsv($handle, $data, $delimiter);
}
fclose($handle);
}
You can combine these steps to make your code more efficient by reducing the number of loops.
This approach is less code
<?php
$inFile = fopen('test.csv','r');
$outFile = fopen('output.csv','w');
$line = fgetcsv($inFile);
while ($line !== false) {
$line[] = 'third column';
$line[] = 'fourth column';
fputcsv($outFile, $line);
$line = fgetcsv($inFile);
}
fclose($inFile);
fclose($outFile);

Group all lines with the same word in first column in csv

I have two columns in my csv file: first_column and second_column. I would like to group all the rows in second column into one string separated by "," if they all have the same word in the first column then output them into a text file.
first_column second_column
a Chris
a Jake
a Paula
b Anita
b Lionel
b Sheila
Desired output
a: Chris, Jake, Paula
b: Anita, Lionel, Sheila
This is what I tried. I seem to be only getting the first letter from the second_column. Any pointers would be great.
$csv_file = fopen("test.csv", "r");
$text_file = fopen("test.txt","w");
$data = array();
if ($csv_file)
{
while (($line = fgets($csv_file)) !== false)
{
$column_1 = $line[0];
$column_2 = $line[1];
if (!empty($column_1))
{
$data [$column_1] = column_2;
}
}
fclose($csv_file);
fclose($text_file);
}
else
{
// error opening the file.
}
//print_r($data);
This should work for you:
Here I first get your .csv file into an array with file(). Then I loop through each line and create an array, where the first column is the key and the second column a value of the sub array.
After this you can loop through your created array and implode() each sub array with the key to the expected line which you want. Then you can just save the data with file_put_contents() into your .txt file.
<?php
$csv_file = "test.csv";
$text_file = "test.txt";
$lines = file($csv_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
array_shift($lines);
foreach($lines as $line) {
list($key, $value) = explode(",", $line); //Change your .csv delimiter here, if you use something else than ,
$data[$key][] = $value;
}
foreach($data as $key => $arr)
$content[] = $key . ": " . implode(",", $arr) . PHP_EOL;
file_put_contents($text_file, $content);
?>
Storing result in an data array and then wring it bacj to text file should work.
$csv_file = fopen("test.csv", "r");
$text_file = fopen("test.txt","w");
$data = array();
if ($csv_file)
{
while (($line = fgets($csv_file)) !== false)
{
$column_1 = $line[0];
$column_2 = $line[1];
if (!isset($data[$column_1]))
{
$data[$column_1] = column_2
} else {
$data[$column_1] = $data[$column_1] .',' . $column_2
}
}
foreach($data as $k=>$d ){
fputs($text_file, "$k: $d") ;
}
fclose($csv_file);
fclose($text_file);
}
else
{
// error opening the file.
}

Append data to middle line/row of a csv instead of the last line or row

I have a csv file with some records and each record has unique ID. I'm running a loop to find that unique ID and then append some more data to that record.
Is it possible to do this without a temporary file? Creating such file and moving all data in it takes more time...
My code is:
<?php
$temp = fopen('tempwin.csv','w+');
if (($handle = fopen("win.csv", "r+")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
if($data[4] == trim($leadid)){
$data[5] = trim($_POST['year']);
$data[6] = trim($_POST['make']);
$data[7] = trim($_POST['model']);
$data[8] = trim($_POST['trade']);
}
}
fputcsv($temp, $data);
}
fclose($handle);
fclose($temp);
}
unlink('win.csv');
rename('tempwin.csv','win.csv');
You can use following, but you need to pass the row number i.e where you need to add row.
<?php
//A helping function to insert data at any position in array.
function array_insert($array, $pos, $val)
{
$array2 = array_splice($array, $pos);
$array[] = $val;
$array = array_merge($array, $array2);
return $array;
}
//What and where you want to insert
$DataToInsert = '11,Shamit,Male';
$PositionToInsert = 3;
//Full path & Name of the CSV File
$FileName = 'data.csv';
//Read the file and get is as a array of lines.
$arrLines = file($FileName);
//Insert data into this array.
$Result = array_insert($arrLines, $PositionToInsert, $DataToInsert);
//Convert result array to string.
$ResultStr = implode("\n", $Result);
//Write to the file.
file_put_contents($FileName, $ResultStr);
?>
Fetch the data out of the original file as an array or string, make your modifications and then simply overwrite the contents of the file with your modified data.

How can I parse a CSV into array with first value as key?

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];

Categories