PHP & CSV - Echo Result only once - php

i am fairly new to PHP and tried several hours to get something going, sadly without a result. I hope you can point me into the right direction.
So what i got is a CSV file containing Articles. They are separated into diff columns and always the same structure, for example :
ArtNo, ArtName, ColorCode, Color, Size
When an article has different color codes in the CSV, the article is simply repeated with the same information except for the color code, see an example:
ABC237;Fingal Edition;48U;Nautical Blue;S - 5XL;
ABC237;Fingal Edition;540;Navy;S - 5XL;
My problem is, i want to display all the articles in a table, include an article image etc.. so far i got that working which is not a problem, but instead of showing the article twice for every different color code i want to create only one line per ArtNo (First CSV Line) but still read the second duplicate line to add the article color to the first one, like :
ABC237; Fingal Edition ;540;Nautical Blue, Navy;S - 5XL;
Is this even possible or am I going into a complete wrong direction here? My code looks like this
<?php
$csv = readCSV('filename.csv');
foreach ($csv as $c) {
$artNo = $c[0]; $artName = $c[1]; $colorCode = $c[2]; $color = $c[3]; $sizes = $c[4]; $catalogue = $c[5]; $GEP = $c[6]; $UVP = $c[7]; $flyerPrice = $c[8]; $artDesc = $c[9]; $size1 = $c[10]; $size2 = $c[11]; $size3 = $c[12]; $size4 = $c[13]; $size5 = $c[14]; $size6 = $c[15]; $size7 = $c[16]; $size8 = $c[17]; $picture = $c[0] . "-" . $c[2] . "-d.jpg";
// Echo HTML Stuff
}
?>
Read CSV Function
<?php
function readCSV($csvFile){
$file_handle = fopen($csvFile, 'r');
while (!feof($file_handle) )
{
$line_of_text[] = fgetcsv($file_handle, 0, ";");
}
fclose($file_handle);
return $line_of_text;
}
?>
I tried to get along with array_unique etc but couldn't find a proper solution.

Read all the data into an array, using the article number as the key....
while (!feof($file_handle) ) {
$values = fgetcsv($file_handle, 0, ";");
$artno = array_shift($values);
if (!isset($data[$artno])) $data[$artno]=array();
$data[$artno][]=$values;
}
And then output it:
foreach ($data as $artno=>$v) {
$first=each($v);
print $artno . "; " . each($first);
foreach ($v as $i) {
$discard=array_shift($i);
print implode(";", $i);
}
print "\n";
}
(code not tested, YMMV)

You need to know exactly how many items belong to each ArtNo group. This means a loop to group, and another loop to display.
When grouping, I steal the ArtNo from the row of data and use it as the grouping key. The remaining data in the row will be an indexed subarray of that group/ArtNo.
I am going to show you some printf() and sprintf() syntax to keep things clean. printf() will display the first parameter's content and using any subsequent values to replace the placeholders in the string. In this case, the 2nd parameter is a conditional expression. On the first iteration of the group, ($i = 0), we want to show the ArtNo as the first cell of the row and declare the number of rows that it should span. sprinf() is just like printf() except it produces a value (silently). Upon any subsequent iterations of the group, $i will be greater than zero and therefore an empty string is passed as the value.
Next, I'm going to use implode() which is beautifully flexible when you don't know exactly how many columns your table will have (or if the number of columns may change during the lifetime of your project).
Tested Code:
$csv = <<<CSV
ABC237;Fingal Edition;48U;Nautical Blue;S - 5XL
ABC236;Fingal Edition;540;Navy;S - 5XL
ABC237;Fingal Edition;49U;Sea Foam;L - XL
ABC237;Fingal Edition;540;Navy;S - 5XL
CSV;
$lines = explode(PHP_EOL, $csv);
foreach ($lines as $line) {
$row = str_getcsv($line, ';');
$grouped[array_shift($row)][] = $row;
}
echo '<table>';
foreach ($grouped as $artNo => $group) {
foreach ($group as $i => $values) {
printf(
'<tr>%s<td>%s</td></tr>',
(!$i ? sprintf('<td rowspan="%s">%s</td>', count($group), $artNo) : ''),
implode('</td><td>', $values)
);
}
}
echo '</table>';
Output:

Related

Processing data in PHP, iteratively assign variables to every 8 items, to catagorize them to be added to an SQL database

