Mal eine Fachfrage aus PHP (Schleife in Schleife)

Hallo,

bin gerade dabei für mein Backend etwas zu entwickeln und hab da ein kleines Verständnisproblem, ich hoffe jemand kann mir ein Tipp geben wie ich das Problem löse.

Folgendes habe 2 Schleifen, die erste Schleife sucht nach Titelbeschreibung in csv die eine bestimmte ID haben (beginnend mit S), in der 2. Schleife wird in einer anderen csv nach Titel gesucht um weitere Daten aus der csv zu verarbeiten.

Das klappt soweit auch, allerding nur 1 mal in Schleife 2, hat er den Titel gefunden, bricht er ab und soll wieder in Schleife 1, nur dieses mal durchläuft er nur Schleife 1 bis zum Schluss. WARUM? Dachte eigentlich, dass ich mit reset() den Zeiger wieder auf Null setze aber irgendwie klapp das nicht.

Bin für alle Ideen offen.

Grüße aus Berlin


<?php
while($data = fgetcsv($handle, 8000, ';'))
{    
    $string = $data[3];
    
    if($string[0]=="S")
    {
        $cutstringoxid=$string;

        $shorttitle=special_character_replace2($data[5]); 
        
        $cutshorttitle = $shorttitle.' +';
        
        $teile = explode(" + ", $shorttitle);
        $titlealone=$teile[0]; 
                 
        reset($handle2);
        
        while($data2 = fgetcsv($handle2, 8000, ';'))
        {
            $string2 = $data2[3];
            
            if($found==1)
            {
                break;
            }
                      
            if($string2[0]!="S")
            {

                if($titlealone===$data2[5])
                {
                    $string2;   //ID
                    $newshorttitle=special_character_replace2($data2[5]); 
                    $newean=$data2[13];
                    $newmpn=$data2[16];
                    
                    echo $found=1;

                    $dataupdate = "$cutstringoxid|$newshorttitle|$newean|$newmpn
";
                    fputs($fp,$dataupdate); 
                    
                    $j++;
                }
                else
                {                    
                    $l++;
                }    
            }            
        }    
    }           
    $k++;         
}            
?>

also in c++ ist ein break ein defintiver raussprung komplett aus dem ganzen.

ergo würde ich probieren ich für schleife 2 probieren:

while($data2 = fgetcsv($handle2, 8000, ‘;’) && found !=1 )
{
}

dann sparste dir ein unsauberes spagetti code break.

in dem Fall ist break kein Raussprung, das wäre exit, wie auch immer spielt keine Rolle ob das drin ist oder nicht, wenn es raus ist würde er lediglich in Schleife 2 weitersuchen auch wenn der Titel schon gefunden wurde.

Löst ergo nicht das Problem, weitere Ideen?

Habs performanter gelöst!

Rein aus Wissensneugier würde mich trotzdem eine Lösung interessieren! Also falls es eine Lösung gibt und die gibt es sicherlich, einfach mal posten.

Danke!

ah der fehler ist übrigens, dass du “found” nicht wieder auf 0 setzt wenn er zurück in schleife 1 ist.

daher ist die bedingung “if found == 1” also ab dem ersten titel immer 1

im übrigen ist mein ansatz den ich vorher gepostet hab immer noch besser als ihn in die schleife laufen zu lassen und dann erst abzufragen. break sollte auch immer mit vorsicht genossen werden.

daher empfehle ich also:

  1. found wieder auf 0 setzen nachdem er aus schleife 2 raus ist.

  2. schleife 2 wie folgt: while($data2 = fgetcsv($handle2, 8000, ‘;’) && found !=1 )

Dann schreibe doch bitte auch, wie.

Das reset ist falsch, reset arbeitet mit arrays du übergibst ihm aber einen filepointer. Du möchtest “rewind” nutzen, nicht reset :wink:

edit:

Übrigens. So kann man das mit PHP 5 machen:


$file = new SplFileObject('csvdatei.csv');
$file->setFlags(SplFileObject::READ_CSV); // alles als csv behandeln
$file->setCsvControl(',','"'); // zur sicherheit noch die csv kontrollchars

foreach ($file as $lineNo => $line) {
     $string = $data[3];
     // hier dein code
}

ist gleich viel “fluffiger” und die klassen sind auch erweiterbar sodass man sich schöne eigene File Container bauen kann für solche exporte.

hier die doku zur klasse:

http://de3.php.net/manual/de/class.splfileobject.php

edit:

noch ein paar sachen:

dann sparste dir ein unsauberes spagetti code break.

ganz unsauber ist das nicht, häufig die einzige möglichkeit aus einer foreach schleife rauszuspringen. break hat übrigens parameter und kann “level” bekommen, sprich “break 2;” springt aus zwei verschachtelten schleifen.

in dem Fall ist break kein Raussprung, das wäre exit

exit beendet die skriptausführung komplett, break springt bloß aus der schleife.

Noch ein paar tips zum Code:


$dataupdate = "$cutstringoxid|$newshorttitle|$newean|$newmpn
";

Das ist nicht ganz sauber. “” führen php code aus, das schreibt sich zwar schön schnell ist aber im regelfall problematisch, weil eben wirklich ALLES in diesem string was php sein könnte ausgeführt wird.

die zeile könnte man auch so umsetzen:


    $dataupdate = implode('|', array($cutstringoxid, $newshorttitle, $newean, $newmpn)) . "
";

Zudem würde ich für die ganzen fixen array positionen klassenkonstanten definieren, so hast du “sprechenden” code den du besser lesen und im nachhinein erheblich besser warten kannst da du dann nur noch eine stelle ändern musst. Wenn du da in 2 monaten nochmal draufguckst weisst du auf anhieb nicht mehr was “$data[13]” nochmal war und musst nachzählen.

@rubbercut

Gelöst in dem ich nicht eine weitere csv zum Vergleich ran ziehe, sondern vorhanden Daten aus der DB.

@csimon

Das ist ja mal ne ausführliche Antwort. Nur leider ist es mir aus Zeitmangel bis dato nicht vergönnt gewesen mich mit objektorientierten PHP5 zu befassen. Verstehe schon was du meinst bzgl. Wartbarkeit und Übersicht. Die Scripte sind jedoch so minimalistisch, so dass es keinen Sinn machte sich mit anderer Programmierart zu befassen, zumal ich nebenher auch noch meine Produkte verkaufen will. Hab jetzt so an die 40 Scripte die alles halbwegs automatisieren vom Produktimport mit über 10.000 Artikeln bis hin zur Erstellung der googlefeed xml und erweiterte Artikelverwaltung uvm. und ja alles läuft wie du sagen würdest über Spagetticode.

Defakto ist aber auch, es funzt!

Ja das rewind wäre es gewesen :wink: und mit break wollte ich genau das erreichen, raus aus Schleife 2 und Schleife 1 fortfahren, exit ist wie du schon erwähnst ein Scriptabbruch.

Trotzdem werde ich mich irgendwann mal mit objektorientierten PHP5 befassen ABER erst wenn es wirklich notwendig wird, bis dahin Spagetticode. :slight_smile:

Und danke für die ausführlichen Beispiele.

Grüße aus Berlin