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.
Related
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);
I am trying to update last line of a csv file, I get the last line with using this code:
$f = public_path('MYCSV.csv');
$rows = file($f);
$last_row = array_pop($rows);
$data = str_getcsv($last_row);
I searched a lot but did not find any way to replace or at least to remove the last line of csv file, it will be great if do not use foreach loop as the file size is big...
Code: (I don't have Laravel to test on, but I tested with raw php)
$f = public_path('MYCSV.csv');
$rows = file($f);
array_pop($rows); // remove final element/row from $array
file_put_contents($f, implode($rows)); // convert back to string and overwrite file
Now if you want to add a new row to the end of your file, you will just need to push the new data as a comma-separated string (with a trailing newline character) into the $rows array.
If you have a .csv file with this content:
Sally Whittaker,2018,McCarren House,312,3.75
Belinda Jameson,2017,Cushing House,148,3.52
Jeff Smith,2018,Prescott House,17-D,3.20
Sandy Allen,2019,Oliver House,108,3.48
Then $rows array, after the array_pop() call, will be:
array (
0 => 'Sally Whittaker,2018,McCarren House,312,3.75
',
1 => 'Belinda Jameson,2017,Cushing House,148,3.52
',
2 => 'Jeff Smith,2018,Prescott House,17-D,3.20
')
*Notice that the newline characters are not lost when file() is used -- so no "glue" is necessary with implode().
After file_put_contents() is called, the file will be overwritten with:
Sally Whittaker,2018,McCarren House,312,3.75
Belinda Jameson,2017,Cushing House,148,3.52
Jeff Smith,2018,Prescott House,17-D,3.20
<?php try {
$csv_path = 'MYCSV.csv';
$fp = fopen($csv_path, 'r+');
if ($fp) {
$data = array();
while ($row = fgetcsv($fp)) {
$data[] = $row;
}
fclose($fp);
array_pop($data);
$fp = fopen($csv_path, 'w+');
foreach($data as $key => $value) {
fputcsv($fp, $value);
}
} else {
throw new Exception("Failed to open file");
}
} catch (Exception $e) {
echo $e -> getMessage();
}?>
I have csv file with 1500+ entries in a column.I can able to read csv file's all values of column with this.
$rowcount = 1;
$srcFileName = "input/test.csv";
$file = fopen($srcFileName,"r");
$inputfielscount = count(file($srcFileName, FILE_SKIP_EMPTY_LINES));
while($rowcount < $inputfielscount)
{
$row = fgetcsv($file);
$result=array("id" =>$row[0],"des"=>"I am jhon",salery="10000");
$Final=array("listingsEmp"=>$result);
}
After reading first (1-10) value i will create an array (like array [0] =>$result) and Then wantto repeat same task from (11-20) and create another array (like array [1] =>$Final this time $final array contain information about the next ids whic we read from csv file (11-10)) and so on.
For the above requirment i changed code to this :
$rowcount = 1;
$srcFileName = "input/test.csv";
$file = fopen($srcFileName,"r");
while($rowcount < 20)
{
if(($rowcount % 10 == 0) && ( $rowcount != 0)) {
$rowcount++;
break;
}else{
$row = fgetcsv($file);
// some curl code for fetching data according to csv file field(Id)
$result=array("id" =>$row[0],"des"=>"I am jhon",salery="10000"); //contain 10 array
}
}
$Final=array("listingsEmp"=>$result);
Now i will post this $final array which has (0-10 index array ,each has unique id and corresponding values) using curl and get response which i am save in csv file.
$currenttime=date("Y-m-d-H_i_s");
$opfile='output'.$currenttime.'.csv'; //path wher op csv file exist
if(!#copy($srcFileName,'/output/'.$opfile))
{
$errors= error_get_last();
echo "COPY ERROR: ".$errors['type'];
echo "<br />\n".$errors['message'];
}else { // echo "File copied from remote!";
$fp = fopen('output/output'.$currenttime.'.csv',"a");
$fr = fopen($srcFileName,"r");
$rowcounts=0;
$FinalRES=$Final->response;
while($rowcounts< $inputfielscount) {
$resultBulk=$FinalRES[$rowcounts];
$resultBulkStatus=$FinalRES->status;
$resultBulkErrors=$FinalRES->errors;
$errorMsgArray=$resultBulkErrors[0];
$BulkErrorsMessage=$errorMsgArray->message;
$rows = fgetcsv($fr);
if($resultBulkStatus=='failure'){
$list = array ($rows[0],$rows[1],$resultBulkStatus,$BulkErrorsMessage);
}else {
$list = array ($rows[0],$rows[1],$resultBulkStatus,"successfully");
}
fputcsv($fp,$list);
//$p++;
$rowcounts++;
}
}
This full code runs once and give response for 10 ids ,i want repeat this code again for next 10 id (11-20)and then for (21-30) so on .
Once all response write in output csv file After that it display download output file link,Output file contain full response for all Ids which is in csv file(1500 +)
<?php $dnldfilw='output'.$currenttime.'.csv';?>
<a href='download.php?filename=<?php echo $dnldfilw; ?>'>Download Output file</a>
?>
The easiest method is to just use the file() function you are already using...
So to shorten the code to some pseudocode:
<?php
$indexedArray = array();
$indexedSplit = 10;
$lines = file($srcFileName);
$tempArray = array();
foreach($lines as $line) {
if(count($tempArray) % $indexedSplit === 0) {
$indexedArray[] = $tempArray;
$tempArray = array();
}
$tempArray[] = $line;
}
foreach($indexedArray as $index => $valueArray) {
// do the curl magic
// write results of curl into csv
}
Your question is poorly phrased, but I think this would be your aim, right?
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());
?>
My goal here is to open temp.php, explode by ### (line terminator), then by %% (field terminator). Change a specific field, on a specific line, then implode everything back together and save it.
There are a couple variables at play here:
row = the target row number
target = the target field/column number
nfv = the info that i want to place into the target field
Im using the counter $i to count until i get to the desired row. Then counter $j to count til i get to my desired field/target. So far this gives me an error for invalid implode arguments, or doesn't save any data at all. Im sure there are a couple things wrong, but i am frustrated and lost.
<?
$row = $_GET['row'];
$nfv = $_GET['nfv'];
$target = $_GET['target'];
$data = file_get_contents("temp.php");
$csvpre = explode("###", $data);
$i = 0;
$j = 0;
foreach ( $csvpre AS $key => $value){
$i++;
if($i == $row){
$info = explode("%%", $value);
foreach ( $info as $key => $value ){
$j++;
if($j == "$target"){
$value = $nfv;
}
}
$csvpre[$key] = implode("%%", $info);
}
}
$save = implode("###", $csvpre);
$fh = fopen("temp.php", 'w') or die("can't open file");
fwrite($fh, $save);
fclose($fh);
header("Location: data.php");
?>
If someone can tell what is wrong with this, please be detailed so i can learn why its not working.
Here is some sample csv data for testing
1%%4%%Team%%40%%75###2%%4%%Individual%%15%%35###3%%4%%Stunt Group%%50%%150###4%%4%%Coed Partner Stunt%%50%%150###5%%4%%Mascot%%15%%35###6%%8%%Team%%40%%75###7%%8%%Stunt Group%%50%%150###8%%8%%Coed Partner Stunt%%50%%150###9%%3%%Team%%40%%75###10%%1%%Team%%40%%75###11%%1%%Solo%%15%%35###12%%1%%Duet%%50%%150###13%%2%%Team%%50%%50###14%%2%%Solo%%15%%35###15%%2%%Duet%%50%%150###16%%8%%Individual%%15%%35###
The following should work. This also eliminates a lot of unnecessary looping
<?php
$row = $_GET['row'];
$nfv = $_GET['nfv'];
$target = $_GET['target'];
$data = file_get_contents("temp.php");
$csvpre = explode("###", $data);
//removed i and j. unnecessary.
//checks if the row exists. simple precaution
if (isset($csvpre[$row]))
{
//temporary variable, $target_row. just for readability.
$target_row = $csvpre[$row];
$info = explode("%%", $target_row);
//check if the target field exists. just another precaution.
if (isset($info[$target]))
{
$info[$target] = $nfv;
}
//same as yours. just pack it back together.
$csvpre[$row] = implode("%%", $info);
}
$save = implode("###", $csvpre);
$fh = fopen("temp.php", 'w') or die("can't open file");
fwrite($fh, $save);
fclose($fh);
header("Location: data.php");
?>
The looping you were doing was removed as the row were numerically indexed already anyways. Accessing the array element directly is much faster than looping through the elements until you find what you want.