A PHP array, with items like
Date, number, number, number, number, number, Date, number, number, number, etc...
but all in numbered array as individual items
What I need is to take this array and be able to process a large data set and actually assign the variables so that I can put them into a database like
Date Number1 Number2 Number3 Number4
01/01/2001. 01. 02. 03. 04
So far, I'm able to open the file, and pull the number into an array but that's about it.
<?php
$lines=array();
$fp=fopen('numbers.txt', 'r');
while (!feof($fp))
{
$line=fgets($fp);
//process line ?
$line=trim($line);
//add to array
$lines[]=$line;
}
fclose($fp);
print_r($lines);
?>
What do you suggest I do to at least display the items from the array in the desired format. Ideally I'd like to get them into a database so I can run analytics. Any assistance is greatly appreciated.
I think you are looking for the function array_chunk()
<?php
// create example data
$lines = [];
for($i=1; $i < 32; $i++)
$lines[] = "Entry $i";
// this is the function you are looking for - see https://www.php.net/manual/en/function.array-chunk.php
$dataSets = array_chunk($lines, 8);
// Lets print our results
// First loop throu all datasets…
foreach($dataSets as $index => $dataSet){
// "\n" is a new line
echo ("Data set $index has this entries: \n");
// … and then throu all entries
foreach($dataSet as $index => $entry){
// "\t" is the tab symbol
echo "\t [$index] = '$entry' \n";
}
echo "\n";
}
Working example to play arround

need to access 3 values in a php array that contains 20, is a 3d array and I need to access the same values 60 times

