Gedanke Nachrichtenfuntktion

  • Hey zusammen,


    ich habe vor eine Nachrichtenfunction zu erstellen.


    Nun hat jeder User die Möglichkeit auch 1ne Nachricht an mehrere User zu senden.

    Es wird ein Formular erstellt und Checkboxen für jeden User. Die userId ist dann die Value der Checkbox.

    Die SenderId erhalte ich dann über die Session.


    Mein Tabellen Aufbau habe ich mir so gedacht:

    messageId (INT)
    senderId (INT) empfaengerId (INT)


    Nun gehen wir es mal durch:


    Wenn der User an einem anderen User eine Nachricht sendet sieht die Tabelle so aus. Stellt mich vor keine Probleme.

    messageId (INT) senderId (INT) empfaengerId (INT)
    1 1 2


    Wenn der User nun an mehrer User eine Nachricht sendet, habe ich geplant, dass die Tabelle so aussieht:

    messageId (INT) senderId (INT) empfaengerId (INT)
    1 1 2,3,4,5,6,7



    Nun stell ich mir die Frage wie ich denn die ID's in der Spalte empfaengerId weiterverarbeiten soll.

    Ich habe mir überlegt alle auszulesen und dann mittels explode am Komma zu trennen.


    Dann würde es wie folgt ausssehen:

    Nun dachte ich mir mittels einer for-schleife durch das Array $userId zu iterieren und dann jedem User die Nachricht zu senden.


    Beispiel:

    PHP
    1. for($i = 0; $i < count($userId); $i++){
    2. // $userId[$i] ist in jedem Durchgang ein String
    3. sendMessage($userId[$i]);
    4. }

    $userId[$i] ist dann die Zahl und es wird für so viele Keys im Array die Function sendMessage aufgerufen. Das heißt für jeden User an dem die Nachricht gesendet wurde.


    Wird es dann nicht bei einer großer Auswahl zu langsam?

    Habt ihr Verbesserungsvorschläge?

    Kann man es weiter optimieren?


    Freue mich sehr auf eure Antworten.


    Grüße,

    Stef

  • messageId (INT) senderId (INT) empfaengerId (INT)
    1 1 2
    1 1 3
    1 1 4
    1 1 5
    1 1 6
    1 1 7


    Eine Message hat einen Absender (1:1).

    Eine Message hat n Empfänger (1:n).


    Für jeden Empfänger gibt es einen Eintrag.


    Code
    1. // pseudo code
    2. message = "Hallo, ..."
    3. senderId = user[id] // absender / eingeloggte user
    4. receiverIds = $_POST[receiver_id] // checkbox array (<input type="checkbox" name="receiver_id[]" />)
    5. foreach recceiverIds as receiverId
    6.     INSERT INTO tbl SET ...


    :)

  • Hey,


    vielen Dank cottton :)


    Ich bin wirklich froh, das dieses Forum so jemanden hat wie dich cottton !


    Ich habe mir gestern Abend nach dem Posten noch Gedanken darüber gemacht und stieß dann auf das Problem, wie ich wenn alle Ids in einer Zeile stehen, die Ausgabe erstellen für jeden User soll. Da merkte ich schon, dass meine vorige Idee doch nicht machbar und gut ist. Dein Vorschlag ist super. :)


    Grüße,

    Stef

  • Mir fällt da noch was ein.

    Du solltest alle INSERTs über eine TRANSACTION in die db schieben.

    Denn entweder alle Empfänger werden eingetragen, oder keiner.


    An sich eigtl alles, was die Message betrifft - auch die Message selbst.

  • Zitat

    Du solltest alle INSERTs über eine TRANSACTION in die db schieben.

    Warum über eine Transaction ?


    Führt man Transaktionen nicht nur bei Geldgeschäften durch?

  • Aso. 😅


    Ich dachte immer das die Transaktion in PDO nur bei Geldgeschäften verwendet wird. Wieder was dazu gelernt.


    Transaktionen benutzt man um mehrere Querys aufeinmal auszuführen. Dies hat dann eine höhere Effizienz. Stimmt das so?


    Gruß,

    Stef

  • Kann man, glaube ich, grob so sagen.


    Habe selber noch nie damit gearbeitet. Cotton wird da sicher mehr zu sagen können.


    Bin lediglich mal darauf gestoßen und wusste dementsprechend, dass es zumindest nichts mit Geldgeschäften zu tun hat. :D

  • Transaktionssicherheit. Dabei geht es nicht um Geschwindigkeit.

    Du stellst damit sicher, dass alle Queries wirklich durchgingen.


    Bsp.:

    Du willst mit der ersten Query eien User anlegen.

    Mit der zweiten Query in eine andere Tabelle seine Daten speichern.

    Ohne Transaction:

    Per Transaction stellst Du sicher, dass alles, oder nichts gespeichert wird:

    PHP (PDO) spielt hier eher eine Mittelsman Rolle.

    Du kannst Dir das so vorstellen, dass:

    - startTransaction: PHP sendet den MySQL Befehl "START TRANSACTION" and den MySQL Server

    - PHP sendet erste Query an den MySQL Server (der Server notiert sich das, die Daten sind aber noch nicht live)

    - PHP sendet zweite Query an den MySQL Server (der Server notiert sich das, die Daten sind aber noch nicht live)

    - commit: PHP sendet den MySQL Befehl "COMMIT" an den MySQL Server (der Server schließt die Transaktion ab und die Daten sind live)

    order

    - rollback: PHP sendet den MySQL Befehl "ROLLBACK" an den MySQL Server (der Server verwirft alle notierte Änderungen. Nichts wurde an den Daten geändert).


    https://dev.mysql.com/doc/refman/8.0/en/commit.html


    Wichtig zu wissen ist: startest Du eine Transaktion und sendest nie ein COMMIT, dann verwirft der MySQL Server alle Änderungen.

    Und das ist gut. Denn es könnte ja zB sein, dass das Script abgekackt ist (zB Fatal Error).


    Das kannst Du austesten:

    - erstelle einfaches Script

    - starte die Transaktion

    - update irgendwas (oder insert, ...)

    - lasse das Script beenden (die; oder exit;)

    Es wird nichts an den Daten geändert worden sein.

  • Und GANZ wichtig zu wissen: Transactions funktionieren NUR bei Engines, die Transactions unterstützen. Beim Erstellen von Tabellen, die Transactions unterstützen sollen, MUSS also InnoDB gewählt werden, denn MyISAM unterstützen KEINE Transactions.


    Und vielleicht auch interessant: Beim SELECT muss ein FOR UPDATE oder FOR SHARE angehängt werden, wenn die Tabelle innerhalb der Transaction geändert werden soll:

    Zitat

    If you query data and then insert or update related data within the same transaction, the regular SELECT statement does not give enough protection. Other transactions can update or delete the same rows you just queried.