Array intersect inside a while loop - php

I am trying to with array_intersect match variable sku to the csv file,
When running it it causes a white page
while (($result = fgetcsv($ocuk,1024,"\t")) !== false)
{
$csvfull[] = $result;
}
$count=count($csvfull);
$sku = array();
foreach ($csvfull as $row)
{
$sku[] = $row[1];
}
$csv = fgetcsv($ocuk);
while ($x <= $count)
{
array_intersect($sku[$x], $csv)
echo
'',$csv[1], //sku
'test<br>';
$x++;
}
All I require is for array_intersect to check for sku in the csv file and then display the information requested from the csv file
example
sku = fb706, the array intersect finds it in the csv file then displays column 1 in the csv files

Is your $csv variable just a one dimensional array of skus? Seems unlikely but if thats the case then use in_array
while ($x <= $count)
{
if(in_array($sku[$x], $csv){
//the sku is present in the array
}
$x++;
}

Related

PHP recursive function not allowing page to load

I am trying to display the total number in each line of a file that does not contain a path to another file as well as the filename,
but if it has a path to another file loop through that file and sum all the number it has and the loop goes on and on as long as there exists a path to a file in the current file.
here is my code
function fileProcessor($value){
if(file_exists(trim($value))){
$total = 0;
$files = file($value, FILE_SKIP_EMPTY_LINES);
foreach($files as $data) {
if(!preg_match("/.txt/i", $data)){
$num = floatval($data);
$total += $num;
} else {
fileProcessor(trim($data));
}
}
echo $value. ' - ' .($total);
} else {
echo 'File does not exist';
}
fileProcessor('text_files/first.txt');
}
I have 3 .txt files I'm working with, inside those files I have something like this
first.txt
1
3
3
second.txt
second.txt
2
3
third.txt
third.txt
1
2
The output I am looking for
first.txt - 15
second.txt - 8
third.txt - 3
I will really appreciate it if someone can point me in the right direction, I don't know if I'm doing it right.
There are two problems with your code:
You're not including the directory for the source file in the path to subsidiary files, so those files are never found.
You're not returning the total from the function so that higher level invocations can add the total for subsidiary files
Correcting those issues, and renaming the variables to something meaningful gives this code:
function fileProcessor($filename){
if(file_exists(trim($filename))){
$total = 0;
$rows = file($filename, FILE_SKIP_EMPTY_LINES);
foreach($rows as $data) {
if(!preg_match("/.txt/i", $data)){
$num = floatval($data);
$total += $num;
}else {
$total += fileProcessor(dirname($filename)."/".trim($data));
}
}
echo $filename. ' - ' .($total)."<br>\n";
}else{
echo "File does not exist<br>\n";
}
return $total;
}
fileProcessor('text_files/first.txt');
Output:
text_files/third.txt - 3
text_files/second.txt - 8
text_files/first.txt - 15
This lists the files in the order in which the totals are finally accumulated, so the lowest levels appear first.
[Edit]
I spotted a problem with the order of results if two or more filenames appear in a file. Here's a reworked version that deals with that.
To list the files in the order in which they are encountered requires reversing the natural order. In the new version below I've placed the filenames in a $fileList array which is passed down by reference. Each new invocation of the function adds its results to the end of that array. Once processing is complete the array is displayed.
function fileProcessor( &$fileList){
// Get the last filename in the array
end($fileList);
$filename = key($fileList);
if(file_exists(trim($filename))){
// Accumulate the values
$fileList[$filename] = 0;
$rows = file($filename, FILE_SKIP_EMPTY_LINES);
foreach($rows as $data) {
if(!preg_match("/.txt/i", $data)){
$num = floatval($data);
$fileList[$filename] += $num;
}else {
// Recursive call. Add the next filename to the array
$fileList[dirname($filename)."/".trim($data)]=0;
$fileList[$filename] += fileProcessor($fileList);
}
}
} else {
$fileList[$filename]= "File does not exist: $filename";
}
// return the total for the file to add to the accumulator for the file above.
return $fileList[$filename];
}
// Place the initial file in the array
$results = ['text_files/first.txt' => 0];
// run the function
fileProcessor($results);
// display the results
foreach($results as $filename=>$total) {
echo $filename.' - '.$total."<br>\n";
}
Output:
text_files/first.txt - 15
text_files/second.txt - 8
text_files/third.txt - 3
You could use the static var:
<?php
function fileProcessor($value) {
static $results = [];
if (file_exists(trim($value))) {
$results[$value] = 0;
$files = file($value, FILE_SKIP_EMPTY_LINES);
foreach($files as $data) {
if (!preg_match("/.txt/i", $data)) {
$num = floatval($data);
$results[$value] += $num;
} else {
fileProcessor(trim($data));
}
}
} else {
echo 'File does not exist';
}
reset($results);
if (key($results) != $value) {
return;
}
foreach($results as $key => $value) {
echo $key. ' - ' .$value."\n";
}
}
fileProcessor('text_files/first.txt');
Output:
text_files/first.txt - 7
text_files/second.txt - 5
text_files/third.txt - 3

Duduplicate CSV File by Grouping with Element and Filtering by another [duplicate]

This question already has answers here:
PHP: Remove duplicate elements and get the latest data in the array
(4 answers)
Closed 5 months ago.
Please a have some days trying to resolve a code To duduplicate csv file
the idea is to browse the csv file, remove duplicates and let the line that has the maximum id
For Example this file CSV FILE TO duduplicate
And the result will be rewriting of result into csv
while (($this->lineInWork = fgetcsv($handle, 0, $delimiter)) !== false) {
if ($index == 0) {
if (!$this->checkHeaderFile()) {
fclose($handle);
return false;
}
} else {
$idProject = $this->columns[self::ID_PROJET]['index'];
$TitleProject = $this->columns[self::Title_Project]['index'];
$currentTitle = null;
if ($this->lineInWork[$TitleProject] != $currentTitle)
{
$currentTitle = $this->lineInWork[$TitleProject];
array_push($this->temporary_file[$currentTitle], $this->lineInWork);
}
}
$index++;
}
fclose($handle);
The problem is not to rewrite file but is to build an array with the right lines
I would probably do two different sorts for this (assuming I have understood what you are requiring). I have created a quick csv writer, which you may already have:
protected function saveToCsv($data, $path)
{
$fp = fopen($path, 'w');
foreach ($data as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
}
Script to filter and sort:
# Create a storage array
$new = [];
# Increment array to determine header row
$i = 0;
# Turn the csv file to array
$array = array_map('str_getcsv', file('original.csv'));
# Sort low to high by the ID_project
usort($array, function($a, $b){
return ($a[0] < $b[0]);
});
# Loop the array and just re-assign over the top of each instance of value
# which will eventually assign the last value (highest)
foreach($array as $row) {
if($i == 0) {
# Save header to put back into the copy csv
$header = $row;
$i++;
continue;
}
# Assign by id so the values are unique and sortable after
if(!isset($new[$row[2]]))
$new[$row[2]] = $row;
}
# Resort by the app_id
ksort($new);
# Save the new CSV somewhere with the header merged
$this->saveToCsv(array_merge([$header], $new), 'copy.csv');

PHP Array push does not work and return null

I am trying to extract some data from a file. The data is read but when I try to put it in an array, the array_push function is not working and return null. Here`s my code:
<?php
$in_file = 'php-files-task.csv';
$new_array = array();
$data = file_get_contents($in_file,true);
if($data[1] == 'simple' && (int)$data[3] < 10){
array_push($new_array, $data);
}
print_r($new_array); //return an empty array
?>
If anyone knows how to fill this array and return a proper result?
file_get_contents() returns a string, not an array.
You should be calling fgetcsv() in a loop.
$fd = fopen($in_file, "r");
while ($data = fgetcsv($fd)) {
if($data[1] == 'simple' && (int)$data[3] < 10){
array_push($new_array, $data);
}
}
fclose($fd);
This will create a 2-dimensional array containing all the rows of the file that meet the if condition.
You can write the new array to another file with a similar loop using fputcvs().
$fd = open($out_file, "w");
foreach ($new_array as $row) {
fputcsv($fd, $row);
}
fclose($fd);
You can do the entire thing with a single loop, without using an array.
$in_fd = fopen($in_file, "r");
$out_fd = fopen($out_file, "w");
while ($data = fgetcsv($in_fd)) {
if($data[1] == 'simple' && (int)$data[3] < 10){
fputcsv($out_fd, $data);
}
}
fclose($in_fd);
fclose($out_fd);

PHP script for adding prefix to sku when duplicate in .csv

At the moment I have a script that will remove the row in my csv when it has already seen the sku before.
Here is the script:
<?php
// array to hold all unique lines
$lines = array();
// array to hold all unique SKU codes
$skus = array();
// index of the `sku` column
$skuIndex = -1;
// open the "save-file"
if (($saveHandle = fopen("unique.csv", "w")) !== false) {
// open the csv file
if (($readHandle = fopen("original.csv", "r")) !== false) {
// read each line into an array
while (($data = fgetcsv($readHandle, 8192, ",")) !== false) {
if ($skuIndex == -1) {
// we need to determine what column the "sku" is; this will identify
// the "unique" rows
foreach ($data as $index => $column) {
if ($column == 'sku') {
$skuIndex = $index;
break;
}
}
if ($skuIndex == -1) {
echo "Couldn't determine the SKU-column.";
die();
}
// write this line to the file
fputcsv($saveHandle, $data);
}
// if the sku has been seen, skip it
if (isset($skus[$data[$skuIndex]])) continue;
$skus[$data[$skuIndex]] = true;
// write this line to the file
fputcsv($saveHandle, $data);
}
fclose($readHandle);
}
fclose($saveHandle);
}
?>
This works fine but I am starting to need the content that is deleted.
What i need now, is to modify the code to add the same prefix to all duplicate sku's as there will only be 2 of the same sku.
I do not know where to start.
Adding a prefix to duplicates
This will add a prefix to any duplicate SKU and will then store it into the unique CSV output, e.g. XYZ123 becomes duplicate-XYZ123.
Change:
if (isset($skus[$data[$skuIndex]])) continue;
to:
if (isset($skus[$data[$skuIndex]])) $data[$skuIndex] = 'duplicate-' . $data[$skuIndex];
Fixing the duplicate header row
Add continue; after fputcsv($saveHandle, $data); Inside if ($skuIndex == -1) {. Because fputcsv(...) appears twice in the loop, it will be run twice on the first iteration of the loop.

how to read text file and translate fild

Hello, how to read txt file using php and replacement with array?
i want read file like this:
||Search||,||s||---||Images||,||i||
this my php code:
$f = fopen("test.txt", "r");
$image= "Imgaes";
// Read line by line until end of file
while (!feof($f)) {
// Make an array using comma as delimiter
// $arrM = explode("---",fgets($f));
$arr = explode("||---||",fgets($f));
// Write links (get the data in the array)
$num = 1;
while($num <= 30) {
list($eng,$fa) = explode("||,||", $arr[$num]);
foreach($html->find('html') as $full) {
$all = $full->innertext;
}
$fe = str_replace($eng,$fa,$all);
$num = $num+1;
}
echo $fe;
}
fclose($f);
but this not work:(!!!
before the explode, parse your data in this function:
// Function arrayData
function arrayData($data){
# code...
// Create an array out of each line
$data_array=explode("\n", $data);
// Find the last key in the array
$last_key=count($data_array)-1;
// If the last line is empty revise the last key downwards until there's actually something there
while(empty($data_array[$last_key]))
{
$last_key-=1;
}
// Figure out the first key based upon the value set for the number of lines to display
$first_key=$last_key-($this->num_lines-1);
// Start a new array to store the last X lines in
$final_array=array();
// Work through the array and only add the last X lines to it.
foreach($data_array as $key => $value)
{
if($key >= $first_key && $key <= $last_key)
{
$final_array[]=$value;
}
}
return $final_array;
} // end function

Categories