Schleife und übergehen nicht existenter ip's

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

  • Schleife und übergehen nicht existenter ip's

    Hi @ all,

    ich habe bislang folgendes geschrieben

    PHP-Code:
     <?php
    $id_neu 
    $id 1;
    $id_alt $id 1;


    echo 
    "<div align=\"left\">";
    echo 
    "<a href='$PHP_SELF?id=$id_neu'>";
    ?>
    <img src="pics/nextvideobutton.gif" border="0"></a></div>
    Nun möchte ich versuchen, dass

    1. nach dem idmax wieder zu id1 gesprungen wird und

    2. wenn beispielsweise id3; id4 nicht existent sind, man automatisch von id zu id5 springt.


    zu 2.

    man könnte ein Array aller IDs machen, in dem Stil:
    $all_ids[0] = 1
    $all_ids[1] = 2
    $all_ids[2] = 5
    $all_ids[3] = 7

    Im vorliegenden Beispiel gäbe es 4 Einträge in der DB, jeweils mit den ids 1, 2, 5, 7. Man könnte sagen:
    aktuelle ID ist zB 2, finde den entsprechenden Array-Eintrag bzw. die Nr..

    Dann:

    $id_neu = $all_ids["$all_id_für2" + 1]

    Sprich in diesem Fall:

    $id_neu = $all_ids[2] = 5

    Was haltet ihr davon ?
    Zuletzt geändert von Odomanie; 22.05.2007, 21:37.

  • #2
    ohne array:

    wie bisher einfach die ID um einen hochzählen...

    in der query dann folgendes:

    WHERE id>=$nextid ORDER BY id LIMIT 1

    fertig

    dadurch ist es egal, ob die nächste, die übernächste oder welche auch immer id vergeben ist, da du den ersten datensatz erhälst, der nextid oder der nächsten größeren zugeordnet ist...

    greetz, high
    Good programming is 40% experience, 20% skill, 20% RTFM, 15% caffeine, and 5% attention to detail.
    When everything else fails, manipulate the data...
    Beschriftungen / Großformatdruck / Werbemittel

    Kommentar


    • #3
      Ich sehe da nichts von ner Query. Was hat das ganze mit IPs zu tun?
      Nur wenige wissen, wieviel man wissen muss, um zu wissen, wie wenig man weiß.

      Kommentar


      • #4
        @arsen

        Es interessiert wohl kaum einen, was du siehst oder nicht...
        Allgemein sollte es bekannt sein, dass Datenbanken mit queries abgefragt werden...

        Im vorliegenden Beispiel gäbe es 4 Einträge in der DB, jeweils mit den ids 1, 2, 5, 7.
        Der aufmerksame Leser hätte weiterhin gemerkt, dass es sich in der Überschrift um einen Tippfehler handeln muss, und es um iDs statt um iPs geht...

        ist nicht ganz so schwierig, aber wenn du fragen hast, frag ruhig ;-)

        hab ich übrigens auch eine: Warum sind hier eigentlich 50% der Beiträge Einzeiler nach dem Motto "Ich hab zwar auch keine Ahnung, aber ich kritisiere erst mal den Fragenden, weil ich was nicht verstanden habe" ?

        greetz, high
        Good programming is 40% experience, 20% skill, 20% RTFM, 15% caffeine, and 5% attention to detail.
        When everything else fails, manipulate the data...
        Beschriftungen / Großformatdruck / Werbemittel

        Kommentar


        • #5
          Hi Leute,

          back to business


          ich habe eine lösung für den 2ten teil der frage gefunden, allerdings ist mir das mit der schleife noch nicht geglückt... ich möchte, dass bei $max_id mit dem gleichen button zu der ersten(dabei muss geprüft werden welche id existiert) id gesprungen wird. Weiß jemand was ich meine ?



          PHP-Code:
          <?php

          $mysql_host 
          "x";
          $mysql_user "x;
          $mysql_db = "x";
          $mysql_pass = "x";
          $mysql_table = "x";

          $conn = @MYSQL_CONNECT($mysql_host$mysql_user$mysql_pass);
          @MYSQL_SELECT_DB(
          $mysql_db) or die ("<h1>Entweder existiert die Datenbank '$mysql_db' nicht oder der MySQL-Server ist nicht verbunden!</h1>");
          //Check
          if(!
          $conn) die("<h1>MySQL-Verbindungsfehler<br>Pr&uuml;fen Sie die Einstellungen ...</h1>");

          $result = MYSQL_QUERY("SELECT FROM $mysql_table ORDER BY 'id'");
          $ids = array();
          while (
          $row = MYSQL_FETCH_ARRAY($result))
              {
              
          $ids[] = $row[id];
              }


          if(
          $show > 0)
          {
          $id_prev = $show - 1;
          echo "
          <br><a href=\"test.php?show=" $id_prev "\">LEAST</a>";
          }
           
          $id_next $show 1;

          echo 
          "<br>ID current: " $ids[$show] . "<br>";
               
          $max_id end($ids);
          if(
          $ids $max_id) echo "<br><a href=\"test.php?show=" $id_next "\">Next</a>";
          if(
          $ids == $max_id) echo "<br><a href=\"test.php?show=" $id "\">Next anfang</a>";
          if(
          $ids[$show] != end($ids))
           {

          echo 
          "ID-next: " $ids[$id_next];

          echo 
          "<br><a href=\"test.php?show=" $id_next "\">Next</a>";
          echo 
          "<br><a href=\"test.php?show=" $id "\">Next anfang</a>";
           }

          MYSQL_CLOSE($conn);
          ?>

          Kommentar


          • #6
            if($ids == $max_id) echo "<br><a href=\"test.php?show=" . $id = 1 . "\">Next anfang</a>";
            dort machst du gleichzeitig mit deiner ausgabe von $id eine zuweisung ($id = 1)

            geht man davon aus, dass du deine IDs in einem Array sortiert stehen hast, dann wäre folgendes die Lösung:

            PHP-Code:
            if($ids == $max_id) echo "<br><a href=\"test.php?show=" $ids[0] . "\">Next anfang</a>" 
            bedenke bitte, dass dein Code langsamer wird, umso mehr einträge deine DB enthält, weil du jedes mal die gesamte tabelle abfragst.

            sinnvoller wäre es, den link in jedem Fall gleich zu frmulieren, und die abfragelogik entscheiden zu lassen, welcher datensatz nun wirklich zu holen ist.

            greetz, high
            Good programming is 40% experience, 20% skill, 20% RTFM, 15% caffeine, and 5% attention to detail.
            When everything else fails, manipulate the data...
            Beschriftungen / Großformatdruck / Werbemittel

            Kommentar


            • #7
              Vielen Dank für deine Antwort!

              Ab was für einer größenordnung verlangsamt sich deiner meinung nach der zugriff spürbar?


              Nun sind immer noch beide "next" zu sehen. ich möchte allerdings versuchen, dass mit ein und dem selben "next" zum einen weitergeskippt werden kann und zum anderen das man bei $max_id zu id1(sofern vorhanden) skippt.

              Ich habe es wie folg geändert:

              PHP-Code:
              <?php

              $mysql_host 
              "x";
              $mysql_user "x";
              $mysql_db "x";
              $mysql_pass "x";
              $mysql_table "x";

              $conn = @MYSQL_CONNECT($mysql_host$mysql_user$mysql_pass);
              @
              MYSQL_SELECT_DB($mysql_db) or die ("<h1>Entweder existiert die Datenbank '$mysql_db' nicht oder der MySQL-Server ist nicht verbunden!</h1>");
              //Check
              if(!$conn) die("<h1>MySQL-Verbindungsfehler<br>Pr&uuml;fen Sie die Einstellungen ...</h1>");

              $result MYSQL_QUERY("SELECT * FROM $mysql_table ORDER BY 'id'");
              $ids = array();
              while (
              $row MYSQL_FETCH_ARRAY($result))
                  {
                  
              $ids[] = $row[id];
                  }


              if(
              $show 0)
              {
              $id_prev $show 1;
              echo 
              "<br><a href=\"test.php?show=" $id_prev "\">LEAST</a>";
              }
               
              $id_next $show 1;

              echo 
              "<br>ID current: " $ids[$show] . "<br>";
                   
              $max_id end($ids);
              if(
              $ids $max_id) echo "<br><a href=\"test.php?show=" $id_next "\">Next</a>";
              if(
              $ids == $max_id) echo "<br><a href=\"test.php?show=" $ids[0] . "\">Next</a>";
              if(
              $ids[$show] != end($ids))
               {

              echo 
              "ID-next: " $ids[$id_next];

              echo 
              "<br><a href=\"test.php?show=" $id_next "\">Next</a>";
              echo 
              "<br><a href=\"test.php?show=" $ids[0] . "\">Next</a>";
               }

              MYSQL_CLOSE($conn);
              ?>
              c

              Kommentar


              • #8
                OffTopic:
                Das da was vonner DB steht hab ich übersehen, mein Fehler. Das mit den IPs IDs gemeint waren habe ich aber wirklich nicht gecheckt. Das P ist doch nun wirklich nicht neben dem D auf der Tastatur. Die Erklärung war auch sehr dürftig.
                Nur wenige wissen, wieviel man wissen muss, um zu wissen, wie wenig man weiß.

                Kommentar


                • #9
                  ahhh jepp, i see...

                  da ist noch ein dreher in den variablen drin...

                  die abfrage soll wohl im klartext heißen:

                  falls aktuelle id < max_id, dann mache dieses
                  falls aktuelle id == max_id, dann mache jenes...

                  die aktuelle id steht aber nicht in $ids, sondern in $show

                  das sollte helfen...

                  =============
                  wann es merklich langsamer wird, hängt davon ab, wie viele daten in der tabelle (außer id) sonst noch drin stehen...

                  um die geschwindigkeit einigermaßen gut zu halten, ohne die logik zu verändern, solltest du in der query nur holen, was du wirklich brauchst...

                  also statt SELECT * FROM

                  nur SELECT id FROM

                  das geht schon mal um einiges schneller, außer, du benötigst natürlich vollständige datenbankzeilen an anderer stelle im script...

                  für eine einfache seite denke ich, ist das script gut für ca. 1000 einträge, je nachdem, wie schnell der server ist, auf dem das ganze läuft... wenn du wirklich performance benötigst, dann solltest du die logik ändern

                  beispiel...
                  du übergibst im link nicht die nächste id oder die vorherige, sondern
                  du übergibst die aktuelle und ggf in einem zweiten parameter ein "next" oder ein "prev"...

                  die aufgerufene seite würde dann hin gehen und folgendes tun:
                  falls kein schlüsselwort, dann hole den datensatz mit genau dieser ID (WHERE id=$my_id), falls schlüsselwort "next", dann hole den datensatz mit der ersten ID, die größer ist, als ID (WHERE id>$my_id ORDER BY id ASC LIMIT 1), falls dort kein datensatz zu finden ist, dann hole den ersten datensatz in der liste... falls schlüsselwort "prev" dann hole den datensatz mit der ersten ID, die kleiner ist als ID (WHERE id<$my_id ORDER BY id DESC LIMIT 1) falls dort keine zu finden ist, dann hole den letzten datensatz in der liste...

                  damit musst du im normalfall nur einen einzigen datensatz mit einer einzigen query aus der datenbank holen.
                  einzige ausnahmen sind die beiden extrema, die eine zweite query erfordern, weil es keinen vorherigen bzw. nächsten datensatz mehr gibt. in diesem fall wäre aber auch nur ein datensatz abzuholen, weil die erste query in einem leeren ergebnis endet.

                  wofür ist denn die anwendung gedacht?

                  greetz, high
                  Good programming is 40% experience, 20% skill, 20% RTFM, 15% caffeine, and 5% attention to detail.
                  When everything else fails, manipulate the data...
                  Beschriftungen / Großformatdruck / Werbemittel

                  Kommentar


                  • #10
                    Original geschrieben von highrise
                    das geht schon mal um einiges schneller, außer, du benötigst natürlich vollständige datenbankzeilen an anderer stelle im script...
                    Ich brauche andere datensätze aus der tabelle an anderer stelle... daher muss ich es wohl auf diese weise lösen.




                    Original geschrieben von highrise
                    da ist noch ein dreher in den variablen drin...

                    die abfrage soll wohl im klartext heißen:

                    falls aktuelle id < max_id, dann mache dieses
                    falls aktuelle id == max_id, dann mache jenes...

                    die aktuelle id steht aber nicht in $ids, sondern in $show

                    Kannst du mir das nochmal erklären? Bitte.


                    Und dann habe ich noch ein kleines prob bei der lösung mit array. und zwar wenn man einen eintrag direkt verlinken möchte ist es solange kein problem, bis der erste eintrag aus der DB gelöscht wird, da sich dann alle werte (.php?show=4) um einen wert verschieben... und das ist ja mist. ich bräuchte einen dauerhaften link zu einer id. mit der id lösung wäre das natürlich kein problem, aber gibt es auch für die Arrayvariante eine lösung?

                    Kommentar


                    • #11
                      Kannst du nicht nur die nächste und vorige id abfragen?

                      PHP-Code:
                      SELECT MAXp.id ) AS prevMINn.id ) AS next
                      FROM tabelle 
                      AS ptabelle AS n
                      WHERE p
                      .id <$aktuelle_id
                      AND n.id >$aktuelle_id 
                      so in etwa?
                      ich glaube

                      Kommentar


                      • #12
                        kann ich gerne noch mal erklären...

                        am einfachsten ist es glaub ich, wenn ich deinen code kommentiere:

                        PHP-Code:
                        //hole alle einträge aus der Tabelle, die in $mysql_table vermerkt ist der Reihe nach
                        $result MYSQL_QUERY("SELECT * FROM $mysql_table ORDER BY 'id'");
                        //erzeuge ein leeres Array und merk es dir in der Variable $ids
                        $ids = array();

                        //solange wie noch ergebnisse von der datenbank kommen
                        while ($row MYSQL_FETCH_ARRAY($result))
                            {
                            
                        //merke dir das ergebnis des feldes $row[id] im nächsten freien Element des Array $ids (*3)
                            
                        $ids[] = $row[id];
                            }
                         
                        //ids sollte nun ein array sein, wie in deinem ersten beitrag beschrieben

                        //fallse der inhalt von $show>0 ist (in $show steht natürlich die 
                        //angeforderte ID drin, weil der Link später heißen wird z.B. 
                        //irgendwas.php?show=9
                        if($show 0)
                        {
                        //merke dir den Vorläufer von $show in $ud_prev
                        $id_prev $show 1;
                        //shreibe einen HTML Link zum Vorläufer (also zu $id_prev) (*1 später mehr)
                        echo "<br><a href=\"test.php?show=" $id_prev "\">LEAST</a>";
                        }

                        //merke dir den nachfolger von $show in $id_next 
                         
                        $id_next $show 1;


                        //gib den Inhalt von $ids an der Stelle $show aus
                        echo "<br>ID current: " $ids[$show] . "<br>";
                             
                        //hole den LETZTEN eintrag aus $ids un merke ihn dir in $max_id
                        $max_id end($ids);

                        //Achtung! falls das Array $ids < $max_id .... diese Abfrage ist 
                        //natürlich quatsch... dort sollte es heißen $ids[$show]<$max_id
                        if($ids $max_id) echo "<br><a href=\"test.php?show=" $id_next "\">Next</a>";
                        //hier genauso... falls das Array $ids == der Zahl $max_id ist ebenso 
                        //quatsch... besser $ids[$show] == $max_id
                        if($ids == $max_id) echo "<br><a href=\"test.php?show=" $ids[0] . "\">Next</a>";

                        //testausgaben nehme ich an ??
                        if($ids[$show] != end($ids))
                         {

                        echo 
                        "ID-next: " $ids[$id_next];

                        echo 
                        "<br><a href=\"test.php?show=" $id_next "\">Next</a>";
                        echo 
                        "<br><a href=\"test.php?show=" $ids[0] . "\">Next</a>";
                         } 
                        soooo.. die stellen 1 und 2 in meinem durcheinander linken jeweils auf $show-1 bzw $show+1
                        das heißt, die wirklichen IDs, die du dir zuvor mühevoll in ein array gelegt hast, bleiben völlig unbeachtet, und die links werden sicherlich nur funktionieren, wenn die IDs lückenlos und der Reihe nach vorhanden sind... sonst gibt das huddel...

                        abhilfe kann geschaffen werden, wenn du den code innerhalb deine while schleife änderst (*3)

                        zunächst werden wir mal die zeilen
                        $id_prev = $show - 1;
                        und
                        $id_next = $show + 1;
                        ersatzlos streichen die bringen ja gar nichts, außer, dass wir einen hoch oder runter zählen. in wirklichkeit wollen wir aber die tatsächlich nächste oder vorherige ID wissen... das können wir innerhalb der schleife tun:

                        also
                        PHP-Code:
                        //merken wir uns, dass wir noch keine datensätze geholt haben
                        $zuletzt_geholt 0;
                        while (
                        $row MYSQL_FETCH_ARRAY($result))
                            {
                            
                        //nachsehen ob im vorherigen durchlauf evtl $show geholt 
                            //wurde... dann ist dieser durchlauf $id_next
                            
                        if ($zuletzt_geholt == $show$id_next $row[id];
                            
                        //nachsehen, ob wir vielleicht jetzt gerade $show geholt haben, 
                            //dann steht id_prev in zuletzt_geholt aus dem vorherigen 
                            //durchlauf...
                            
                        if ($row[id] == $show$id_prev=$zuletzt_geholt
                            
                        //jetzt merken wir und noch die aktuelle ID in der holfsvariable $zuletzt_geholt für die nächste runde...
                            
                        $zuletzt geholt $row[id];
                            
                        //und speichern sie im array etwas anders als zuvor.. wir 
                            //benutzen nämlich zusätzlich noch einen textschlüssel 
                            //'id'.$row[id]
                            //das erlaubt uns später, direkt auf die zelle, in der $show drin 
                            //steht zuzugreifen, ohne irgendwelchen huddel... später mehr
                            
                        $ids['id'.$row[id]] = $row[id]
                            }
                        //nachdem wir alles durchlaufen haben, müssen wir uns noch 
                        //gedanken über die extremwerte machen... falls es keinen vorläufer 
                        //zu $show gibt, dann wird $id_perv den Wert 0 haben.. damit 
                        //haben wir es schließlich ganz zu beginn initialisiert.... wenn das so 
                        //ist, dann soll $id_prev auf den letzten eintrag zeigen
                        if ($id_prev == 0$id_prev end($ids); 
                        soooo....

                        unser array hat jetzt übrigend zwei indizes... einen numerischen vie bisher... und einen benannten mit textschlüsseln...

                        um dein array aus deinem ersten beitrag zu verwenden...

                        $ids[0] => 1
                        $ids[1] => 2
                        $ids[2] => 5
                        $ids[3] => 7

                        aber auch:
                        $ids['id1'] => 1
                        $ids['id2'] => 2
                        $ids['id5'] => 5
                        $ids['id7'] => 7

                        zu deinen vollständigen datensätzen:
                        mag sein, dass ich mich da falsch ausgedrückt habe... du merkst dir in dem array ja nur die IDs... der rest der abfragen wir ohnehin verworfen... da gehe ich davon aus, dass an anderer stelle sowieso neu bei der DB angefragt wird.. insofern kannst du ruhig SELECT id FROM an dieser speziellen stelle verwenden statt SELECT * FROM...

                        das bringt einiges...

                        das benannte array dürfte auch schon weitestgehend dein problem lösen, das auftaucht, nachdem datensätze gelöscht worden sind...
                        du solltest immer auf die tatsächliche ID verlinken...
                        however....

                        wenn noch was unkar ist, dann schreib einfach wieder...

                        greetz, high
                        Zuletzt geändert von highrise; 24.05.2007, 16:45.
                        Good programming is 40% experience, 20% skill, 20% RTFM, 15% caffeine, and 5% attention to detail.
                        When everything else fails, manipulate the data...
                        Beschriftungen / Großformatdruck / Werbemittel

                        Kommentar


                        • #13
                          die ORDER BY klausel ist übrigens nicht korrekt.

                          zu der frage ganz am anfang (hab jetzt kein wort aus der diskussion gelesen):
                          die links sollten so aussehen:
                          Code:
                          foo.php?id=42&direction=next
                          wobei "id" die aktuelle id ist.

                          foo.php nimmt den parameter "direction" und wählt aus der datenbank (z.b. bei "next") mit:
                          Code:
                          SELECT ... WHERE `id` > $_GET['id']
                          ORDER BY `id` ASC
                          LIMIT 1
                          den "nächsten" eintrag, egal, welche id er hat.

                          Kommentar


                          • #14
                            @penizillin...

                            sehe ich genauso... steht auch schon irgendwo
                            scheint aber (aus welchem grund auch immer) hier nicht in frage zu kommen... deshalb der komplizierte workaraound...

                            ich glaube auch, dass es hier eher um das verständnis geht, WARUM man es so machen sollte, und nicht einfach nur, wie es funktioniert...

                            schau mal meinen post vom 22-05-2007 21:44
                            und lies mal korrektur... vielleicht kriegen wir ihn dann gemeinsam auf den richtigen weg ;-)

                            greetz, high
                            Good programming is 40% experience, 20% skill, 20% RTFM, 15% caffeine, and 5% attention to detail.
                            When everything else fails, manipulate the data...
                            Beschriftungen / Großformatdruck / Werbemittel

                            Kommentar

                            Lädt...
                            X