<?php
// Open the file
$filename = 'pvemail.txt';
$fp = fopen($filename, 'r');
// Add each line to an array
if ($fp) {
$array = explode("\n", fread($fp, filesize($filename)));
}
//print_r ($array);
for ($c = 0; $c < count($array); $c++){
$cell = explode(",", $array[$c]);
print_r ($cell);
echo '<br/>';
}
?>
I am currently working on this code. I have taken a text file generated from a Google report, and managed to explode it into an array, and then I've taken each element of the array and exploded that into another array. However, the problem I'm now having is I only want to retrieve 3 elements of the second exploded array and there are 20 elements to each array.
What would be the best way to go about this, should I use a for or foreach loop? I only need to print $cell[2], $cell[11] and $cell[12]. I have tried using:
echo ($cell[2] + " " + $cell[12] + " " + $cell[11]
($cell[11] and $cell[12] are in this order because 11 is a last name and 12 is a first name and I want the first name first so I've had to put them backwards) but when I run that piece of code it just outputs line breaks and 0's. I'm really just wondering what would be the most effective method of looping through the arrays, and should I do it within the loop that I have already established?
I was thinking that if I were to put it inside my existing for loop I could use an if/else loop, something like:
if($cell = $cell[2]){
echo ($cell[2])
};
but i'm not convinced this will work. Should I define a variable to store $cell[2], [11] and [12] in, and create my if loop based on that, and then I would only need to echo the variable? Is that likely to be effective? Any help would be appreciated, I've looked around on the forum for posts similar to this but I haven't been able to find anything.
20130912,b875c9b154cf7b8d,el#pv-eu.com,ACTIVE,30720,1054180015,,,20100902,‌​20130910,20130904,L,E,,,,20130911,2010-09-02 09:11:37,2013-09-10 23:51:21,2013-09-04 03:06:09,2013-09-11 00:41:24
20130912,66c63753b8188f17,lf#pv-eu.com,ACTIVE,30720,3699701524,,,20110315,201309‌​11,20130911,F,L,,,,19691231,2011-03-15 02:00:31,2013-09-11 00:50:17,2013-09-11 00:52:16,1969-12-31 16:00:00
20130912,bd5ef40689adf9ac,ah#pv-eu.com,ACTIVE,30720,3476851137,,,20110426,201309‌​11,20130910,H,A,,,,20110720,2011-04-26 01:47:56,2013-09-11 16:58:48,2013-09-10 06:20:26,2011-07-20
This is how the text file itself looks, although there is a lot more data. All I'm trying to pull is the email address and name.
Assuming pvemail.txt is a CSV file, does this solve your problem?
$content = file_get_contents('pvemail.txt');
$lines = explode("\n", $content);
header('Content-type: text/plain');
foreach($lines as $line) {
$values = explode(',', $line);
echo $values[2], ' ', $values[12], ' ', $values[11], "\n";
}
Using the 3 sample lines, the above code outputs this:
el#pv-eu.com E L
lf#pv-eu.com L F
ah#pv-eu.com A H

Reading tab and newline delimited (multi-dimensional) flat-file database

Apologies if this may be a simple question, I haven't worked with flat file databases before and finding this pretty non-intuitive.
I have a flat file, tab \t and \n new line delimited database as such:
Sebastian Ingrosso Kidsos (Wippenberg Mix) 2F32829628 Electro
Avicii Silhouettes 2F47987574 House
(two rows just for sample). I want to be able to iterate through each line, encapsulate each element delimited by a \t tab character inside a span tag and then move on to the next line, preferable encapsulating each new line in a <li> element.
I have this to start with, which doesn't add spans or li's:
function display_tracklist($max) {
$db = fopen('db/db.txt', 'r');
$row = 0;
while (($tracks = fgetcsv($db, "\n")) !== FALSE) {
if ($max > count($tracks)) {
$max = count($tracks);
}
$row++;
for ($index=0; $index < $max; $index++) {
echo "<li>" . $tracks[$index] . "</li>";
}
}
fclose($db);
}
What is the best way to handle this task? Normally I would have done this with a SQL database making things a lot more intuitive but that's not an option here. I've thought of nested foreach loops, etc. no luck so far.
End result should be:
<li><span>Sebastian Ingrosso</span> <span>Kidsos (Wippenberg Mix)</span> <span>2F32829628</span> <span>Electro</span></li>
<li><span>Avicii</span> <span>Silhouettes</span> <span>2F32829628</span> <span>House</span></li>
etc.
Assuming your data is alike my $data, that looks like giving what you want;
$data = "Sebastian\tIngrosso\tKidsos (Wippenberg Mix)\t2F32829628\tElectro\nAvicii\tSilhouettes\t2F47987574\tHouse";
foreach ((array) explode("\n", $data) as $lines) {
print "<li>";
foreach ((array) explode("\t", $lines) as $line) {
print "<span>{$line}</span>";
}
print "</li>\n";
}
Output;
<li><span>Sebastian</span><span>Ingrosso</span><span>Kidsos (Wippenberg Mix)</span><span>2F32829628</span><span>Electro</span></li>
<li><span>Avicii</span><span>Silhouettes</span><span>2F47987574</span><span>House</span></li>

need advice with logic for coding out this php exercise

I've got a list in a text file with the top 1000 words used in the english language. Each line has a list of up to 50 words, like this:
the,stuff,is,thing,hi,bye,hello,a,stuffs
cool,free,awesome,the,pray,is,crime
etc.
I need to write code using that file as input, to make an output file with the a list of pairs of words which appear together in at least fifty different lists. For example, in the above example, THE & IS appear together twice, but every other pair appears only once.
I can't store all possible pairs of words, so no brute force.
I'm trying to learn the language and I'm stuck on this exercise of the book. Please help. Any logic, guidance or code for this would help me.
This is what I have so far. It doesn't do what's intended but I'm stuck:
Code:
//open the file
$handle = fopen("list.txt", 'r');
$count = 0;
$is = 0;
while(!feof($handle)) {
$line = fgets($handle);
$words = explode(',', $line);
echo $count . "<br /><br />";
print_r($words);
foreach ($words as $word) {
if ($word == "is") {
$is++;
}
}
echo "<br /><br />";
$count++;
}
echo "Is count: $is";
//close the file
fclose($handle);
$fp = fopen('output.txt', 'w');
fwrite($fp, "is count: " . $is);
fclose($fp);
This is what I came up with but I think it's too bloated:
plan:
check the first value of the $words array
store the value into $cur_word
store $cur_word as a key in an array ($compare) and
store the counter (line number) as the value of that key
it'll be 1 at this point
see if $cur_word is on each line and if it is then
put the value into $compare with the key as $cur_word
if array has at least 50 values then continue
else go to the next value of the $words array
if it has 50 values then
go to the next value and do the same thing
compare both lists to see how many values match
if it's at least 50 then append
the words to the output file
repeat this process with every word
There are probably 100's of solutions to this problem. Here is one
$contents = file_get_contents("list.txt");
//assuming all words are separated by a , and converting new lines to word separators as well
$all_words = explode(",", str_replace("\n", ",", $contents));
$unique_words = array();
foreach ($all_words as $word) {
$unique_words[$word] = $word;
}
this will give you all the unique words in the file in an array.
You can also use the same technique to count the words
$word_counts = array();
foreach ($all_words as $word) {
if (array_key_exists($word, $word_counts)) {
$word_counts[$word]++;
} else {
$word_counts[$word] = 1;
}
}
then you can loop through and save the results
$fp = fopen("output.txt", "w");
foreach ($word_counts as $word => $count) {
fwrite($fp, $word . " occured " . $count . " times" . PHP_EOL);
}
fclose($fp);

Subtraction between data in file1 and file2 using PHP

Suppose that I have 2 files:
File1.txt
10;30;15;40;12;14;15
23;32;10;50;12;54;60
File2.txt
2;4;5;6;7;8;9
3;6;7;8;9;0;7
I want to subtration between these 2 files. Ex 10 - 2........
PHP code:
$file1 = 'File1.txt';
$file2 = 'File2.txt';
if(file_exists($file1)){
$files = fopen($file1,'r');
while(!feof($files)){
$data = explode(";",fgets($files));
if($title ==""){
$title = $data[0];
}
if(!empty($data[3])){
$cate = $data[3];
$filepmta = fopen($file2,'r');
while(!feof($filepmta)){
$hourData = explode(";",fgets($filepmta));
if(!empty($hourData[3])){
if($title ==""){
$title = $hourData[0];
}
if(!empty($btnHour)){
echo $percentRed = ((int)$data[2] - (int)$hourData[2]);
//it loads page so long time so I don know what's error.
}
}
}
It loads the page is so long time.I don know how to fix this,Anyone know help me please,thanks.
I would recommend just simply opening both files and storing the contents of the file into memory. IE Create 2 simple loops (not nested) which iterates through both files respectively and saves the content to an array.
Then make one more loop after the first two. Iterate through the third loop based on the array size of the first two. (I'm assuming you can assume they are both the same size, but it will be a good idea to add checks to make sure loop 1 and loop 2 produce the same size/length arrays.
Within the 3rd loop iterate through both previously two generated arrays with the same index.
Pseudo Code // even tho I said I'd do pseudo code, I ended up doing it all. :-/
$file_values1 = $file_values2 = $answers = array();
while(!feof($file1)) $file_values1[] = explode(';', fgets($file)); // loop 1
while(!feof($file2)) $file_values2[] = explode(';', fgets($file)); // loop 2
foreach($file_values1 as $key1 => $sub_array) { // loop 3
foreach($sub_array as $key2 => $value) // loop 4; hehe, oh wellz
{
$answers[] = $file_values1[$key1][$key2] = $file_values2[$key1][$key2]
}
}
Basically, the nested loop 4, meh. There ARE faster answers. The 3rd loop can be improved upon, it's O(N^2). I'll leave that for you to optimize. No free lunches. :-)
fgets() doesn't move the file pointer after the last line, so you're staying on the last line, feof() still returns false and you're trapped in an infinite loop.
The common way of doing what you want is:
while (($line = fgets($handle)) !== false) {
echo $line;
}
Have a look at the code example in fgets() documentation, it's quite exhaustive.
You're making this way more complicated than it has to be.
Open your files and read them both in with file(), which will give you an array of lines in each file.
Iterate over both line arrays simultaneously with a MultipleIterator.
Convert each lines' contents to arrays with str_getcsv() and an array_map() trick.
Iterate over each line values with another MultipleIterator.
Compute the subtraction and print it.
That's all it takes! I've implemented the above algorithm below.
$file1 = 'File1.txt';
$file2 = 'File2.txt';
$file1 = file( $file1);
$file2 = file( $file2);
$iter = new MultipleIterator;
$iter->attachIterator( new ArrayIterator( $file1));
$iter->attachIterator( new ArrayIterator( $file2));
foreach( $iter as $element) {
list( $line1, $line2) = array_map( 'str_getcsv', $element, array( ';', ';'));
$val_iter = new MultipleIterator;
$val_iter->attachIterator( new ArrayIterator( $line1));
$val_iter->attachIterator( new ArrayIterator( $line2));
foreach( $val_iter as $value) {
list( $el1, $el2) = $value;
echo ($el1 - $el2); echo ";";
}
echo "\n";
}
You can see from this demo, which statically defines the files as arrays, that this produces:
8;26;10;34;5;6;6;
20;26;3;42;3;54;53;

Categories