Dynamische Userzahlen

  • Hey,


    ich habe das komplette Layout von meiner Userverwaltung geändert.


    Ich habe jetzt für jeden User eine eigene Reihe. Pro Seite werden aus der Datenbank nur 5 User gezogen.

    Gibt es mehr als 5 User kann man auf diese über die Pagination zugreifen. Es wird auf jeder Page angezeigt wie viel User von allenUsern nun gezeigt worden sind.


    Da habe ich Schwierigkeiten.


    Habe jetzt bestimmt schon 45 Minuten herumgetestet und nachgedacht.


    Ich habe mir folgenden Programmablauf gedacht:


    Ich erfasse die ganzen Keys von den Paginationseiten mittels count() und die Seite, auf der ich aktuell bin, über GET.

    Nun führe ich eine for-schleife aus indem ich die for schleife so oft neu durchgehe, bis die ganze Anzahl der Keys, von den Paginationseiten, erreicht ist.

    Währenddessen erstelle ich eine Variable welche bei jedem Durchlauf sich um 5 erhöht.


    Somit ist auf jeder Seite folgendes gegeben:

    • Seite 1 = 5
    • Seite 2 = 10
    • Seite 3 = 15
    • usw..


    Und dann überprüfe ich ob die Variable users, welche hochgezählt wird, kleiner als diese Variable ist. Die Variable users wird in einer while-schleife hochgezählt.

    Das ist mein Code:

    Bei var_dump kommt immer die Anzahla aller User raus. Was ich nicht verstehen kann.

    int(1) int(2) int(3) int(4) int(5) int(6) int(7) int(8) int(9) int(10) int(11) int(12) int(13) int(14) int(15) int(16) int(17) int(18) int(19) int(20) int(21)


    Ich weiß grad ehrlich gesagt nicht woran das liegt. Hoffe ihr könnt mir helfen.


    Grüße,

    Stef

  • Edit:


    Ich habe es jetzt fast lösen können.



    Habe nurnoch ein Punk wo ich nicht hinbekomme.


    Wenn es nur 21 Users gibt wird trotzdem 25 angezeigt. Das ist selbsterklärend weil wenn $useranzeige = 20 ist ist diese Variable ja nicht kleiner als $records und somit wird 20 nochmal mit 5 addiert.


    Wie kann ich es denn machen, dass es individuell zur Useranzahl hochgezählt wird?


    Edit:


    Habe eben als Test auch User gelöscht. Da besteht das gleiche Problem.


    Grüße,

    Stef

  • Verstehe das Problem gerade gar nicht.

    Aber ich glaube, Du machst es Dir zu kompliziert.


    Wenn ich Dich richtig verstehe, willst Du die eigentliche Pagonation bauen.


    Das Grundprinzip ist eigtl ganz einfach:

  • Hey,


    Wenn man das ganze mit den Userzahlen dynamisch erstellt dann kann man das so machen. Ist sogar besser.


    Aber wenn ich statisch immer nach jeder Überprüfung um 5 hochzähle bringt das nichts.


    Das Ziel ist, das es dynamisch ist und sich nach jedem User hinzufügen und löschen anpasst.


    Daran scheitere ich in Moment.


    cottton :


    Vielen Dank für deine Antwort und das kleine Tutorial wie man am besten eine Pagination erstellt. Ich werde dieses mir morgen noch genauer anschauen.


    Diese Pagination ist bereits vorhaden.

    Ich lasse zu jeder Seite anzeigen wie viel User nun angeschaut worden sind von der Anzahl der vorhandenen.


    Also z.b. Seite 1 : 5 von 18 User, Seite 2 : 10 von 18 User, Seite 3: 15 von 18 User, Seite 4 18 von 18 User.


    Daran scheitert es weil ich nicht weis wie man das dynamisch erstellt, somit die erste Zahl sich immer anpasst. Die 2 te Zahl habe ich bereits definiert und diese beinhaltet die Anzahl der ganzen User.


    Hoffe , dass du mein Problem jetzt besser nachvollziehen kannst.


    Grüse,

    Stef

  • Guten Morgen.


    cottton :


    Ich habe mir nochmal dein Codebeispiel angeschaut und bin es durchgegangen. Währenddessen ist mir au fgefallen, das dein Code einen Fehler bei der DB-Abfrage hat. Wenn ich die DB-Abfrage so erstelle wie du, bekomme ich erst ab Page 2 Ergebnisse. Page 1 ist leer. Ich habe jetzt zuerst das offset und dann das Limit gesetzt und es zeigt nun auf jeder Page alle Ergebnisse an.


    PHP
    $selectUsers = $dbv->prepare("SELECT userId, username, avatar, rang FROM users LIMIT :offset, :start");


    Nun habe ich mir nochmals gedanken gemacht wie ich die Anzeige " Userzahl von Userzahl Usern" dynamisch erstellen kann und kam auf die Idee den $key welchen ich bereits verwende für die Nummerierung der User für dies zu verwenden. Dies funktioniert auch solange man User hinzufügt und löscht bis eine Page leer ist.


    Das ist der Code dazu:


    Beispiel:

    Ich bin auf manageUsers.php?page=3. Habe dort noch 1 User stehen. Somit ist die Anzeige " 11 User von 11 User". Nun wenn ich diesen 1nen User lösche bleibe ich trotzdem in der Url auf manageUsers.php?page=3 und im browser direkt wird mir aber die Page 2 mit deren Werten angezeigt. Somit steht nun bei der Anzeige : "15 User von 10 User". Wenn ich nun über die Pagination Page 2 anklicke wird wieder alles so wie gewollt angezeigt : 10 User von 10 User.


    Frage:

    Wie erreiche ich es, dass wenn eine Page leer ist, automatisch in der Url auf die darunterliegende Page weitergeleitet zu werden, bzw. das sich die Url dann automatisch anpasst?


    Grüße,

    Stef

  • Zitat

    Ich habe mir nochmal dein Codebeispiel angeschaut und bin es durchgegangen. Währenddessen ist mir au fgefallen, das dein Code einen Fehler bei der DB-Abfrage hat. Wenn ich die DB-Abfrage so erstelle wie du, bekomme ich erst ab Page 2 Ergebnisse. Page 1 ist leer. Ich habe jetzt zuerst das offset und dann das Limit gesetzt und es zeigt nun auf jeder Page alle Ergebnisse an.

    Dann verwendest Du aber die Begriffe falsch. Bei LIMIT wird als ersten Parameter der 0-basierte Index angegeben und dann der Offset:

    Code
    // gibt Datensätze von 6 ( start-index: 5 ) bis 8 ( offset: 3, 6 wird berücksichtigt, daher nur bis 8, insgesamt drei Datensätze )
    select * from table limit 5,3

    Ich würde mir in der Query evtl. sogar den Startindex und das Offset mit zurückgeben lassen.

    Dann habe ich das immer zur Verfügung. Muss man aber nicht so machen.

  • Hey,


    ich verstehe es gerade nicht. wie kann den bei limit 5, 3 was gezogen werden ? 5 ist doch größer?


    Dies ist mein Code welcher die Pagination erstellt:


    Ne weiter frage habe ich auch noch.


    Und zwar wenn ich anstatt bindParam, execute() verwende und da den Platzhaltern mitgebe bekomme ich immer eine SQL Error, dass in diesem Prepare-Statement ein Fehler ist, obwohl beide Variablen keine Strings sind.


    Warum ist das so?


    Und bei der x von x Usern Anzeige kam ich bis jetzt nicht weiter.

  • Die Syntax lautet:

    Zitat

    SELECT column1, column2 from table1 LIMIT <index>, <offset>

    <index> gibt den Startwert an

    <offset> gibt die Anzahl an Datensätzen an, beginnend ab <index>


    Der index muß damit nicht zwingend kleiner sein als der offset.

  • Was Arne Drews sagt und -



    EDIT: hab hier Mist über LIMIT geschrieben :D nicht beachten - werd ich asap ändern.



    SELECT ... WHERE ... LIMIT 1;

    wird nur einen Datensatz ausgeben.


    Der 2te Parameter nach dem Komma ist dass OFFSET.

    SELECT ... WHERE ... LIMIT 1, 5;

    Gib mir eine row und skippe die ersten 5.


    SELECT ... WHERE ... ORDER BY `id` DESC LIMIT 1;

    Gib mir eine row, sortiert bei id DESC. Bei Einträgen mit ids 1, 2, 3, 4 und 5 wird die 5te row ausgegeben.


    SELECT ... WHERE ... ORDER BY `id` DESC LIMIT 1, 2;

    Gib mir eine row, skipped die ersten 2, sortiert bei id DESC. Bei Einträgen mit ids 1, 2, 3, 4 und 5 wird die 4te row ausgegeben.


    Platzhalter

    Über bindParam() kannst Du angeben, als was die Value in die Query eingefügt werden soll.

    Du könntest per bindParam() einen String ("5") übergeben - der wird dann aber als Integer eingefügt.


    Ohne bindParam() - also die Parameter per execute übergeben - werden die Values default immer als String in die Query eingefügt.

    Gibst Du also ein array('limit' => 5) als integer rein, wird trotzdem (default) ein String eingefügt.


    Stell Dir die Query als Template vor (hier ganz gut beschrieben: http://php.net/manual/de/pdo.prepared-statements.php).

    Du gibtst an, dass :hier eine Value eingefügt werden soll - im Bsp "Foo".

    Per PHP übergibst Du die Value für :hier an execute().


    Jetzt kommt PHP daher und ersetzt den Platzhalter :hier mit der Value "Foo".

    Dabei Nimmt er den String

    SELECT * FROM tbl WHERE col = :hier

    und setzt an die Stelle :hier den String 'Foo' (inclusive der ' einfachen Anführungszeichen)

    SELECT * FROM tbl WHERE col = 'Foo'


    Per bindParam() können wir aber sagen: ich will, dass Du die Value als Integer einfügst.

    Dann bekommt die Value keine Anführungszeichen, weil ... naja, Integer halt :) .


    Das einfügen der Values kann PHP (Treiber http://php.net/manual/de/pdo.drivers.php) oder auch der MySQL Server übernehmen (Siehe MySQL Prepared Statements.).

    Bei PHP erledigt das der Treiber. Also wird intern die Query prepared und dann an den MySQL Server geschickt.

    Man kann das, glaub ich mal gelesen zu haben, auch umstellen, dass man das den MySQL Server erledigen lässt.

    Aber das ist sehr weit weg vom Thema :)


    Du kannst beides mixen - bindParam() und zusätzlich Parameter per execute() übergeben.

    Wichtig ist bindParam() immer dann, wenn Du nur einen bestimmten Typ (String, Integer, ...) übergeben soltlest.

    Und das ist der Knackpunkt bei LIMIT, denn das akzeptiert nur ganze Zahlen ohne Anführungszeichen.

    SELECT ... FROM ... LIMIT '1', '5'; ist nicht valid.



    Zu Deinem Script: ich glaub ich weiß jetzt, was Du willst.

    Du willst die Links

    << Previous [1][2][3][4][5] Next >>

    darstellen. Das aber dynamisch, damit sowas nicht passiert:

    << Previous [1][2][3][4][5][6][7][8][9][10][12][13][14][15]... Next >>

    sondern:

    << Previous [5][6][7][8][9] Next >>


    Das hab ich gerade mal versucht - bekomm ich gerade net hin :D

    Ist zu lange her.

  • Zitat

    Der 2te Parameter nach dem Komma ist dass OFFSET.

    SELECT ... WHERE ... LIMIT 1, 5;


    Gib mir eine row und skippe die ersten 5.

    Kannst Du das etwas genauer erklären, wie Du das "skippen" meinst cottton? Klingt für mich falsch, aber es mag sein, dass Du es anders meinst, als ich es lese.

  • Guten Morgen,


    Arne Drews $ cottton :


    Vielen Dank für eure sehr gute Hilfe und Mühe. :)


    Okay. Wenn ich es nach der Syntax erstelle und die Werte so eintrage wird trotzdem nichts Ausgegeben.


    Wenn ich OFFSET in die SQL-Query Eingebe verfärbt sich das aber nicht Rot. Und es kommt zum Fehler.


    Dies ist der Codeteil vom Limit und Offset:

    Beispiel:


    Wir sind auf Seite 1. Also wird dem Offset der Wert null zugewiesen, denn (1 -1) * 5 = 0. Somit steht in der SQL-Query drin:

    Select columns FROM users LIMIT 5, 0 . Da wird nichts aus der DB gezogen. Nun gehen wir auf Seite 2. Da lautet die Rechnung (2 - 1) * 5. Da kommt dann 5 raus. Das heißt es werden ab dem startIndex 5, 5 columns aus der DB gezogen. Nun gehen wir auf Seite 3. Rechnung : (3 - 1) * 5 = 10. Nun werden von startIndex 5, 10 Columns aus der DB gezogen. Und so weiter....


    Seite 1 bekommt somit keine Resultate zurück Weil der Offset 0 ist. Deswegen bekommt erst Seite 2 die Daten aus der Datenbank.

    Da liegt irgendwo dann ein Fehler vor. Aber wenn bei Seite 3 vom startIndex 5, 10 Reihen gefetcht werden sollte man doch 10 Ausgaben haben?


    Zitat

    Ohne bindParam() - also die Parameter per execute übergeben - werden die Values default immer als String in die Query eingefügt.

    Gibst Du also ein array('limit' => 5) als integer rein, wird trotzdem (default) ein String eingefügt.

    Aso okay. Darum funktioniert das nicht. Jetzt wird es mir verständlich warum es nicht funktioniert.


    Nein. Da hast du mich falsch verstanden. Das ist mir nicht so wichtig. Es geht um die Anzeige wie viel User von so viel Usern angezeigt wurden.


    Beispiel:

    Page 1: 5 von 18 User

    Page 2: 10 von 18 User

    Page 3: 15 von 18 User

    Page 4: 18 von 18 User.


    Diese Anzeige funktioniert solange man beim löschen keine ganze Page "löscht". Das heißt wenn man auf Page 4 nun alle 3 User löscht kommt man automatisch auf Page 3 weil Page 4 leer ist. Auf Page 3 sind aber nur 15 von 15 User. In der Url steht trotz automatischen Wechsel auf Page 3 noch als Parameter page=4 drin. Somit ist die Anzeige nicht 15 von 15 User sondern 20 von 15 User. Nun wenn ich über die Pagination auf Seite 3 klicke wird wieder alles normal dargestellt.

    Wie erreiche ich es, dass wenn Page 4 leer ist und dann automatisch man auf Page 3 kommt dies auch in der Url beim Parameter angepasst wird.

    Damit meine ich wenn eine Seite leer ist, dass dann in der Url man auf die darunterliegende Seite, in diesem Fall Seite 3, geleitet wird, sodass diese Ungereimtheiten bei der Anzeige x von x User nicht vorkommen.


    Hier ist die Live Demonstration:
    Link: http://stef97.bplaced.net/admin/php/manageUser.php


    Wenn du den User basti1012 auf der Page 2, der Pagination löschst, wird dir die Page 1 Angezeigt, aber in der Url steht immernoch ?page=2 drin.


    basti1012 & Co :

    Wenn es euch was ausmacht, dass ich eure Namen da zum testen erstelle dann sagt es mir bitte.



    Grüße,

    Stef

  • Wenn es euch was ausmacht, dass ich eure Namen da zum testen erstelle dann sagt es mir bitte.

    Nee ,kannst du ruhig nehmen.

    Aber ich muß sagen das mir das Layout deiner Tabelle gefällt.

    Gegenüber meinen bunten kram bist du ein Weltmeister.

    Hast du das Layout im Kopf,oder holst du dir irgendwo anregungen ? ,weil ich muß mir mal so langsam für meine ganze Page ein Layout erstellen was die Besucher nicht gleich abschreckt

  • basti1012 :


    Okay alles klar.


    Zitat

    Aber ich muß sagen das mir das Layout deiner Tabelle gefällt.

    Gegenüber meinen bunten kram bist du ein Weltmeister.

    Haha ^^ Danke ;)



    Das ist keine Tabelle. Das sind mehrere div-blöcke welche im Bootstrap Grid-System eine feste Spaltenanzahl erhalten haben


    Zitat

    Hast du das Layout im Kopf,oder holst du dir irgendwo anregungen ? ,weil ich muß mir mal so langsam für meine ganze Page ein Layout erstellen was die Besucher nicht gleich abschreckt

    Dieses Layout hatte ich nicht im Kopf. Ich habe dieses im Internet gesehen und dachte mir einfach, dass dies als Userverwaltung super aussieht und für jeden gut bedienbar. Dies ist aufjedenfall besser als das vorige Layout und hat mehr Funktionen zu bieten.


    Dieses Layout habe ich von dieser Seite: https://www.tutorialrepublic.c…ser-management-data-table

  • Das ist keine Tabelle. Das sind mehrere div-blöcke welche im Bootstrap Grid-System eine feste Spaltenanzahl erhalten haben

    Auch gut ,ich hatte nicht im Quelltext geschaut.

    Aber wie auch immer ,finde es gut weil wie du auch schon sagtest ist einfach zu bedienen und ist Benutzerfreundlich.

    Da werde ich mir mal eine Scheibe von abschneiden und mal Schaun ob ich meine Wortsuch Tabelle Optisch irgendwie so in der art auch hinbekomme.

    Vieleicht gibt es hir irgendwo einen Webdesigner der mal Tips hätte wie man an besten vorgeht in Sachen Design und Funktionalität.

    Googel schmeißt zwar ein paar Tips raus,aber ich als Layout versager komme damit nicht sehr weit.

    Nagut ,wir sind von Thema abgekommen.

    Also break und return to post 13

  • Ich würde die Werte gefühlt nicht über :start und :offset per bindParam übergeben, sondern einfach konkatenieren ersetzen.

    In solchen Fällen arbeite ich auch gerne mit "Schablonen":

    PHP
    <?php
    const QUERY_USERS = "SELECT `userId`, `username`, `avatar`, `rang` FROM `users` LIMIT {{INDEX}}, {{OFFSET}}";
    // ... some code
    $oStmntUsers = $dbv->prepare(
            strtr( QUERY_USERS )
            , [
                '{{INDEX}}' => $start,
                '{{OFFSET}}' => $offset        ]
            ]
        );

    Ist aber nur die von mir bevorzugte Variante, musst Du nicht so machen.

    bindParam u.a. nutze ich eigentlich nur innerhalb der WHERE-Klausel oder bei INSERTs und UPDATEs

    Einmal editiert, zuletzt von Arne Drews () aus folgendem Grund: Wort ersetzt, Code-Definition angepasst

  • Hey,


    Okay. Diese Methode, der Query die Parameter mitzugeben, sehe ich das erste mal.


    Zitat


    Ich würde die Werte gefühlt nicht über :start und :offset per bindParam übergeben

    Warum denn nicht? Was spricht gegen bindParam in diesem Fall?


    Ich habe mir nochmal Gedanken übder die Useranzeige gemacht.


    Mein jetziger Scriptablauf, der in den richtigen Weg geht nach meiner Ansicht nach ist so:

    Ich füge dem Array links die Paginationlinks zu. Für jeden Link, also 1, 2, 3, wird im Array ein neuer Key hinzugefügt.

    Nun wenn ich auf Seite 3 bin. Und den letzten User lösche, werde ich in der foreach-schleife Überprüfen ob der GET-Parameter page, welcher in der Variable $page abgespeichert wurde, größer als die Anzahl der Keys im Array links sind. Denn wenn ja auf der 3ten seite der letzte User gelöscht wird hat man nurnoch 2 Paginationslinks. Und im if-else Statement wird dann wenn dies der Fall ist von der Variable $page 1 abgezogen. Somit ist man auf der aktuellen Page. Und der Key wird mit 0 addiert. Darüberhinaus überprüfe ich ob die Page gleich 1 ist. Wenn dies der Fall ist sollen ja die 5 nicht mit dem Key addiert werden. Wenn Page ungleich 1 ist wird der Key mit 5 addiert.


    Nun habe ich aber da auch ein Problem. Es werden dann auf "Page 2" die Userdaten von Page 1 angezeigt, was ich ehrlich gesagt nicht verstehe.

    Denn in $page stehen danach 2 drin und in der Variable welche die Schlüssel des Arrays links ermittelt auch 2 (habe auf beide var_dump angewendet). Somit kann es doch nicht sein, dass die Userdaten von Page 1 angezeigt werden.


    Der Code:

  • Guten Tag alle zusammen,


    ich habe es nun hinbekommen, dass alles passt mit folgendem Script:


    Grüße,

    Stef

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!