Ankündigung

Einklappen
Keine Ankündigung bisher.

Konzeptionelles Problem WHILE-/FOR-Schleifen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Konzeptionelles Problem WHILE-/FOR-Schleifen

    Guten Abend liebes Forum,

    ich bin der Neue und hoffe, hier Unterstützung zu finden und vielleicht später auch mal geben zu können

    Zu meinem aktuellen Problem:
    Ausgangslage ist ein array, in dem z.B. $album, $interpret, $titel und $laenge anliegen.

    Ziel ist, die Daten in der Form
    Code:
    <DATEIANFANG>
    $album
    $interpret
    
    $titel $laenge
    $titel $laenge
    $titel $laenge
    $titel $laenge
    $titel $laenge
    ...
    <DATEIENDE>
    in jeweils eine Datei pro $album zu schreiben. Und zwar so, dass $interpret und $album darin nur jeweils 1x ausgegeben werden; $titel und $laenge natürlich entsprechend der tatsächlichen Anzahl.

    Mit einer WHILE- oder FOR-Schleife schaffe ich es zwar, alle zu $album gehörenden Werte in eine Datei zu schreiben, aber eben nur in der Form
    Code:
    <DATEIANFANG>
    $album $interpret $titel $laenge
    $album $interpret $titel $laenge
    $album $interpret $titel $laenge
    ...
    <DATEIENDE>

    Könnt Ihr mir einen Tipp geben? Z. B. wie ich die Schleifen verschachteln müsste und wie die Bedingungen sinnvoller Weise aussehen könnten?
    grüße vom mathes

  • #2
    Hallo mathes,

    zunächst ein Herzliches Willkommen im Forum!

    Was dein Problem angeht, so gibt es für mich zwei Lösungsmöglichkeiten:

    1. Schleifendurch so konzeptionieren, dass du nur einmal pro äußerem Durchlauf Interpret und Titel schreibst.

    2. Array so konzeptionieren, dass es nur einmal Interpret und Titel enthält.

    Da ich keinen genauen Code kenne kann ich dir auch nur so abstrakt antworten. Alternativ arbeitest du mit Objekt-Strukturen. Hier kannst du ja ein Objekt "Album" mit den Attributen "Interpret" und Titel" und ein Objekt "Track" mit den entsprechenden Attributen entwerfen. Dabei hat das Objekt "Album" ein Attribut für die Speicherung der Titel. In dieser Liste befinden sich dann die Objekte "Track". Hast du einen Liste von "Album"-Objekten ist beim Durchlauf genau definiert, wie die Ausgabe zu erstellen ist, das es die Interpret- und Titel-Information nur einmal gibt.
    Viele Grüße,
    Dr.E.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1. Think about software design [B]before[/B] you start to write code!
    2. Discuss and review it together with [B]experts[/B]!
    3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
    4. Write [I][B]clean and reusable[/B][/I] software only!
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Kommentar


    • #3
      Hallo Dr.E.,
      vielen Dank für die nette Aufnahme und Deine Antwort!
      Vorschlag 1 müsste ich hinbekommen; die "elegantere" Methode wäre wohl 2. Die dritte Variante kann ich zwar gedanklich nachvollziehen, dazu fehlt mir aber noch etwas die Basis.
      Ich melde mich später mal mit einen Statusbericht
      grüße vom mathes

      Kommentar


      • #4
        da du ja pro album eine datei hast, was spricht gegen einen solchen dateinamen:
        interpret_album.datei
        inhalt ist dann
        $titel $laenge
        $titel $laenge
        $titel $laenge
        $titel $laenge
        $titel $laenge

        oder ordner interpret, dateiname album

        oder was spricht gegen eine datenbank

        Kommentar


        • #5
          Mal etwas weiter ausgeholt...

          Hallo zusammen,

          vielleicht sollte ich doch mal etwas konkreter werden; hier mal der Code, den ich bisher habe:

          PHP-Code:
          <?
          #    HIER WERDEN DIE VARIABLEN "ALBUM" UND "INTERPRET" AUSGELESEN...
              $queryFileHeader = ("SELECT album, interpret FROM alben ORDER BY interpret ASC");

              $resultFileHeader = mysql_query($queryFileHeader);


              while ($row = mysql_fetch_array($resultFileHeader)) {
                  $album = $row ["album"];
                  $interpret = $row ["interpret"];
                  $id = $row ["id"];


          #    ...UND IN DEN DATEI-HEADER GESCHRIEBEN
                      $fileHeader .= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
                      $fileHeader .= "<Alben Version=\"1.0\">";
                      $fileHeader .= "<Album Name='".$album."', Interpret='".$interpret."'>";


          #    NUN WERDEN FUER DAS EINZELNE "ALBUM" DIE VARIABLEN "TITEL" UND "LAENGE" AUSGELESEN...
                      $queryFileBody = ("SELECT titel, laenge FROM inhalt WHERE albumId = '$id'");

                      $resultFileBody = mysql_query($queryFileBody);


                      while ($row = mysql_fetch_array($resultFileBody)) {
                          $titel = $row ["titel"];
                          $laenge = $row ["laenge"];

          #    ...UND IN DEN FILEBODY GESCHRIEBEN
                          $fileBody .= "<Titelname Type=\"Item\" Titel=".$titel." Laenge=".$laenge."/>";
                          }


                      $fileFooter .= "</Album>";
                      $fileFooter .= "</Alben>";


          #    SCHLIESSLICH WIRD DIE XML-DATEI LOKAL GESPEICHERT
                      $createFile = fopen("".$pfad."/".$album.".xml","a+");
                      fputs($createFile,$fileHeader."\r\n".$fileBody."\r\n".$fileFooter);
                      fclose($createFile);
                      }
                  }
          ?>
          Bei jedem Ausführen des Skripts wird zwar eine XML-Datei erzeugt; der Inhalt derselben ist jedoch ein unbrauchbares, verschachteltes Konglomerat aus ($fileHeader + $fileBody + $fileFooter) * Anzahl der vorhandenen Datensätze.
          grüße vom mathes

          Kommentar


          • #6
            Du machst das doch etwas sehr kompliziert. Eine Abfrage genügt doch. Hier einfach mal ein beispiel für die Ausgabe in eine Tabelle:
            PHP-Code:
            <?
            $query = "
                SELECT 
                    a.album, 
                    a.interpret
                    i.titel,
                    i.laenge 
                FROM 
                    alben 
                INNER JOIN
                    inhalt i ON a.id = i.albumId
                ORDER BY 
                    interpret ASC";

                $result = mysql_query($query) or exit(mysql_error());

                $interpret_alt = $album_alt = '';
                echo "<table>"
                echo "<tr><th>Interpret</th><th>Album</th><th>Titel</th><th>L&auml;nge</th></tr>\n";
                while ($row = mysql_fetch_array($result)) {
                    $interpret = '';
                    if ($row["interpret"] != $interpret_alt){
                        $interpret = $row["interpret"];
                        $interpret_alt = $interpret;
                    }
                    echo "<tr><td>$interpret</td>";
                    $album = '';
                    if ($row["album"] != $album_alt){
                        $album = $row["album"];
                        $album_alt = $album;
                    };
                    printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>",
                               $interpret, $album, $row['titel'], $row['laenge']);
                }
            ?>
            Daraus solltest du eigentlich die Datei-version ableiten können
            Gruss
            L

            Kommentar


            • #7
              Hmm, kompliziert?? Echt?
              Ich werde mir dein Konstrukt mal entsprechend umbauen und sehen, ob es klappt. Den JOIN-Syntax habe ich noch nicht ganz durchdrungen.
              Nach Umstellen der Schleifen habe ich übrigens mittlerweile eine Version, die bis auf einen Fehler läuft. Die Daten werden jetzt in korrektem Syntax in die Datei geschrieben. Nur leider ALLE in ALLE Dateien...
              Wie schaffe ich es denn, dass bei jedem Schleifendurchlauf nur die zu einem $album gehörenden Daten in eine Datei geschrieben werden?
              grüße vom mathes

              Kommentar


              • #8
                Zitat von mathes Beitrag anzeigen
                Wie schaffe ich es denn, dass bei jedem Schleifendurchlauf nur die zu einem $album gehörenden Daten in eine Datei geschrieben werden?
                Indem du für jedes Album halt einen eigene Datei erstellst.
                Ich sehe allerdings nicht ein, wozu es gut sein soll, Daten aus einer Datenbank in Textdateien zu speichern.
                Gruss
                L

                Kommentar


                • #9
                  Hi L,

                  Ich sehe allerdings nicht ein, wozu es gut sein soll, Daten aus einer Datenbank in Textdateien zu speichern.
                  in meinem Post habe ich der Übersichtlichkeit halber nur Beispielvariablen verwendet, da die ganze Geschichte etwas komplexer ist.

                  Indem du für jedes Album halt einen eigene Datei erstellst.
                  Naja, das schon, aber wie sage ich's meiner WHILE-Schleife? Die macht erst Schluss, wenn alles in der Wurst ist.
                  Das Skript wird zeitgesteuert ausgeführt. Zum Zeitpunkt x werden immer alle in der DB neu aufgelaufenen Daten abgefragt. Wenn man nur einen Datensatz "erwischt", ist alles wunderbar; sobald es mehrere sind, Müll.
                  Ich habe es sowohl mit einem break am Ende der Schleife als auch mit einem Zähler in der Schleife probiert, aber ich glaube, dass ich die Funktionweise von beiden nicht ganz verstanden habe.
                  grüße vom mathes

                  Kommentar


                  • #10
                    Na, wenn du die Ableitung halt nicht schaffst:
                    PHP-Code:
                    ...
                        
                    $result mysql_query($query) or exit(mysql_error());

                        
                    $interpret_alt $album_alt '';
                        while (
                    $row mysql_fetch_array($result)) {
                            
                    $interpret '';
                            if (
                    $row["interpret"] != $interpret_alt){
                                
                    $interpret $row["interpret"];
                                
                    $interpret_alt $interpret;
                            }
                            
                    $album '';
                            if (
                    $row["album"] != $album_alt){
                                
                    $album $row["album"];
                                
                    $album_alt $album;
                                if (!empty(
                    $fp)){
                                    
                    fclose($fp);
                                }
                                
                    $fp fopen("$album.txt"'w');
                                
                    fputs($fp"Artist:\t$interpret\nAlbum:\t$album\nTracks:\n");
                            };
                            
                    fprintf($fp "\t%s(%s)\n"$row['titel'], $row['laenge']);
                        }
                        
                    fclose($fp); 
                    Der Sinn des Ganzen ist mir allerdings immer noch völlig suspekt.
                    Gruss
                    L

                    Kommentar


                    • #11
                      Hi L,

                      Na, wenn du die Ableitung halt nicht schaffst:
                      Nee, das ist (in diesem Fall) nicht das Problem; nur war ich noch gar nicht so weit Vielen Dank trotzdem für das "strippen"!

                      Der Sinn des Ganzen ist mir allerdings immer noch völlig suspekt.
                      Es geht ganz einfach darum, Daten als XML zu exportieren, um sie mit einer bestehenden Anwendung weiterverarbeiten zu können.

                      So, aber jetzt zur Sache: Ich habe meine WHILE-Schleife mal entsprechend Deinem Snippet umgebaut. Das funktioniert nun auch ganz munter für den Fall, dass innerhalb des festgelegten Abfragezeitraums ein einzelner Datensatz angelegt wurde. Sind es mehrere, wird nur aus dem jeweils letzten eine Datei geschrieben.
                      Darf ich Dich/Euch noch mal um einen Tipp bitten?
                      grüße vom mathes

                      Kommentar


                      • #12
                        Da müsste ich deinen genauen Code sehen. Meiner kanns nicht sein, weil da noch ein entscheidender Fehler drin war.
                        Gruss
                        L

                        Kommentar


                        • #13
                          Alsdann - Butter bei die Fische

                          Meine bisherige Version:
                          PHP-Code:
                              $queryFileHeader = ("...");
                              $queryFileBody = ("...");

                              $resultFileHeader = mysql_query($queryFileHeader);

                              while ($row = mysql_fetch_array($resultFileHeader)) {
                                  $orderNr = $row ["orderNr"];
                                  $orderDate = date("d.m.Y; H:i",$row ["orderDate"]);
                                  $customerNr = $row ["customerNr"];

                                  $collectionTime = (date('YmdH')-$collectionInterval);

                                  $orderTime = date("YmdH",$row ["tstamp"]);

                                  if($orderTime >= $collectionTime) {
                                      $fileHeader .= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
                                      $fileHeader .= "<Bestellung Version=\"1.0\">";
                                      $fileHeader .= "<Bestelldaten Kundennummer='".$customerNr."', Bestelldatum='".$orderDate."'>";

                                      $resultFileBody = mysql_query($queryFileBody);

                                      while ($row = mysql_fetch_array($resultFileBody)) {
                                          $itemQty = $row ["itemQty"];
                                          $itemNr = $row ["itemNr"];
                                          $fileBody .= "<Artikel Type=\"Item\" Artikelnummer=".$itemNr." Menge=".$itemQty."/>";
                                          }

                                      $fileFooter .= "</Bestelldaten>";
                                      $fileFooter .= "</Bestellung>";
                                      }

                                      $createFile = fopen("".$path."/".$orderNr.".xml","a+");
                                      fputs($createFile,$fileHeader."\r\n".$fileBody."\r\n".$fileFooter);
                                      fclose($createFile);
                                      }
                          Das Ergebnis derselben: Datei 1 ist O.K.; Datei 2 enthält zusätzlich zu ihrem eigenen Inhalt den von Datei 1; Datei 3 den von 1, 2, und 3, usw.

                          Die nach Deinem Tipp geänderte Version sieht so aus:
                          PHP-Code:
                              $queryFileHeader = ("...");
                              $queryFileBody = ("...");

                              $resultFileHeader = mysql_query($queryFileHeader);

                              while ($row = mysql_fetch_array($resultFileHeader)) {
                                  $orderNr = $row ["orderNr"];
                                  $orderDate = date("d.m.Y; H:i",$row ["orderDate"]);
                                  $customerNr = $row ["customerNr"];

                                  $collectionTime = (date('YmdH')-$collectionInterval);

                                  $orderTime = date("YmdH",$row ["tstamp"]);

                                  if($orderTime >= $collectionTime) {
                          ######EINGEFUEGT######
                                      $orderNrLast = '';
                                      $customerNrLast = '';
                                      $customerNr = '';
                                      if ($row["Kundennummer"] != $customerNrLast) {
                                          $customerNr = $row["Kundennummer"];
                                          $customerNrLast = $customerNr;
                                          if (!empty($createFile)) {
                                              fclose($createFile);
                                              }
                          ####################

                                      $fileHeader .= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
                                      $fileHeader .= "<Bestellung Version=\"1.0\">";
                                      $fileHeader .= "<Bestelldaten Kundennummer='".$customerNr."', Bestelldatum='".$orderDate."'>";

                                      $resultFileBody = mysql_query($queryFileBody);

                                      while ($row = mysql_fetch_array($resultFileBody)) {
                                          $itemQty = $row ["itemQty"];
                                          $itemNr = $row ["itemNr"];
                                          $fileBody .= "<Artikel Type=\"Item\" Artikelnummer=".$itemNr." Menge=".$itemQty."/>";
                                          }

                                      $fileFooter .= "</Bestelldaten>";
                                      $fileFooter .= "</Bestellung>";
                                      }

                                      $createFile = fopen("".$path."/".$orderNr.".xml","a+");
                                      fputs($createFile,$fileHeader."\r\n".$fileBody."\r\n".$fileFooter);
                                      fclose($createFile);
                                      }
                                  }
                          Das Ergebnis: Es werden nur leere Dateien geschrieben, wenngleich in der korrekten Anzahl
                          Ja, ich weiß - zwei Queries sind umständlich, aber so habe ich es im Griff. Was ich seit meinem letzten Post geändert habe, weiß ich leider nicht mehr; da wurde zumindest noch eine Datei (die jeweils letzte) erzeugt.
                          grüße vom mathes

                          Kommentar


                          • #14
                            Das hat jetzt aber nicht mehr das Geringste mit meinem Beispiel zu tun. Aber wenn du es unbedingt kompliziert und mit mehreren Abfragen haben willst, dann kannst du das ja tun. Ich hab dir eine Lösung aufgezeigt.
                            Gruss
                            L

                            Kommentar


                            • #15
                              Ich hab dir eine Lösung aufgezeigt.
                              Und die habe ich versucht umzusetzen.

                              Aber wenn du es unbedingt kompliziert und mit mehreren Abfragen haben willst, dann kannst du das ja tun.
                              Die haben aber IMHO nichts mit dem Problem zu tun. Da geht es doch nur um umständich oder elegant. Das Problem liegt irgendwo in der äußeren WHILE-Schleife und/oder den IF-Abfragen.

                              Nochmal zu Deinem letzten Post:
                              Meiner kanns nicht sein, weil da noch ein entscheidender Fehler drin war.
                              Worin besteht denn der?

                              Bitte kuck doch noch mal drüber. Vielleicht fällt Dir ja doch noch was auf
                              grüße vom mathes

                              Kommentar

                              Lädt...
                              X