Pandar: Seitenzahlen mit mysql Datensätzen

Moin,

ich habe meiner Meinung nach eine extrem kompliziert Problem. Ich werke jetzt schon ein paar Stunden daran und es ist bisher nicht wirklich was rausgekommen.

Vielleicht kann mir jemand helfen.

Also es werden Datensätze aus einer Datenbank gelesen und die maximalen(links rechts), sowie aktuelle Seite erkannt.

Ich möchte gerne, dass es so funktioniert.

Ersten Seiten
!
1 2 3 4 5 6 7

!
1 2 3 4 5 6 7

!
1 2 3 4 5 6 7

Normal Zustand:
      !
1 2 3 4 5 6 7

!
2 3 4 5 6 7 8

!
3 4 5 6 7 8 9

!
4 5 6 7 8 9 10

Letzten Seiten:
        !
4 5 6 7 8 9 10

!
4 5 6 7 8 9 10

!
4 5 6 7 8 9 10

Also das ! sagt an, dass man sich gerade auf dieser Seite befinden.
Die Ausgabe und das auslesen habe ich bereits vollständig.

Im normal Zustand, gibt es links und rechts von der aktuelle 3 Seiten.
In den anderen beiden Zuständen, wird jeweils die fehlende Anzahl der anderen dazu addiert.
bsp:
  !
1 2 3 4 5 6 7
hier sind links 1 verschiebungen und rechts 5.

Also fehlen mir folgende Werte:

  • erste Seite die angezeigt wird
  • letzte Seite die angezeigt wird
    die beiden Werte müssen sich dann aber anpassen so das immer (außer wenn es weniger als 7 Seiten gibt) 7 Seiten zur Auswahl stehen.

Hat jemand ne Idee? Das Problem ist bei mir das mathematische, ich habe leider schon 4x ein Konzept gebaut, aber jedes mal kann ein falsches Ergebnis raus.

Danke für jede Hilfe!

  1. Hi!

    ich habe meiner Meinung nach eine extrem kompliziert Problem.

    Naja, so extrem ist es nun auch wieder nicht, denn Pager-Lösungen gibt es einige.

    Im normal Zustand, gibt es links und rechts von der aktuelle 3 Seiten.
    In den anderen beiden Zuständen, wird jeweils die fehlende Anzahl der anderen dazu addiert.
    Also fehlen mir folgende Werte:

    • erste Seite die angezeigt wird
    • letzte Seite die angezeigt wird
      die beiden Werte müssen sich dann aber anpassen so das immer (außer wenn es weniger als 7 Seiten gibt) 7 Seiten zur Auswahl stehen.

    Du hast die aktuelle Seite, du kennst die Differenz zur ersten oder zur letzten. Wenn sie weniger als 3 ist, hast du einen Korrekturwert für die andere Seite. Das beste ist außerdem noch, wenn die erste Seite zumindest zum internen Rechnen die Nummer 0 bekommt, sonst musst du immer eine 1 hinzufügen oder abziehen.

    max(0, 3 - n) ist die Anzahl der zusätzlichen Seiten auf der rechten Seite.

    Proberechnungen:
    3 - 0 = 3
    3 - 1 = 2
    3 - 2 = 1
    3 - 3 = 0
    3 - 4 = -1, aber max(0, -1) = 0

    Bekommst du die Rechte Seite selbst hin? Zu beachten ist noch der Spezialfall wenn weniger als 7 Seiten existieren. Da müsstest du den max/min-Trick auch noch mal auf die Berechnung von 3 und dem Korrekturwert anwenden.

    Lo!

    1. Also ich hab etwas rumversucht, aber ich glaub so weit war ich auch schon.
      Ich habe folgendes benutzt um den zusatz Wert für rechts zu berechnen:

      if($_GET[p] > 3) {
              $start = $_GET[p] - 3;
            }

      if($_GET[p] <= ($pnb - 4)) {
              $end = $_GET[p] + 4;
            }

      for($c=$start; $c>$end; $c++) {
              if($c==$_GET[p]) {
                echo $c;
              } else {
                echo '<a href="?p='.$c.'">'.$c.'</a>';
              }
            }

      Ich hab leider grad keine Plannung wie ichs weiter hinkriegen soll...
      Meine Idee war, dass es immer geht also auch bei 1 Seite oder 3 geht.

      Ich verstehe das mit max noch nicht ganz. Im php manual steht es werden arrays benutzt.

      Also mit den Code funktionieren alle Werte die zwischen 4 und letzte Seite - 4 liegen.
      Jetzt kommen wir zum Problem dass ich noch nicht lösen konnte.
      Also was rechts dazu kommt habe ich so gelöst

      if(($_GET[p] - 3) < 1) {
              $ends_add = ($_GET[p] -3) * -1;
            }

      Jetzt fehlt noch links und dazu kommt, dass ich noch überprüfen muss ob es auf der anderen Seite noch genung Seiten gibt?

      Vielleicht klappt es ja mit der max() funktion
      Hast du eine Ahnung wie ich das hinkriege oder jemand anderes?

      1. Hi!

        Ich habe folgendes benutzt um den zusatz Wert für rechts zu berechnen:
              if($_GET[p] > 3) {
                $start = $_GET[p] - 3;
              }
              if($_GET[p] <= ($pnb - 4)) {
                $end = $_GET[p] + 4;
              }

        Damit beachtest du erstmal nur den Normalfall. Im Nicht-Normal-Fall sind zudem $start und/oder $end übrigens nicht definiert. Mit nicht definierten Werten weiterzurechnen ist zwar unter PHP gestattet, aber wenig sinnvoll bis fehleranfällig. Wer weiß, was irgendwer vorher schon mit diesen Variablen angestellt hat.

        for($c=$start; $c>$end; $c++) {

        Du müsstest dann hier Notice-Meldungen angezeigt bekommen, wenn du das error_reporting auf E_ALL (und display_errors auf on) stehen hast.

        Meine Idee war, dass es immer geht also auch bei 1 Seite oder 3 geht.

        Für die Ränder sind Ausnahmen zu betrachten. Du benötigst auf der anderen Seite einen Korrekturwert, den du zusätzlich zu den drei normalen Seiten zuschlägst. Desweiteren ist der Fall mit weniger als 7 Seiten zu berücksichtigen.

        Ich verstehe das mit max noch nicht ganz. Im php manual steht es werden arrays benutzt.

        Da steht aber auch eine zweite Syntax mit Einzelwerten.

        Also mit den Code funktionieren alle Werte die zwischen 4 und letzte Seite - 4 liegen.
        Jetzt kommen wir zum Problem dass ich noch nicht lösen konnte.
        Also was rechts dazu kommt habe ich so gelöst

        if(($_GET[p] - 3) < 1) {
                $ends_add = ($_GET[p] -3) * -1;
              }

        Ja, so gehts auch (abgesehen vom Nicht-Vorhandensein von $ends_add, wenn die Bedingung nicht zutrifft). Das was du mit der Bedingung sicherstellst, mache ich mit max(0, ...). Ich berechne den Wert mit einem Einzeiler, mit der angenehmen Nebenwirkung, dass immer ein Ergebnis entsteht, das einer Variable zugewiesen wird und nicht nur manchmal. (Statt *-1 kannst du übrigens auch einfach nur ein Minuszeichen vor die öffnende Klammer setzen.)

        Jetzt fehlt noch links und dazu kommt, dass ich noch überprüfen muss ob es auf der anderen Seite noch genung Seiten gibt?
        Vielleicht klappt es ja mit der max() funktion

        Nein, hier benötigst du nach meiner Methode das Pendant min(). Die Logik zum Einsatz von min() und max() zur Begrenzung auf einen Minimal- oder Maximalwert ist genau entgegengesetzt als die Funktionen heißen.

        f: feststehender Wert, v: variabler (zu prüfender) Wert

        min(f, v)

        Solange v kleiner als f ist, ist das Ergebnis v, ansonsten f. Das Ergebnis ist also maximal f.

        max(f, v)

        Solange v größer als f ist, ist das Ergebnis v, ansonsten f. Das Ergebnis ist also minimal f.

        Aber zurück zum Thema. maxpages minus p ergibt die Differenz zum rechten Rand. Die darf nicht größer als 3 werden. 3 minus differenz ergibt die Anzahl der links hinzuzufügenden Seiten.

        Prüfung: 3 -  differenz = ?
        3 - (>3) -> gibt es nicht, wird abgefangen.
        3 - 3 = 0
        3 - 2 = 1
        usw.

        Bleibt noch der Fall abzufangen, dass jemand als aktuelle Seite einen Wert kleiner als 0 (oder 1, wenn du mit 1 anfängst zu zählen) und der maximalen Seitenzahl angibt.

        Lo!

        1. Hey,

          Ich habe es jetzt genauso gemacht wie du es gesagt hast.

          $start = min(3, $pnb - $_GET[p]);
                $end = max(0, 3 - $start);
                for($c=$start; $c<$end; $c++) {
                  if($c==$_GET[p]) {
                    echo $c;
                  } else {
                    echo '<a href="?p='.$c.'">'.$c.'</a>';
                  }
                }

          Also wenn ich $start und $end in der Schleife vertausche, kann ich zumindest die nächsten 3 Seiten sehen(und natürlich die Aktuelle).

          Aber so kommen garnicht erst die Seiten, $start = 3 und $end = 0.
          Ab Seite 8 sind die Werte $start = 2 und $end = 1.

          Danke nochmal für die Hilfe, wäre super wenn ich das mit deiner Hilfe noch hinkriege ;)

          @mods
          sry aber irgendwie hab ich ausversehn auf meine nachricht geantwortet...

          1. Hi!

            Übrigens: Eingangsparameterprüfungen solltest du auch nicht vergessen. $_GET[p] kann alles mögliche und unmögliche enthalten. Damit es im gültigen Wertebereich landet, kann man wiederum mit min/max arbeiten. Nebeneffakt ist, dass es nun auch garantiert eine Zahl ist, zur Not 0.

            $p = max(0, min($pnb, $_GET['p'])); // 0 <= $_GET['p'] <= $pnb

            Da du nicht darauf eingegangen bist, nehme ich mal an, dass du von 0 zu zählen beginnst, schon weil es einfacher zu rechnen ist.
            Und: p soll ein String sein und keine Konstante, also notiere ihn lieber wie einen String in Anführungszeichen.

            Ich habe es jetzt genauso gemacht wie du es gesagt hast.

            Nö, nicht ganz.

            $start = min(3, $pnb - $_GET[p]);

            Damit rechnest du erst die Differenz zum rechten Rand aus. Der Korrekturwert für die linke Seite ergibt sich erst aus 3 minus der Differenz. Zusammen mit dem rechten Korrekturwert wäre das:

            $korrektur_links = 3 - min(3, $pnb - $p);  
            $korrektur_rechts = max(0, 3 - $p);
            

            Die Korrekturwerte sind jeweils zu den 3 nach links und rechts dazuzurechnen. Dann erst hast du den Anfangs- und Endwert beim Blättern.

            Nun kann es noch den Fall von weniger als 7 Seiten geben, bei dem die aktuelle sich so in einer mittleren Position befindet, dass inklusive der Korrkturwerte am Ende die Seiten von kleiner als 0 bis größer als $pnb gehen. Dieses Problem lässt sich lösen, indem du mit dem min/max-Trick den linken und rechten Rand wieder einfängst.

            Lo!

      2. Ich habe es jetzt genauso gemacht wie du es gesagt hast.

        $start = min(3, $pnb - $_GET[p]);
              $end = max(0, 3 - $start);
              for($c=$start; $c<$end; $c++) {
                if($c==$_GET[p]) {
                  echo $c;
                } else {
                  echo '<a href="?p='.$c.'">'.$c.'</a>';
                }
              }

        Also wenn ich $start und $end in der Schleife vertausche, kann ich zumindest die nächsten 3 Seiten sehen(und natürlich die Aktuelle).

        Aber so kommen garnicht erst die Seiten, $start = 3 und $end = 0.
        Ab Seite 8 sind die Werte $start = 2 und $end = 1.

        Danke nochmal für die Hilfe, wäre super wenn ich das mit deiner Hilfe noch hinkriege ;)

  2. Moin,

    ich habe meiner Meinung nach eine extrem kompliziert Problem. Ich werke jetzt schon ein paar Stunden daran und es ist bisher nicht wirklich was rausgekommen.

    Wenns Dir nix ausmacht, gehe ich mal nicht auf Deinen Ansatz ein (das hat ja dedlfix schon gemacht, danke) sondern poste hier mal einen völlig anderen Ansatz (der zu überlegen wäre und den ich gar nicht mal so schlecht finde):

    Speichere die Daten bereits in der DB "seitenweise". Das kann innerhalb einer Tabelle erfolgen mit einem extra Feld für die Seitennummer. Oder ne extra Tabelle die dann ge-joint wird.

    Viele Grüße,
    Horst Pfiffikuss

    --
    In die BNN von heute wird morgen der Fisch eingewickelt.
    1. Hi!

      Speichere die Daten bereits in der DB "seitenweise". Das kann innerhalb einer Tabelle erfolgen mit einem extra Feld für die Seitennummer. Oder ne extra Tabelle die dann ge-joint wird.

      Das ist unrealistisch, wenn die Daten unterschiedlich sortiert oder gefiltert ausgegeben werden sollen, und aufwendig neu zu berechnen, wenn Daten hinzukommen oder entfallen. Außerdem löst das mitnichten die Pager-Problematik.

      Lo!

      1. hi,

        Das ist unrealistisch, wenn die Daten unterschiedlich sortiert oder gefiltert ausgegeben werden sollen, und aufwendig neu zu berechnen, wenn Daten hinzukommen oder entfallen. Außerdem löst das mitnichten die Pager-Problematik.

        Mein Gästebuch ist durchaus sehr realistisch und das funktioniert einwandfrei auf diese Art und Weise. Und ja, es löst die Pager-Problematik bereits beim Einfügen der Daten.

        Hotte

        1. Hi!

          Mein Gästebuch ist durchaus sehr realistisch und das funktioniert einwandfrei auf diese Art und Weise. Und ja, es löst die Pager-Problematik bereits beim Einfügen der Daten.

          Du gestattest sicher, dass ich immer noch zweifle. Du hast also eine Reihe Datensätze, zu denen eine Seitennummer gespeichert ist.

          1         2
          123456789012345678901234567

          111222333444555666777888999

          Drei Einträg pro Seite, als Beispiel. Gemäß der Ausgabenstellung des OP gibst du Seite 7 aus und willst, weil der Pager rechts von Seite 7 nur zwei Seiten stehen haben kann links eine mehr haben, also nicht wie üblich 4-6 sondern 3-6. Um also zu berechnen, dass Seite 3-6, 7 und 8-9 ausgegeben werden sollen hilft dir jetzt die Seitenzahl in der Datenbank auf welche Weise?

          Lo!

          1. hi,

            Gemäß der Ausgabenstellung des OP ...

            hatte ich einen alternativen _Ansatz_ vorgeschlagen. Das Paging-Problem löse ich bereits beim Erheben der Daten und nicht erst bei der Darstellung.

            Viele Grüße,
            Horst Haselhuhn

            --
            Am Ende machen s alle sowieso wie hotti.
            1. Hi!

              hatte ich einen alternativen _Ansatz_ vorgeschlagen. Das Paging-Problem löse ich bereits beim Erheben der Daten und nicht erst bei der Darstellung.

              Ja dann erzähl doch endlich mal, wie genau das realisiert ist. Bisher konnte ich aus deinen Andeutungen nicht schließen, wie du die Seiten-Links schon beim Einfügen so erstellen willst, das sie unter anderem auch für die spätere tatsächliche Seitenanzahl stimmen.

              Lo!

              1. hatte ich einen alternativen _Ansatz_ vorgeschlagen. Das Paging-Problem löse ich bereits beim Erheben der Daten und nicht erst bei der Darstellung.
                Ja dann erzähl doch endlich mal, wie genau das realisiert ist.

                Mich würde das auch sehr interessieren. Los Hotte! Vielleicht wird es ja lehrreich....

        2. Hi,

          Mein Gästebuch ist durchaus sehr realistisch und das funktioniert einwandfrei auf diese Art und Weise. Und ja, es löst die Pager-Problematik bereits beim Einfügen der Daten.

          Wie denn?

          Legt es nach x Einträgen eine neue aktuelleste Seite an, auf der dann nur der erste neue Eintrag steht?
          Das wäre bei der Chronologie, in der Gästebücher üblicherweise dargestellt werden, alles andere als eine Lösung - das wäre schon im Konzept verpfuscht.

          Oder zeigt es immer die x neusten Einträge auf der Startseite des Gästebuchs an, und schreibt bei jedem neuen Eintrag die Start- und alle Folgeseiten neu? Das wäre immer noch Kokolores.

          MfG ChrisB

          --
          “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
          1. Hi,

            Mein Gästebuch ist durchaus sehr realistisch und das funktioniert einwandfrei auf diese Art und Weise. Und ja, es löst die Pager-Problematik bereits beim Einfügen der Daten.

            Wie denn?

            Wie ichs geschrieben habe. Die Aufteilung in Einzelseiten erfolgt bei der Erhebung der Daten und nicht erst bei der Darstellung und schon gar nicht zur Laufzeit und erst recht nicht mit Rewrite.

            Genauso wie bei allen anderen Seiten auch. Die sind fixt und fertig und einsortiert bevor überhaupt der erste Request kommt.

            Viele Grüße,
            Horst

            1. Hi,

              Wie ichs geschrieben habe. Die Aufteilung in Einzelseiten erfolgt bei der Erhebung der Daten und nicht erst bei der Darstellung

              Dann können sie also nicht der erwähnten, vom Benutzer als Standard erwarteten chronologischen Präsentationsfolge dienen, bzw. wenn dann nur mit dem anderen erwähnten Nachteil.

              MfG ChrisB

              --
              “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]