Martin_Online: Mehrere Werte speichern

0 74

Mehrere Werte speichern

Martin_Online
  • php
  1. 0
    Der Martin
    1. 0
      Martin_Online
      1. 0
        Der Martin
        1. 0
          Martin_Online
          1. 0
            Der Martin
            1. 0
              Martin_Online
              1. 0
                Tom
                1. 0
                  Martin_Online
                  1. 0
                    rimi
                2. 0
                  molily
                  1. 1

                    Mehrere Lösungswege eines Threads zulassen

                    Tom
                    • zu diesem forum
                    1. 0
                      Martin_Online
                      1. 0
                        Tom
                        1. 0
                          Martin_Online
                          1. 0
                            Tom
                            1. 0
                              Martin_Online
                              1. 0
                                dedlfix
                                1. 0
                                  Tom
                                  1. 1
                                    dedlfix
                                    1. 0
                                      Tom
                              2. 0
                                Tom
                              3. 0
                                molily
                            2. 0
                              dedlfix
                              1. 0
                                Martin_Online
                                1. 0
                                  Tom
                                2. 0
                                  dedlfix
                              2. 0
                                Tom
                                1. 0
                                  dedlfix
                            3. 0

                              Neuer Ansatz

                              Martin_Online
                              1. 0
                                Martin_Online
                                1. 1
                                  Auge
                                  1. 0
                                    Martin_Online
                                    1. 0
                                      molily
                                      1. 0
                                        Martin_Online
                                        1. 0

                                          Nachtrag

                                          Martin_Online
                                          1. 0
                                            molily
                                          2. 1
                                            Christian Kruse
                                        2. 0
                                          molily
                          2. 0
                            molily
                            1. 0
                              Christian Kruse
                              1. 0

                                Lange nichts gehört

                                Matthias Apsel
                                • menschelei
                                1. 0
                                  Gunnar Bittersmann
                                  1. 0
                                    Christian Kruse
                                2. 0
                                  Christian Kruse
                                  1. 0
                                    molily
                                    1. 1
                                      Christian Kruse
                                      1. 1
                                        Christian Kruse
                                      2. 0
                                        molily
                                        1. 0
                                          Christian Kruse
                    2. 0

                      Das Streben nach einer angemessenen Lösung

                      molily
            2. 0
              Martin_Online
            3. 0
              Martin_Online
              1. 0
                Der Martin
                1. 0
                  Martin_Online
                  1. 0
                    dedlfix
                    1. 0
                      Martin_Online
                      1. 0
                        dedlfix
                        1. 0
                          Martin_Online
                          1. 0
                            dedlfix
                            1. 0
                              Martin_Online
                              1. 0
                                dedlfix
                                1. 0
                                  Martin_Online
                                2. 0
                                  molily
                                  1. 1
                                    dedlfix
                                    1. 0
                                      molily
                                      1. 0
                                        dedlfix
                                      2. 1
                                        Christian Kruse
  2. 0
    dedlfix
  3. 0
    molily
    1. 0
      Martin_Online
      1. 0
        molily
  4. 0
    Martin_Online
  5. 0
    hotti

Ich stehe heute mal wieder vor einem Problem wo ich einfach nicht weiter komme. Es gibt ein Bereich auf meiner Seite wo der User seine Sprache wählen kann. Es ist auch eine Mehrfachauswahl möglich. Dieses habe ich über „checkboxen“ gelöst. Diese sehen derzeit wie folgt aus:

  
<form name="form1" method="post" action="">  
  
<h1>Sprache wählen</h1>  
  
  <input type="checkbox" name="was[]" id="was">  
  <label for="was"></label>  
  Deutsch  
<br>  
  <input type="checkbox" name="was[]" id="was">  
  <label for="was"></label>  
  Holländisch  
<br>  
  <input type="checkbox" name="was[]" id="was">  
  <label for="was"></label>  
  Tschechisch  
<br>  
  <input type="checkbox" name="was[]" id="was">  
  <label for="was"></label>  
  Türkisch  
<br>  
  <input type="checkbox" name="was[]" id="was">  
  <label for="was"></label>  
  Russisch  
<br>  
<br>  
  <input type="submit" name="abschicken" id="abschicken" value="Daten eintragen">  
  
</form>  

Nun stellt sich mir die Frage, wie soll ich diese Daten in einer Datenbank speichern?

Für mich kommen zwei Optionen in Frage, ich lege eine Tabelle mit „sprachen“ an, In dieser befinden sich Spalten und zwar für jede Sprache eine. In diesem Fall wären dieses 5 Spalten. Nachteil dieser Lösung ist, wenn weitere Sprachen hinzukommen muss die Tabelle jeweils angepasst werden. Vorteil dieser Lösung ist, ich kann diese Daten ohne Probleme speichern, wieder auslesen, Updaten usw. In diesem Beispiel könnte ich dann die [] auch wieder entfernen, da jede Sprache eine eigene Spalte hat.

Überlegung zwei, ich lege eine Tabelle an mit „sprachen“ dort befinden sich drei Spalten „id, userID, Sprache“  Alle Felder die vom User angeklickt werden, werden schmerzlos untereinander in dieser Tabelle gespeichert.

Vorteil dieser Lösung wäre, ich müsste, sollte weitere Sprachen hinzukommen nichts anpassen. Nachteil dieser Lösung, ich weiß nicht wirklich wie ich diese Daten in meiner Datenbank speichern soll. Wenn ich es richtig verstanden habe, dann habe ich mit [] ein Array und muss mein INSERT in einer schleife durchlaufen, bis alle Einträge gespeichert sind (würde ich wohl noch hinbekommen).

Ganz anderes sieht es beim Update aus, wie gehe ich da vor? Lösche ich erst ALLE Einträge von diesem User, schreibe die angeklickten Felder komplett neu? Und wie sieht es beim auslesen aus, also wenn der User auf die Seite kommt und die Felder bearbeiten möchte?

Ich merke jetzt schon, hier kommen sehr viele Probleme auf mich zu oder? Wie speichert ihr solche Daten?

Ein Ansatz habe ich bei Joomla gesehen, hier werden alle Daten in EINEM Feld gespeichert mit einem , getrennt, aber ich gehe davon aus, dass dieses noch um einiges schwerer ist zu speichern, bearbeiten und löschen?

  1. Hallo,

    Ich stehe heute mal wieder vor einem Problem wo ich einfach nicht weiter komme. Es gibt ein Bereich auf meiner Seite wo der User seine Sprache wählen kann. Es ist auch eine Mehrfachauswahl möglich.

    mehrere Sprachen? Das irritiert mich und schreit nach einer genaueren Erklärung.

    Dieses habe ich über „checkboxen“ gelöst.

    Für eine mögliche Mehrfachauswahl vermutlich das Sinnvollste.

    <input type="checkbox" name="was[]" id="was">

    <label for="was"></label>
      Deutsch
    <br>
      <input type="checkbox" name="was[]" id="was">
      <label for="was"></label>
      Holländisch
    <br>
      <input type="checkbox" name="was[]" id="was">
      <label for="was"></label>
      Tschechisch
    <br>
      <input type="checkbox" name="was[]" id="was">
      <label for="was"></label>
      Türkisch
    <br>
      <input type="checkbox" name="was[]" id="was">
      <label for="was"></label>
      Russisch
    <br>

      
    Zum Markup:  
    1\. Die br-Elemente sehen da ziemlich unbeholfen aus; sinnvoller wäre hier IMO eine Liste, deren li-Elemente die Checkbox und das zugehörige Label enthalten. Die sind auch "von Haus aus" Blockelemente".  
    2\. Mehrere Elemente können nicht dieselbe ID haben - erstens schon aus Prinzip nicht, zweitens hier erst recht nicht, weil dann die Zuordnung von Label und Control nicht eindeutig ist.  
    3\. Der Text (z.B. "Deutsch") gehört als \_Inhalt\_ in das label-Element, andernfalls ist das label ja ziemlich zweckfrei.  
    4\. Sprachbezeichnungen sollten möglichst auch in der jeweiligen Sprache formuliert sein, also "Deutsch", "Français", "Nederlands" usw., zumal "Holländisch" auch sachlich nicht korrekt ist (Noord-Holland und Zuid-Holland sind Provinzen der Niederlande).  
      
    
    > Nun stellt sich mir die Frage, wie soll ich diese Daten in einer Datenbank speichern?  
      
    Da gibt's natürlich mehrere Ansätze. Mindestens.  
    Man könnte die values (die in deinem Code-Auszug übrigens fehlen) einfach mit einem geeigneten Trennzeichen (Blank, Komma) zu einem String verketten - und dafür selbstverständlich ISO-Sprachkürzel verwenden. Dann käme etwas wie "de,cs,ru" heraus.  
    Man kann ebensogut pro Sprache eine Boolean-Spalte in der DB vorsehen und deren Wert ggf. auf true setzen. Nachteil: Wenn man nachträglich eine Sprache hinzufügt, muss man die DB-Struktur umbauen.  
      
    
    > Für mich kommen zwei Optionen in Frage, ich lege eine Tabelle mit „sprachen“ an, In dieser befinden sich Spalten und zwar für jede Sprache eine. In diesem Fall wären dieses 5 Spalten. Nachteil dieser Lösung ist, wenn weitere Sprachen hinzukommen muss die Tabelle jeweils angepasst werden.  
      
    Das meinte ich.  
      
    
    > Überlegung zwei, ich lege eine Tabelle an mit „sprachen“ dort befinden sich drei Spalten „id, userID, Sprache“  Alle Felder die vom User angeklickt werden, werden schmerzlos untereinander in dieser Tabelle gespeichert.  
      
    Das könnte auch noch eine elegante Lösung sein, hängt aber davon ab, wie und wofür du die Daten verwendest.  
      
    Ciao,  
     Martin  
    
    -- 
    F: Kennt jemand einen Automobilfilm?  
    A: Der mit dem Golf tankt.  
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    
    1. Hallo,

      mehrere Sprachen? Das irritiert mich und schreit nach einer genaueren Erklärung.

      Ganz einfach. Meine User können sich ein kleines Profil anlegen, dort gibt es ein Bereich, welche sprachen Sie sprechen, viele sprechen ja nicht nur Deutsch sondern auch Englisch, Französisch usw. Dieses möchte ich damit erreichen.

      Zum Markup:

      1. Die br-Elemente sehen da ziemlich unbeholfen aus; sinnvoller wäre hier IMO eine Liste, deren li-Elemente die Checkbox und das zugehörige Label enthalten. Die sind auch "von Haus aus" Blockelemente".

      Da dieses noch nicht das endgültige Layout ist, habe ich einfach ein paar <br> genommen, da sich um diese Sachen meine Freundin kümmert :) für mich zum testen und alles vorzubereiten reichen die <br>

      1. Mehrere Elemente können nicht dieselbe ID haben - erstens schon aus Prinzip nicht, zweitens hier erst recht nicht, weil dann die Zuordnung von Label und Control nicht eindeutig ist.
      1. Der Text (z.B. "Deutsch") gehört als _Inhalt_ in das label-Element, andernfalls ist das label ja ziemlich zweckfrei.

      OK, ich hab es überarbeitet, dieses sieht nun so aus

        
              <form name="form1" method="post" action="">  
        
                <input name="was[]" type="checkbox" id="de">  
                <label for="de">Deutsch</label>  
              <br>  
                <input type="checkbox" name="was[]" id="hollaendisch">  
                <label for="hollaendisch">Holländisch</label>  
              <br>  
                <input type="checkbox" name="was[]" id="tschechisch">  
                <label for="tschechisch">Tschechisch</label>  
              <br>  
                <input type="checkbox" name="was[]" id="tuerkisch">  
                <label for="tuerkisch">Türkisch</label>  
              <br>  
                <input type="checkbox" name="was[]" id="russisch">  
                <label for="russisch">Russisch</label>  
              <br>  
              <br>  
                <input type="submit" name="abschicken" id="abschicken" value="Daten eintragen">  
        
              </form>  
      
      

      Da gibt's natürlich mehrere Ansätze. Mindestens.
      Man könnte die values (die in deinem Code-Auszug übrigens fehlen) einfach mit einem geeigneten Trennzeichen (Blank, Komma) zu einem String verketten - und dafür selbstverständlich ISO-Sprachkürzel verwenden. Dann käme etwas wie "de,cs,ru" heraus.

      OK, ich hab ein value hinzugefügt, dieses sieht nun so aus

        
              <form name="form1" method="post" action="">  
        
                <input name="was[]" type="checkbox" id="deutsch" value="Deutsch">  
                <label for="deutsch">Deutsch</label>  
              <br>  
                <input type="checkbox" name="was[]" id="hollaendisch" value="Holländisch">  
                <label for="hollaendisch">Holländisch</label>  
              <br>  
                <input type="checkbox" name="was[]" id="tschechisch" value="Tschechisch">  
                <label for="tschechisch">Tschechisch</label>  
              <br>  
                <input type="checkbox" name="was[]" id="tuerkisch" value="Türkisch">  
                <label for="tuerkisch">Türkisch</label>  
              <br>  
                <input type="checkbox" name="was[]" id="russisch" value="Russisch">  
                <label for="russisch">Russisch</label>  
              <br>  
              <br>  
                <input type="submit" name="abschicken" id="abschicken" value="Daten eintragen">  
        
              </form>  
      
      

      Die values werden später noch mit den richtigen Kürzeln geändert. Ich muss erst schauen wie dieses für die einzelnen Sprachen lauten.

      Überlegung zwei, ich lege eine Tabelle an mit „sprachen“ dort befinden sich drei Spalten „id, userID, Sprache“  Alle Felder die vom User angeklickt werden, werden schmerzlos untereinander in dieser Tabelle gespeichert.

      Welche der drei Beschriebenen Gedanken wie ich die Daten speichern soll, würdest du mir denn empfehlen bzw. mit welcher Option habe ich die später die wenigstens Probleme?

      Das könnte auch noch eine elegante Lösung sein, hängt aber davon ab, wie und wofür du die Daten verwendest.

      Wie oben bereits geschrieben der User kann sich ein eigenes Profil anlegen, dort sieht ein anderer User was für Sprachen der jeweilige User spricht. Ob ich dieses über Text oder Fahnen löse weiß ich noch nicht wirklich.

      1. Hi,

        mehrere Sprachen? Das irritiert mich und schreit nach einer genaueren Erklärung.
        Ganz einfach. Meine User können sich ein kleines Profil anlegen, dort gibt es ein Bereich, welche sprachen Sie sprechen, viele sprechen ja nicht nur Deutsch sondern auch Englisch, Französisch usw. Dieses möchte ich damit erreichen.

        verstehe, das ist ungewöhnlich, aber okay. Meist wählt man nur eine einzige Sprache aus.

        OK, ich hab ein value hinzugefügt, dieses sieht nun so aus
        [...]
        Die values werden später noch mit den richtigen Kürzeln geändert. Ich muss erst schauen wie dieses für die einzelnen Sprachen lauten.

        Deutsch: de, Englisch: en, Niederländisch: nl, Französisch: fr, Tschechisch: cs, Türkisch: tr, Russisch: ru.

        Welche der drei Beschriebenen Gedanken wie ich die Daten speichern soll, würdest du mir denn empfehlen bzw. mit welcher Option habe ich die später die wenigstens Probleme?

        Ich würd's als Aufzählung in einem einzigen String machen. Ob das die beste Lösung ist, kann ich aber noch nicht absehen.

        [...] was für Sprachen der jeweilige User spricht. Ob ich dieses über Text oder Fahnen löse weiß ich noch nicht wirklich.

        Bitte nicht mit Fahnen! Flaggen stehen für Länder; Ländergrenzen fallen aber oft nicht mit den Grenzen der Verbreitung von Sprachen zusammen (Belgien? Schweiz? Österreich? Englisch in UK, Irland, USA, Australien? Spanisch in ES und vielen südamerikanischen Ländern).

        So long,
         Martin

        --
        Ich wollt', ich wär ein Teppich.
        Dann könnte ich morgens liegenbleiben.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. verstehe, das ist ungewöhnlich, aber okay. Meist wählt man nur eine einzige Sprache aus.

          So ungewöhnlich finde ich das jetzt nicht. Wenn ich z.B. ein Bild einstelle und hoffen, dass ich Nachrichten von anderen Usern bekommen, wäre es doch schön zu wissen, welche Sprachen ich außer Deutsch noch verstehe.

          Ich würd's als Aufzählung in einem einzigen String machen. Ob das die beste Lösung ist, kann ich aber noch nicht absehen.

          Hast du für mich ein kleines Bespiel wie ich dieses speichern könnte?

          Bitte nicht mit Fahnen! Flaggen stehen für Länder; Ländergrenzen fallen aber oft nicht mit den Grenzen der Verbreitung von Sprachen zusammen (Belgien? Schweiz? Österreich? Englisch in UK, Irland, USA, Australien? Spanisch in ES und vielen südamerikanischen Ländern).

          Ok, dann verzichte ich auf die Fahnen und schreibe es als Klartext hin.

          1. Hallo,

            Ich würd's als Aufzählung in einem einzigen String machen. Ob das die beste Lösung ist, kann ich aber noch nicht absehen.
            Hast du für mich ein kleines Bespiel wie ich dieses speichern könnte?

            gehen wir mal von dieser Auswahl an Optionen aus:

            <input type="checkbox" name="lang[]" value="de">  
            <input type="checkbox" name="lang[]" value="en">  
            <input type="checkbox" name="lang[]" value="ru">  
            <input type="checkbox" name="lang[]" value="da">  
            <input type="checkbox" name="lang[]" value="es">
            

            In PHP bekommst du so automatisch ein Array mit den ausgewählten Optionen. Also ist auch die Umwandlung in einen String mit einem vordefinierten Trennzeichen ein Klacks. Das macht die Funktion implode():

            lang_str = implode(',', lang);

            Entsprechend macht explode() diesen Schritt rückgängig:

            lang = explode(',', lang_str);

            Du musst eigentlich nur darauf achten, dass das Array lang[] beim Eintragen nicht fehlt - falls mal jemand gar keine Sprache ankreuzt, was nicht sehr sinnvoll wäre. Diesen Fall (erkennbar daran, dass isset(lang) false liefert) solltest du als Fehler abweisen.

            Ciao,
             Martin

            --
            There are 10 types of people in the world: Those who understand the binary system, and those who don't.
            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
            1. Du musst eigentlich nur darauf achten, dass das Array lang[] beim Eintragen nicht fehlt - falls mal jemand gar keine Sprache ankreuzt, was nicht sehr sinnvoll wäre. Diesen Fall (erkennbar daran, dass isset(lang) false liefert) solltest du als Fehler abweisen.

              Ok, hab es jetzt so umgesetzt

                
              if(isset($_POST['abschicken'])){  
                
              $lang 		= $_POST['lang'];  
              $sprache 	= implode(', ',$lang);  
                
              echo $sprache;  
                
              }  
              
              

              Wenn ich dich richtig verstanden habe, dann speichere ich den Wert $sprache in meiner Datenbank in einem Feld?

              Ich finde dieses ist die beste Lösung, so ist egal wie viele Felder der User anklickt und auch sollten später mal weitere Sprachen hinzukommen muss meine Datenbank nicht erweitert werden.

              1. Hello,

                Wenn ich dich richtig verstanden habe, dann speichere ich den Wert $sprache in meiner Datenbank in einem Feld?

                Jede Sprache in einem Datensatz ist eine saubere Lösung, aber keine schnelle und auch nicht die einzige. Außerdem ist das Konstrukt noch nicht zuende gedacht.

                Checkboxen werden im Request nur übertragen, wenn sie "checked" sind. Nun überleg Dir also noch, wie Du die Sprachdatensätze wieder rausbekommst aus der Tabelle.

                Praktischer sind da Radiogrous aus zwei Radio-Elementen pro Sprache, eines für "ja" und eines für "nein". Und weil z.B. MySQL keinen Spaltentyp Boolean kennt, kannst Du die Radios auch gleich mit den Werten "0" und "1" belegen und den Spaltentyp TINYINT benutzen.

                Dann kannst Du die passende Spalte mit "intval($radio)" beschreiben.

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                Die ultimative Seite für Selbermacher
                1. Hallo Tom,

                  jetzt verstehe ich ehrlich gesagt die Welt nicht mehr so ganz, der eine sagt so der andere sagt so.

                  OK es stimmt es mag eine saubere Lösung sein, jede Sprache in ein Feld zu speichern, aber der Aufwand wenn eine neue Sprache hinzu kommt ist doch sehr hoch. Es müssen Scripte sowie Tabellen angepasst werden.

                  Das ganze über Radiobuttons zu regeln habe ich mir auch schon überlegt, aber ich finde dieses wird einfach zu unübersichtlich bei viele Sprachen, gehen wir von 15 – 20 Sprachen aus, dann habe ich später 40 Radiobuttons auf der Seite, dieses muss wirklich nicht sein.

                  1. Hallo Tom,

                    jetzt verstehe ich ehrlich gesagt die Welt nicht mehr so ganz, der eine sagt so der andere sagt so.

                    OK es stimmt es mag eine saubere Lösung sein, jede Sprache in ein Feld zu speichern, aber der Aufwand wenn eine neue Sprache hinzu kommt ist doch sehr hoch. Es müssen Scripte sowie Tabellen angepasst werden.

                    Das ganze über Radiobuttons zu regeln habe ich mir auch schon überlegt, aber ich finde dieses wird einfach zu unübersichtlich bei viele Sprachen, gehen wir von 15 – 20 Sprachen aus, dann habe ich später 40 Radiobuttons auf der Seite, dieses muss wirklich nicht sein.

                    versuch es mal damit falls ich die Frage richtig verstanden habe
                    codesnipsel

                2. Hallo,

                  Checkboxen werden im Request nur übertragen, wenn sie "checked" sind. Nun überleg Dir also noch, wie Du die Sprachdatensätze wieder rausbekommst aus der Tabelle.

                  Praktischer sind da Radiogrous aus zwei Radio-Elementen pro Sprache, eines für "ja" und eines für "nein".

                  Radiobuttons sind nicht zwingend nötig, es gehen auch Checkboxen. Die üblichen Webframeworks generieren ein <input type="hidden" name="foo" value="0"> und ein <input type="checkbox" name="foo" value="1">, sodass auf jeden Fall ein Wert ankommt.

                  Und weil z.B. MySQL keinen Spaltentyp Boolean kennt, kannst Du die Radios auch gleich mit den Werten "0" und "1" belegen und den Spaltentyp TINYINT benutzen.

                  Dann kannst Du die passende Spalte mit "intval($radio)" beschreiben.

                  Diese Abstrakion übernehmen objektrelationale Mapper, wenn man den Typ im Datenbankschema als Boolean angibt. Dann nimmt der Setter einen Boolean entgegen (Pseudocode: objekt.feld = true) und der Getter gibt immer einen Boolean zurück (objekt.feld == true oder objekt.feld == false).

                  (Sorry, dass ich erneut darauf rumreite, aber man muss nicht das Rad neu erfinden…)

                  Mathias

                  1. Hello Matthias,

                    es ist ja wahrscheinlich gut gemeint, dass Du _mir_ hier erklärst, "wie man es macht". Aber erstens weiß ich das schon und zweitens habe ich deshalb auch nicht gefragt. Ich habe Martin nur zwei Denkansätze gegeben. Auf die Lösung mit den doppelten Checkboxen hätte er selber kommen können. Meinen Hinweis, dass eine normalisierte Lösung die sauberste ist, hat er leider noch nicht verstanden, weil ich auch nochmal erwähnt habe, dass es nicht die einzige ist.

                    (Sorry, dass ich erneut darauf rumreite, aber man muss nicht das Rad neu erfinden…)

                    Ich finde es schade, dass Du dich nicht an das Credo des Forums hältst: "Die Energie des Verstehens". Dazu gehört ein gewisses Maß an Selbermachen. Wenn Du die (eine, deine) Lösung immer schon im Voraus bekannt gibst und leider auch meistens keinerlei andere Lösungswege gelten lässt, stellt das den Sinn des Forums in Frage.

                    Ich fände es produktiver, wenn Du erst ziemlich zum Ende mit den Fertiglösungen kämst, die dann aber auch ausführlich erläutern könntest!

                    Dafür würde sich dann in hervorragender Weise das Wiki eignen. Das würde dadurch nämlich jedes Mal um eine deiner durchaus sehr wertvollen Wissensmarken wachsen.

                    Bitte sieh dieses Posting von mir als Anregung und nicht als Angriff :-)

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    Die ultimative Seite für Selbermacher
                    1. Hallo Tom,

                      Ich habe Martin nur zwei Denkansätze gegeben. Auf die Lösung mit den doppelten Checkboxen hätte er selber kommen können. Meinen Hinweis, dass eine normalisierte Lösung die sauberste ist, hat er leider noch nicht verstanden, weil ich auch nochmal erwähnt habe, dass es nicht die einzige ist.

                      was meinst du mit „normalisierte Lösung“ ich bin eigentlich auf deine Antwort eingegangen. Dazu nochmals meine Bedenken, wenn ich wirklich jede Sprache und es kommen später doch einige hinzu, dann hätte ich vermutlich ca. 40 Spalten in meiner Tabelle, wenn ich dann auch noch jeweils 2 Radio Buttons für die Auswahl (ja, nein) zulasse, dann sind es mehr als 40 Felder, findest du es nicht etwas unübersichtlich das ganze? Außerdem was ist eine „saubere“ Lösung? Ich denke wenn man diese Frage 10 Programmierern stellt, bekommst du 10 verschiedene Antworten?

                      Ich gehe mal davon aus, dass du doch einige Jahre mehr Erfahrung in diesem Bereich hast als ich, also machst du wohl viele Sachen besser bzw. einfacher. Ich muss erstmal damit klar kommen, was ich kann und wie ich es verstehe. Viele Tutorials sind leider in Englisch, ich kann zwar etwas Englisch tu mir aber immer sehr schwer, wenn z.B. in Videos sehr schnell geredet wird.

                      Auf viele Sachen gehe ich einfach nicht drauf ein, weil ich selber keine Antwort weiß oder ich es nicht ganz verstehe wie etwas gemeint ist. Jedes mal bis in kleines Detail nachzufragen möchte ich auch nicht. Ihr hab schließlich auch noch etwas anderes zu tun als mir ständig etwas zu erklären. Ich bin ja schon froh, diese Hilfe hier kostenlos zu bekommen.

                      1. Hello,

                        was meinst du mit „normalisierte Lösung“ ich bin eigentlich auf deine Antwort eingegangen.

                        http://de.wikipedia.org/wiki/Normalisierung_(Datenbank)

                        Ganz grob: gleichartige Elemente werden nicht innerhalb eines Datensatzes gespeichert, sondern es wird eine "90°-Tabelle"-angelegt. Aus den Elementen in einer Zeile (horizontal) werden also Datensätze in einer Tabelle (vertikal).

                        Dazu nochmals meine Bedenken, wenn ich wirklich jede Sprache und es kommen später doch einige hinzu, dann hätte ich vermutlich ca. 40 Spalten in meiner Tabelle, wenn ich dann auch noch jeweils 2 Radio Buttons für die Auswahl (ja, nein) zulasse, dann sind es mehr als 40 Felder, findest du es nicht etwas unübersichtlich das ganze? Außerdem was ist eine „saubere“ Lösung? Ich denke wenn man diese Frage 10 Programmierern stellt, bekommst du 10 verschiedene Antworten?

                        Eine saubere Lösung ist die normalisierte Form, also _keine_ gleichartigen Elemente innerhalb eines Datensatzes.

                        Eine Auflösung mittels einer "m:n"-Beziehung, oder wie Natthias es fremdländisch mit "many-to-many" ausdrückt, wäre also die erste Übung. Die zweite wäre, die Daten wieder zusammenzuführen. Die dritte wäre die Formulierung von Vorgaben und Rahmenbedinungen, falls erforderlich.

                        Ich gehe mal davon aus, dass du doch einige Jahre mehr Erfahrung in diesem Bereich hast als ich, also machst du wohl viele Sachen besser bzw. einfacher. Ich muss erstmal damit klar kommen, was ich kann und wie ich es verstehe. Viele Tutorials sind leider in Englisch, ich kann zwar etwas Englisch tu mir aber immer sehr schwer, wenn z.B. in Videos sehr schnell geredet wird.

                        Genau deshalb sollten wir ja auch kleine Schritte machen. Das war übrigens meine Bitte an Matthias. Du willst es ja augenscheinlich _verstehen_ und das geht nicht in einem großen Schritt.

                        Wenn Du also einverstanden bist, dann lass uns versuchen, die Aufgabe in kleinen Schritten sauber zu lösen, aber auch die (temporären) Nachteile einer solchen Lösung in der Praxis zu besprechen.

                        Auf viele Sachen gehe ich einfach nicht drauf ein, weil ich selber keine Antwort weiß oder ich es nicht ganz verstehe wie etwas gemeint ist. Jedes mal bis in kleines Detail nachzufragen möchte ich auch nicht.

                        Das kannst Du aber gerne tun. Man sieht daran dann leichter, wo man bei der Erklärung versagt hat, oder mal wieder zu vielo auf einmal wollte... :-)

                        Und wenn Du links bekommst, solltest Du denen schon erst einmal folgen und lesen, was es dort zu ergründen gibt.

                        Liebe Grüße aus dem schönen Oberharz

                        Tom vom Berg

                        --
                         ☻_
                        /▌
                        / \ Nur selber lernen macht schlau
                        Die ultimative Seite für Selbermacher
                        1. Hallo Tom,

                          Eine saubere Lösung ist die normalisierte Form, also _keine_ gleichartigen Elemente innerhalb eines Datensatzes.

                          ich verstehe es einfach nicht warum es besser sein soll, für jedes Feld eine eigene Spalte anzulegen.  Hab mir gerade alle Felder angesehen, später sind es 52 Felder Eine Tabelle mit 52 Spalten halte ich einfach für übertrieben. Warum verwenden große Systeme wie Joomla, Wordpress, Contao genau diese Vorgehensweise?

                          1. Hello Martin,

                            Eine saubere Lösung ist die normalisierte Form, also _keine_ gleichartigen Elemente innerhalb eines Datensatzes.

                            ich verstehe es einfach nicht warum es besser sein soll, für jedes Feld eine eigene Spalte anzulegen.  Hab mir gerade alle Felder angesehen, später sind es 52 Felder Eine Tabelle mit 52 Spalten halte ich einfach für übertrieben. Warum verwenden große Systeme wie Joomla, Wordpress, Contao genau diese Vorgehensweise?

                            Bringst Du jetzt nicht Spalte und Zeile durcheinander?

                            Datensatz: Zusammenstellung unterschiedlicher Daten, die einen inneren Zusammenhang haben, z.B. eine Adresse nebst Vorname, Name und Telefonnummer. Diese Daten sind einer "Person" zuordnungsfähig.

                            Der Datensatz besteht aus "Feldern", also Daten unterschiedlicher Art und Bedeutung.

                            Die gleichen Felder mehrerer Datensätze untereinander geschrieben ergeben eine Spalte.

                            Alle Spalten nebeneinander geschrieben ergeben eine Tabelle.
                            Alle Datensätze (Zeilen) untereinander geschrieben ergeben eine Tabelle.

                            Wenn man nun z.B. zu einer Person mehrere Telefonnummern hat, dann kann man die Tabelle um eine entsprechende Anzahl von Spalten erweitern. Man erhält dann t.B. Tel1, Tel2, Tel3 usw.
                            Das Dumme daran ist nur, dass dann die Felder Tel2 und Tel3 in den Datensätzen der anderen Personen erstmal leer bleiben, denn die haben in unserem Beispiel nur eine Telefonnummer.
                            Das ist also schon mal vergeudeter Speicherplatz.

                            Genauso ist es in Deiner Aufgabe mit den Sprachen.
                            Weder, alle Sprachen einer Person durch Komma (oder Plumps) getrennt in einem Feld abzulegen, ist gut, noch für jede mögliche Sprache eine eigene Spalte anzulegen. In beiden Fällen muss man dafür Speicherplatz im Datensatz bereithalten, der leer bleibt, wenn keine Daten dafür vorhanden sind. Man auch deshalb die Normalisierungsregeln ersonnen.

                            Wenn Du nun die Sprachen nicht mehr horizontal speicherst, sondern vertikal, dann sparst Du i.d.R. Platz.

                            Relationale Datenbanken sind entstanden, als Speicherplatz noch knapp war und Zugriffszeiten noch lang. Man hat daher verschiedene Dinge eingeführt:

                            Durch Datensätze mit fester Satzlänge und -Struktur und damit fester Feldlänge war der "Random Access" auf jedes Feld jedes Datensatzes möglich.

                            Datenbanken haben sich seitdem weiterentwickelt und es gibt inziwschen andere Konzepte.

                            Das würde jetzt aber wieder zu weit führen.

                            Du benutzt doch MySQL, oder?

                            Kennst Du das Tool "Heidi-SQL"? Das ist ganz praktisch, um sich so allerhand Erfahrungen im Umgang mit MySQL anzueignen.

                            http://www.heidisql.com/

                            Liebe Grüße aus dem schönen Oberharz

                            Tom vom Berg

                            --
                             ☻_
                            /▌
                            / \ Nur selber lernen macht schlau
                            Die ultimative Seite für Selbermacher
                            1. Hallo Tom,

                              Wenn Du nun die Sprachen nicht mehr horizontal speicherst, sondern vertikal, dann sparst Du i.d.R. Platz.

                              und jetzt sind wir wieder da, wo ich gestern begonnen hab. Meine Überlegung war, UserID -> Sprache einfach untereinander zu schreiben. Dann ist es egal wie viele Sprachen ein User gewählt hat.

                              Mein Problem ist aber, wenn ich dieses Vorhaben umsetzte, ich weiß nicht wie ich die Datensätze Bearbeiten kann. Sprich ein User geht in sein Profil bearbeitet seine Sprachen, klickt auf speichern, was passiert dann? Lösche ich erst ALLE Datensätze von diesem User und schreibe alle neu, was wohl die einfachste Möglichkeit ist oder prüfe ich, welcher Datensatz neu bzw. weg gefallen sind?

                              Aber auch bei Feldern wie Name, Straße, PLZ, Ort, habe ich leere Felder in meiner Datenbank, es kommt heut zu Tage doch nicht mehr auf den Speicherplatz an? Ich kann ein User nicht zwingen diese Felder auszufüllen bzw. möchte ich gar nicht. Also habe ich zwangsläufig leere Felder in meiner Tabelle.

                              Du benutzt doch MySQL, oder?

                              Ja, ich benutze für die Verwaltung einen phpMyAdmin

                              1. Tach!

                                Mein Problem ist aber, wenn ich dieses Vorhaben umsetzte, ich weiß nicht wie ich die Datensätze Bearbeiten kann. Sprich ein User geht in sein Profil bearbeitet seine Sprachen, klickt auf speichern, was passiert dann? Lösche ich erst ALLE Datensätze von diesem User und schreibe alle neu, was wohl die einfachste Möglichkeit ist oder prüfe ich, welcher Datensatz neu bzw. weg gefallen sind?

                                Diese beiden Möglichkeiten hast du. Die erste geht sehr einfach, die andere muss irgendwie die Menge der zu löschenden Datensätze ermitteln, um dann nur genau diese zu löschen. Das ist nur bei seeeehr großen Datenbeständen vorteilhafter.

                                Also habe ich zwangsläufig leere Felder in meiner Tabelle.

                                Und das ist auch kein Problem. VARCHAR-Felder verschwenden keinen Speicherplatz.

                                dedlfix.

                                1. Hello,

                                  Mein Problem ist aber, wenn ich dieses Vorhaben umsetzte, ich weiß nicht wie ich die Datensätze Bearbeiten kann. Sprich ein User geht in sein Profil bearbeitet seine Sprachen, klickt auf speichern, was passiert dann? Lösche ich erst ALLE Datensätze von diesem User und schreibe alle neu, was wohl die einfachste Möglichkeit ist oder prüfe ich, welcher Datensatz neu bzw. weg gefallen sind?

                                  Diese beiden Möglichkeiten hast du. Die erste geht sehr einfach, die andere muss irgendwie die Menge der zu löschenden Datensätze ermitteln, um dann nur genau diese zu löschen. Das ist nur bei seeeehr großen Datenbeständen vorteilhafter.

                                  Es muss nicht vorher gelsöcht werden. Es muss nur die neue Entscheidung gespeichert werden, egal, ob es nun das gesamte SET ist, das da neu aufgebaut werden muss, oder die einzeln angezeigten Detail-Datensätze.

                                  Also habe ich zwangsläufig leere Felder in meiner Tabelle.

                                  Und das ist auch kein Problem. VARCHAR-Felder verschwenden keinen Speicherplatz.

                                  Martin, den Satz überliest Du am besten erstmal. Das ist schon wieder zwei Schritte weiter...

                                  Du hattest Dich ja nun für ein n:m-Design entschieden mit drei Tabellen.

                                  Liebe Grüße aus dem schönen Oberharz

                                  Tom vom Berg

                                  --
                                   ☻_
                                  /▌
                                  / \ Nur selber lernen macht schlau
                                  Die ultimative Seite für Selbermacher
                                  1. Tach!

                                    Es muss nicht vorher gelsöcht werden. Es muss nur die neue Entscheidung gespeichert werden, egal, ob es nun das gesamte SET ist, das da neu aufgebaut werden muss, oder die einzeln angezeigten Detail-Datensätze.

                                    Wenn die neue Entscheidung ist, dass eine Sprache nicht mehr angekreuzt ist, wie speicherst du diese denn ohne zu löschen? Oder hat dein Datenmodell etwa immer alle Nutzer mal Sprache Datensätze, mit der Information ja oder nein drin? Der Ansatz mit dem Löschen jedenfalls geht davon aus, dass nur zu angekreuzten Sprachen Datensätze existieren.

                                    dedlfix.

                                    1. Hello,

                                      Es muss nicht vorher gelsöcht werden. Es muss nur die neue Entscheidung gespeichert werden, egal, ob es nun das gesamte SET ist, das da neu aufgebaut werden muss, oder die einzeln angezeigten Detail-Datensätze.

                                      Wenn die neue Entscheidung ist, dass eine Sprache nicht mehr angekreuzt ist, wie speicherst du diese denn ohne zu löschen? Oder hat dein Datenmodell etwa immer alle Nutzer mal Sprache Datensätze, mit der Information ja oder nein drin? Der Ansatz mit dem Löschen jedenfalls geht davon aus, dass nur zu angekreuzten Sprachen Datensätze existieren.

                                      Das haben wir doch noch gar nicht zuende überlegt. Die Datenphilosophie steht noch nicht fest.
                                      https://forum.selfhtml.org/?t=217687&m=1496000

                                      Die Brückentabelle kann sehr wohl Datensätze enhalten für
                                      * ON       ja
                                      * OFF      nein
                                      * NULL     weiß-nicht

                                      Wenn man jetzt das Modell mit den hidden Checkbox-Werten für die Benutzerschnittstelle benutzt, gibt es nur noch
                                      * ON       ja
                                      * OFF      nein

                                      als Antworten. Kein Datensatz würde dann bedeuten, dem User wurde diese Sprache noch nicht angeboten. Er hat noch keine Entscheidung getroffen.

                                      Da wir das Gesamtkunstwerk ja noch nicht kennen - das wird doch erst entwickelt - sollte Martin sich nicht der Möglichkeit berauben, in der Brückentabelle JA, NEIN diskret speichern zu können und ggf. sogar den Tiny-Int noch für andere Statu(u)s verwenden zu können.

                                      Könnte ja auch sein, dass er kenntlich machen will, dass einem User eine Sprache gar nicht angeboten werden darf.

                                      Liebe Grüße aus dem schönen Oberharz

                                      Tom vom Berg

                                      --
                                       ☻_
                                      /▌
                                      / \ Nur selber lernen macht schlau
                                      Die ultimative Seite für Selbermacher
                              2. Hello,

                                Mein Problem ist aber, wenn ich dieses Vorhaben umsetzte, ich weiß nicht wie ich die Datensätze Bearbeiten kann. Sprich ein User geht in sein Profil bearbeitet seine Sprachen, klickt auf speichern, was passiert dann? Lösche ich erst ALLE Datensätze von diesem User und schreibe alle neu, was wohl die einfachste Möglichkeit ist oder prüfe ich, welcher Datensatz neu bzw. weg gefallen sind?

                                Du hast drei Tabellen:

                                User                User_Sprache                 Sprache
                                ----                ------------                 -------
                                ID                  ID_USER                      ID
                                UPDATE_COUNT        ID_SPRACHE                   UPDATE_COUNT
                                ...                 UPDATE_COUNT                 ...
                                                    ON_OFF

                                Die Tabelle User_Sprache _kann eine eigene ID haben, muss sie aber nicht mehr, da Du ohnehin einen Unique Index über die Spalten ID_USER + ID_SPRACHE legen wirst, der Datensatz damit also eineindeutig (sic) identifiziert werden kann.

                                Wenn Du nun die Userdaten zur Bearbeitung (Anzeige) aufbereitest, dann holst Du dir die Daten aus der Tabelle User, holst Dir die die zugehörigen Daten aus der Tabelle User_Sprache und _alle_ Datensätze aus der Tabelle Sprache.

                                Die beiden Ergebnisse aus Sprache und User_Sprache musst Du noch gegeneinander abgleichen. Angezeigt werden alle Sprachen, aber nur diejenigen, für die es auch einen Datensatz und damit einen Wert für ON_OFF gibt, wurden bisher vom User bearbeitet, gewählt oder abgewählt. Alle Datensätze aus Sprache, die in User_Sprache keinen Partner finden, sind seit der letzten Bearbeitung durch den User hinzu gekommen.

                                Man kann die Teilergebnisse des (HTML-)Formulares, das Du erfinden musst, nun mittels Joins schon von der Datenbank vorbereiten lassen, oder aber diese Aufgabe in PHP erledigen.

                                Du musst Die jedenfalls einen Formulartyp bastelen, der

                                +--------------------------------------+
                                  |          User-Stammdaten             |
                                  |                                      |
                                  |                                      |
                                  |+------------------------------------+|
                                  ||         Details                    ||
                                  |+------------------------------------+|
                                  ||         Details                    ||
                                  |+------------------------------------+|
                                  ||         ...                        ||
                                  |+------------------------------------+|
                                  +--------------------------------------+

                                in etwa so aussieht.

                                Nun ist es Philosphie, ob Du bei Änderungen:

                                * jeweils das gesamte Formular bestätigst
                                * Stammdaten und Detaildaten separat aber im Block bestätigst
                                * Detaildaten einzeln bestätigst

                                Wie komplex Du das machen willst, hängt von deiner Entwicklungspower ab.
                                Für den Anfang würde ich immer jede Änderung einzeln vornehmen.
                                Wenn im Detailbereich nun plötzlich Sprachen auftauchen, zu denen der User sich npch nicht geäußert hat, muss Du das auch irgendwie kenntlich machen und auch überlegen, ob er sich um die Entscheidung drücken darf, oder ON oder OFF wählen muss. Wenn er sich drücken darf, musst Du noch entscheiden, ob trotzdem ein Datensatz in User_Sprache angelegt werden soll (mit ON_OFF = NULL) oder ob du das gar nicht registrieren willst, dass der User sich gedrückt hat.

                                Du siehst: erstmal kommt die Philosophie, dann die Planung, dann die Programmierung.

                                Liebe Grüße aus dem schönen Oberharz

                                Tom vom Berg

                                --
                                 ☻_
                                /▌
                                / \ Nur selber lernen macht schlau
                                Die ultimative Seite für Selbermacher
                              3. Hallo,

                                Sprich ein User geht in sein Profil bearbeitet seine Sprachen, klickt auf speichern, was passiert dann? Lösche ich erst ALLE Datensätze von diesem User und schreibe alle neu, was wohl die einfachste Möglichkeit ist oder prüfe ich, welcher Datensatz neu bzw. weg gefallen sind?

                                Letzteres.

                                Du hast zwei Arrays:
                                1. Die aktivierten Sprachen aus dem Formular
                                2. Die existierenden Sprachen, für die Einträge in der Join-Tabelle bestehen

                                Zu 1.:

                                <form>  
                                <input type="hidden" name="languages[]" value="">  
                                <ul>  
                                <li>  
                                <label><input type="checkbox" name="languages[]" value="1"> Deutsch</label>  
                                </li>  
                                <li>  
                                <label><input type="checkbox" name="languages[]" value="2"> Englisch</label>  
                                </li>  
                                <li>  
                                <label><input type="checkbox" name="languages[]" value="3"> Französisch</label>  
                                </li>  
                                </ul>  
                                </form>
                                

                                $_POST['languages'] ist jetzt

                                • ein leerer Array oder
                                • ein Array mit einer oder mehreren IDs

                                Diesen Array nennt ich im folgenden $existing_language_ids

                                Zu 2.:

                                Die Liste der aktuellen Sprachen holst du dir aus der Join-Tabelle. Die Join-Tabelle speichert einfach zwei Foreign-Keys, einmal user_id und einmal language_id. Sie wird üblicherweise nach den beiden Entitäten benannt, die sie per n:m-Relation verbindet, also in dem Fall users_languages.

                                Gibt mir alle Sprachen für einen User:

                                SELECT * FROM users_languages WHERE user_id = X

                                Daraus hole ich mir alle language_ids. Diesen Array nenne ich im folgenden $new_language_ids.

                                Jetzt habe ich die beiden Arrays:

                                $existing_language_ids
                                $new_language_ids

                                Mit array_diff berechne ich, welche herausfliegen müssen.

                                $ids_to_delete = array_diff($existing_language_ids, $new_language_ids);

                                Für jeden davon führe ich aus:

                                DELETE FROM users_languages WHERE user_id = X AND language_id = Y

                                Wieder mit array_diff berechne ich, welche hinzugekommen sind:

                                $ids_to_insert = array_diff($new_language_ids, $existing_language_ids);

                                Für jeden davon führe ich aus:

                                INSERT INTO users_languages (user_id, language_id) VALUES (X, Y)

                                Das ist jetzt nur eine mögliche Vorgehensweise, die das Prinzip verdeutlichen soll. Es geht bestimmt besser und optimierter (derzeit liegt die Aktualisierungslogik im Anwendungscode, ich vermute, das wäre auch performanter in der DB möglich).

                                Ich habe kurz ausprobiert, was Ruby on Rails hier macht. Dort wird ähnlich gearbeitet. Rails holt sich alle Sprachen für einen User mit einem Join:

                                SELECT languages.* FROM languagesINNER JOINlanguages_usersONlanguages.id=languages_users.language_idWHERElanguages_users.user_id = 1

                                (Das Laden der Languages ist alleine zum Aktualisieren der Relationen streng genommen nicht nötig, Rails antipiziert hier auch Änderungen an den Languages und cacht sie einfach mal.)

                                Dann wird offenbar gedifft mit der ID-Liste aus dem Formular und es werden entsprechende DELETE- und INSERT-Statements ausgeführt.

                                Mathias

                            2. Tach!

                              Wenn man nun z.B. zu einer Person mehrere Telefonnummern hat, dann kann man die Tabelle um eine entsprechende Anzahl von Spalten erweitern. Man erhält dann t.B. Tel1, Tel2, Tel3 usw.
                              Das Dumme daran ist nur, dass dann die Felder Tel2 und Tel3 in den Datensätzen der anderen Personen erstmal leer bleiben, denn die haben in unserem Beispiel nur eine Telefonnummer.
                              Das ist also schon mal vergeudeter Speicherplatz.

                              Arbeitet du etwa mit CHAR statt VARCHAR?

                              Wenn Du nun die Sprachen nicht mehr horizontal speicherst, sondern vertikal, dann sparst Du i.d.R. Platz.

                              Weil man da statt eines Kommas zwischen den Werten in jeder Zeile gegebenenfalls eine ID, auf alle Fälle aber ein Bezug zur Person (üblicherweise Integerfeld) verwendet werden muss?

                              Relationale Datenbanken sind entstanden, als Speicherplatz noch knapp war und Zugriffszeiten noch lang. Man hat daher verschiedene Dinge eingeführt:
                              Durch Datensätze mit fester Satzlänge und -Struktur und damit fester Feldlänge war der "Random Access" auf jedes Feld jedes Datensatzes möglich.

                              Die Zeiten sind vorbei, seit es VARCHAR gibt.

                              Deine Argumentation bezüglich des Speicherplatzes geht an der Frage vorbei, ob man alle Werte in einem Feld oder in mehreren Feldern oder in mehreren Zeilen speichert. Die eigentliche Überlegung sollte sich die Vor- und Nachteile bezüglich der Handhabung vor Augen führen, damit der Probleminhaber sich entscheiden kann, was zu seiner Aufgabenstellung am besten und mit dem geringstmöglichen Aufwand passt.

                              Die Mehrfelder-Lösung hat die Nachteile, dass das Schema angepasst werden muss, wenn Sprachen hinzukommen. Je nach Abfrage muss man sich das Statement individuell zusammenbasteln, wenn nach bestimmten Sprachen und -kombinationen gesucht werden soll, wel jedes Mal die Feldnamen berücksichtigt werden müssen.

                              Bei der Komma-Lösung lassen sich die Sprachen vergleichsweise einfach schreiben und lesen. Beim Abfragen wird es aber herausfordernd, weil man nun mit Stringfunktionen die Werte zwischen den Kommas ansprechen muss - zumindest dann, wenn man FIND_IN_SET() nicht verwenden kann.

                              Die Jede-Sprache-ein-Datensatz-Lösung ist aus DBMS-Sicht die beste, weil dieses damit die Rohdaten mengenbasiert verarbeiten kann und nicht teure Stringoperationen für jeden Datensatz der Tabelle ausführen muss, für die dann auch kein Index verwendet werden kann. Diese Lösung ist aber bei der Datenpflege aufwendiger, weil es bei Änderungen erforderlich sein kann, dass man mehrere/alle Datensätze berücksichtigen muss.

                              Es gibt sicher noch eine Menge weitere Szenarien, die mir gerade nicht einfallen. Auch weiß ich nicht, was der TO am Ende des Tages alles für Features in seiner Anwendung haben möchte, und ob sich dafür die eine oder andere Lösung besser eignet oder besser in die Sackgasse führt.

                              dedlfix.

                              1. Es gibt sicher noch eine Menge weitere Szenarien, die mir gerade nicht einfallen. Auch weiß ich nicht, was der TO am Ende des Tages alles für Features in seiner Anwendung haben möchte, und ob sich dafür die eine oder andere Lösung besser eignet oder besser in die Sackgasse führt.

                                Zu deiner Fragen mit den Features, später soll es ein Userprofil geben mit allen wichtigen Daten die der User ausgefüllt hat, es wird ein kleines Nachrichtensystem geben und eine Suche, nach dem ein User z.B. nach Sprachen suchen kann.

                                Wenn der User "Deutsch" anklickt, sollen alle User erscheinen, die auch Deutsch sprechen.  Dieses müsste sich mit LIKE umsetzten lassen?

                                1. Hello,

                                  Wenn der User "Deutsch" anklickt, sollen alle User erscheinen, die auch Deutsch sprechen.  Dieses müsste sich mit LIKE umsetzten lassen?

                                  Jein. Besser mit find_in_set()
                                  http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_find-in-set

                                  oder mit einem passenden Join, wenn Du dich doch noch für die m:n-Lösung mit "Brückentabelle" entscheidest. Das würde ich Dir erstmal raten.

                                  Liebe Grüße aus dem schönen Oberharz

                                  Tom vom Berg

                                  --
                                   ☻_
                                  /▌
                                  / \ Nur selber lernen macht schlau
                                  Die ultimative Seite für Selbermacher
                                2. Tach!

                                  Wenn der User "Deutsch" anklickt, sollen alle User erscheinen, die auch Deutsch sprechen.  Dieses müsste sich mit LIKE umsetzten lassen?

                                  Das geht nur solange gut, wie die Such-Teilstrings völlig eindeutig im Datenstring sind. Wenn dein Datensatz "...,plattdeutsch,..." enthält, dann wird er auch gefunden, wenn du nach "deutsch" suchst. Jetzt könntest du auf die Idee kommen, die Kommas mit zu berücksichtigen, aber was machst du dann, wenn das Wort am Anfang oder Ende steht? Überschüssige Kommas rein? Dann hast du das Problem gelöst und ein neues geschaffen, weil dein explode() nun zwei Array-Einträge zu viel ergibt, die es zu berücksichtigen oder entfernen gilt. Deswegen gibts die FIND_IN_SET()-Empfehlung.

                                  dedlfix.

                              2. Hello,

                                Arbeitet du etwa mit CHAR statt VARCHAR?

                                Dass so eine blöde Rückfrage kommt an dieser Stelle kommt, habe ich befürchtet :-(
                                Ich war gerade bei "Ramdom Access".

                                VARCHAR, ENUM, SET, usw. sind Spezialtypen, die sich nicht eignen, rudimentäre Datenbankkonzepte zu erklären! Ich fange deshalb ja auch nicht mit B+Tree an...

                                Liebe Grüße aus dem schönen Oberharz

                                Tom vom Berg

                                --
                                 ☻_
                                /▌
                                / \ Nur selber lernen macht schlau
                                Die ultimative Seite für Selbermacher
                                1. Tach!

                                  Arbeitet du etwa mit CHAR statt VARCHAR?
                                  Dass so eine blöde Rückfrage kommt an dieser Stelle kommt, habe ich befürchtet :-(
                                  Ich war gerade bei "Ramdom Access".

                                  Noch eine blöde Rückfrage. Was genau interessiert uns an der Stelle der Random Access? Wir brauchen eine Lösung für ein konkretes Problem und wollen keine Datenhaltung selbst programmieren.

                                  dedlfix.

                            3. Hallo Tom,

                              OK, ich lass mich mal auf das ein, was du und die anderen mir geschrieben haben. Ich sehe zwar noch kein Vorteil darin alle Daten untereinander zu schreiben, aber OK, wenn ihr es sagt wird es schon ein Grund haben, ihr macht es ja definitiv schon länger wie ich.

                              Hab mir nun eine Tabelle mit „sprachen“ angelegt, diese sieht so aus

                                
                              CREATE TABLE IF NOT EXISTS `sprachen` (  
                              `s_id` int(11) NOT NULL,  
                                `s_titel` varchar(200) NOT NULL,  
                                `s_bezeichnung` varchar(200) NOT NULL  
                              ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;  
                              
                              

                              Hab auch schon meine Daten eingefügt, diese sehen wie folgt aus

                                
                              INSERT INTO `sprachen` (`s_id`, `s_titel`, `s_bezeichnung`) VALUES  
                              (1, 'Deutsch', 'deutsch'),  
                              (2, 'Holländisch', 'hollaendisch'),  
                              (3, 'Tschechisch', 'tschechisch'),  
                              (4, 'Türkisch', 'tuerkisch'),  
                              (5, 'Russisch', 'russisch');  
                              
                              

                              Das zusammenbauen meiner Felder kann ich nun auch einfacher machen, dieses habe ich wie folgt gelöst:

                                
                                      <form name="form1" method="post" action="">  
                                      <?php  
                              		$stmt = $mysqli->prepare("SELECT s_id, s_titel, s_bezeichnung FROM sprachen");  
                              		$stmt->execute();  
                                      $stmt->bind_result($s_id, $s_titel, $s_bezeichnung);  
                              		while($stmt->fetch()) {  
                              		?>  
                                        <input name="lang[]" type="checkbox" id="<?php echo $s_bezeichnung;?>" value="<?php echo $s_id;?>">  
                                        <label for="<?php echo $s_bezeichnung;?>"><?php echo $s_titel;?></label>  
                                      <br>  
                              <?php  } ?>  
                                      <br>  
                                        <input type="submit" name="abschicken" id="abschicken" value="Daten eintragen">  
                                      </form>  
                              
                              

                              Das ganze sieht nun so aus:

                              http://s7.directupload.net/images/140610/nuti3u7w.png

                              Wenn ich mir den generierten Quelltext ansehe, sollte soweit auch alles passen. In Value habe ich nun die jeweilige ID stehen.

                              So, kommen wir nun zum speichern, dieses habe ich nun wie folgt gelöst. In meiner Datenbank gibt es nun eine weitere Tabelle mit „sprachen_user“ diese sie derzeit so aus:

                                
                              CREATE TABLE IF NOT EXISTS `sprachen_user` (  
                              `su_id` int(11) NOT NULL,  
                                `su_userID` varchar(200) NOT NULL,  
                                `su_sprachenID` varchar(200) NOT NULL  
                              ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;  
                              
                              

                              Bevor ich meine neuen Daten in die Datenbank eintragen, lösche ich erstmal alle Datensätze die diesem User gehören, da wir hier nicht von großen Datenmengen reden, denke ich mal, dass das der beste und vor allem einfachste Weg ist oder? Dieses mache ich so:

                                
                                $id = '1';	  
                                $stmt = $mysqli->prepare("DELETE FROM sprachen_user WHERE su_userID=?");  
                                $stmt->bind_param("i",  $id);  
                                $stmt->execute();  
                              
                              

                              Derzeit hat $id ein festen Wert, dieser wird später noch dynamisch auf meine UserID geändert, zum testen wollte ich schauen ob wirklich nur die Datensätze gelöscht werden, die den entsprechenden Wert haben.

                              Kommen wir nun zum speichern meiner Daten, dieses habe ich so gelöst:

                                
                                if(is_array($_POST["lang"]) && $_POST["lang"][0]){  
                              	  
                              	foreach($_POST["lang"] as $v){  
                              		  
                              	$stmt = $mysqli->prepare("INSERT INTO sprachen_user (su_userID, su_sprachenID)  VALUES (?, ?)");  
                              			  
                              			$su_sprachenID 	= $v;  
                              			$su_userID	= $user_code;  
                              			  
                              			$stmt->bind_param("ss", $su_userID, $su_sprachenID);			  
                              			$stmt->execute();  
                              	}}  
                              
                              

                              Hab ich es richtig verstanden wie ihr es gemeint habt? Wenn nicht ich bin gerne bereit dieses nochmals umzustellen, sollten noch Fehler vorhanden sein.

                              1. Ich weiß nicht ob die Umstellung wie hier beschrieben wirklich das richtige für mich ist. Es mag für euch vielleicht schöner sein, aber im endefekt ist es doch scheiß egal wie ein Code in der Datenbank aussieht.

                                Speicherplatz hin Speicherplatz her. Ich hab mit meinem Provider gesprochen und er meinte, mach dir bei einer Datenbank solange wir nicht von Millionen von Einträgen ausgehen keine Sorgen ob da ein Feld leer oder belegt ist.

                                Seit drei Stunden hänge ich wieder hier und versuche meine Felder auszulesen, dass diese wieder angeklickt sind, wenn ein User kommt, es klappt einfach nicht. Mit meiner ersten Version war es ohne Probleme möglich.

                                So versuche ich die Werte auszulesen

                                  
                                    $stmt = $mysqli->prepare("SELECT web_users.user_code, sprachen_user.su_userID FROM web_users LEFT JOIN sprachen_user ON web_users.user_code = sprachen_user.su_userID WHERE user_session=?");  
                                	$stmt->bind_param("s", session_id());  
                                    $stmt->execute();  
                                	$stmt->bind_result($user_code, $su_sprachenID);  
                                	$stmt->fetch();  
                                    $stmt->close();  
                                
                                

                                Ich muss diese Werte jetzt wieder in ein Array bekommen oder?

                                Später möchte ich so wieder das vergleichne machen

                                  
                                <?php echo (in_array('Türkisch',$teile)?'checked="checked"':NULL) ?>  
                                
                                

                                Wie kann ich nun $teile wieder füllen?

                                1. Hallo

                                  Ich weiß nicht ob die Umstellung wie hier beschrieben wirklich das richtige für mich ist. Es mag für euch vielleicht schöner sein, …

                                  Es geht hier keineswegs um unser ästhetisches Empfinden.

                                  … aber im endefekt ist es doch scheiß egal wie ein Code in der Datenbank aussieht.

                                  Primär schon, wenn du später aber Änderungen durchführen willst/musst/kannst, ersparst du dir durch das richtige™ Datenmodell Arbeit. Natürlich darfst du jetzt abwägen, wie oft das wohl passieren wird und wie groß der Aufwand mit deinem Schema sein wird, sprich, wieviel sich überhaupt einsparen ließe.

                                  Falls du dann irgendwann doch mal mehr machen wollen solltest, als deine Website, wäre das Wissen um Datenmodelle nicht vergebens.

                                  Speicherplatz hin Speicherplatz her. …

                                  Ich denke mal, dass das Argument Speicherplatz im Bereich einer proivaten oder semiprofessionellen Website nicht zu Problemen führen sollte. Entweder, es fallen nicht erheblich große Datenmenge an oder die Vergrößerung des Speichervolumens ist problemlos möglich.

                                  $stmt = $mysqli->prepare("SELECT web_users.user_code, sprachen_user.su_userID FROM web_users LEFT JOIN sprachen_user ON web_users.user_code = sprachen_user.su_userID WHERE user_session=?");
                                  $stmt->bind_param("s", session_id());
                                      $stmt->execute();
                                  $stmt->bind_result($user_code, $su_sprachenID);
                                  $stmt->fetch();
                                      $stmt->close();

                                  
                                  >   
                                  > Ich muss diese Werte jetzt wieder in ein Array bekommen oder?  
                                    
                                  Ja.  
                                    
                                  
                                  > Später möchte ich so wieder das vergleichne machen  
                                    
                                  Ja.  
                                    
                                  
                                  > Wie kann ich nun $teile wieder füllen?  
                                    
                                  Wie füllst du in anderen Fällen deine Variablen aus `$stmt`{:.language-php} (oder vergleichbaren Quellen)?  
                                    
                                  Tschö, Auge  
                                  
                                  -- 
                                  Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.  
                                  Terry Pratchett, "Wachen! Wachen!"  
                                    
                                  ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}  
                                    
                                  [Veranstaltungsdatenbank Vdb 0.3](http://termindbase.auge8472.de/)
                                  
                                  1. Wie füllst du in anderen Fällen deine Variablen aus $stmt (oder vergleichbaren Quellen)?

                                    Bis jetzt habe ich dieses mit einer while Schleife gemacht, so z.B.

                                      
                                    while($stmt->fetch()) {  
                                      
                                              }  
                                    
                                    

                                    Dann habe ich in $su_sprachenID mein Wert stehen. Ich will in meinem Fall aber keine Ausgabe, sondern mein Array muss ja gefüllt werden. Daher denke ich, dass eine while Schleife hier nicht richtig ist oder?

                                    1. Ich will in meinem Fall aber keine Ausgabe, sondern mein Array muss ja gefüllt werden. Daher denke ich, dass eine while Schleife hier nicht richtig ist oder?

                                      Doch, doch, warum nicht.

                                      Einen Array füllst du so:

                                      $arr = array();

                                      Dann wiederholt:

                                      $arr[] = 'wert';

                                      In einer Schleife, die sich nach und nach alle Ergebnisse holt:

                                      while ($result = $stmt->fetch()) {  
                                        $arr[] = $result['su_sprachenID'];  
                                      }
                                      

                                      (Oder ähnlich – ich weiß nicht genau, wie $result aussieht. Ich vermute einen assoziativen Array mit einem Eintrag su_sprachenID.)

                                      (Disclaimer: Ich habe nicht viel Ahnung von PHP, der Code kann fehlerhaft sein, aber so müsste es prinzipiell möglich sein.)

                                      Mathias

                                      1. Doch, doch, warum nicht.

                                        Einen Array füllst du so:

                                        $arr = array();

                                        Dann wiederholt:

                                        $arr[] = 'wert';

                                        In einer Schleife, die sich nach und nach alle Ergebnisse holt:

                                        while ($result = $stmt->fetch()) {

                                        $arr[] = $result['su_sprachenID'];
                                        }

                                          
                                        Danke für deine Antwort, da hatte ich wohl ein Denkfehler, ich dachte ich brauch die Schleife nur bei einer Ausgabe, was der User zu Gesicht bekommt. Hab nun so umgebaut:  
                                          
                                        ~~~php
                                          
                                            $teile = array();  
                                          
                                            $stmt = $mysqli->prepare("SELECT  
                                        				web_users.user_code,  
                                        				sprachen_user.su_userID,  
                                        				sprachen_user.su_sprachenID  
                                        								  
                                        				FROM web_users  
                                        				LEFT JOIN sprachen_user  
                                        								  
                                        				ON web_users.user_code = sprachen_user.su_userID  
                                        								  
                                        				WHERE user_session=?");  
                                        	  
                                            $stmt->bind_param("s", session_id());  
                                            $stmt->execute();  
                                            $stmt->bind_result($user_code, $su_sprachenID);  
                                          
                                        		while($stmt->fetch()) {  
                                        			$teile[] = $su_sprachenID;  
                                                  }  
                                        
                                        

                                        bekomme jetzt eine Fehlermeldung

                                        Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement in Zeile 23. In dieser Zeile steht dieses:

                                        $stmt->bind_result($user_code, $su_sprachenID);

                                        Meine Frage, was mache ich hier falsch? beide Werte rufe ich oben im SELECT doch aus meiner Datenbank ab. Die Felder sind auch richtig geschrieben.

                                        1. bekomme jetzt eine Fehlermeldung

                                          Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement in Zeile 23. In dieser Zeile steht dieses:

                                          Ok, ich hab den Fehler gefunden, die Zeile muss so aussehen

                                          $stmt->bind_result($user_code, $su_userID, $su_sprachenID);

                                          Meine Frage hier nun, warum müssen bei $stmt->bind_result alle Daten angegeben werden, die ich oben aus meiner Datenbank hole?

                                          1. Hallo!

                                            Meine Frage hier nun, warum müssen bei $stmt->bind_result alle Daten angegeben werden, die ich oben aus meiner Datenbank hole?

                                            Weil das der Sinn von bind_result ist.

                                            Wenn du die Daten nicht im Ergebnis haben willst, wieso SELECTest du sie? Das ist für den JOIN m.W. nicht zwingend nötig.

                                            Aber es schadet auch nicht, eine Variable anzugeben, in die das Ergebnis geschrieben wird, wenn du sie eh nicht benutzt.

                                            Mathias

                                          2. Moin Martin_Online,

                                            Meine Frage hier nun, warum müssen bei $stmt->bind_result alle Daten angegeben werden, die ich oben aus meiner Datenbank hole?

                                            bind_result ist eine unhandliche API. Sobald man am SQL etwas ändert, muss man an vielen Stellen direkt aufpassen und anpassen. Schau dir mal fetch_assoc an, die API ist deutlich handlicher. Sie liefert dir deine Zeile als assoziativen Array zurück.

                                            LG,
                                             CK

                                        2. $stmt = $mysqli->prepare("SELECT
                                          web_users.user_code,
                                          sprachen_user.su_userID,
                                          sprachen_user.su_sprachenID

                                          Hier wählst du *drei* Spalten aus.

                                          $stmt->bind_result($user_code, $su_sprachenID);

                                          Hier gibst du nur *zwei* Variablen zum füllen an.

                                          Daher die Fehlermeldung:

                                          Number of bind variables doesn't match number of fields in prepared statement

                                          Mathias

                          2. Hallo,

                            Warum verwenden große Systeme wie Joomla, Wordpress, Contao genau diese Vorgehensweise?

                            Wo genau tun sie das? Um welche Information zu speichern?

                            Bei Drupal und Wordpress gibt es z.B. die Verbindung von Posts und Tags/Kategorien. Das ist eine n:m-Beziehung, die in einer Joint-Table gespeichert wird.

                            http://codex.wordpress.org/Database_Description – wp_term_relationships.
                            http://posulliv.github.io/2012/08/02/drupal-er-diagram/ – taxonomy_index

                            Grüße
                            Mathias

                            1. Moin molily,

                              […] Joint-Table […]

                              *rotfl* made my day

                              LG,
                               CK

                              1. Om nah hoo pez nyeetz, Christian Kruse!

                                […] Joint-Table […]
                                *rotfl* made my day

                                Hey, dich gibts ja doch noch ;-)

                                Matthias

                                --
                                Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Boot und Bootes.

                                1. @@Matthias Apsel:

                                  nuqneH

                                  Hey, dich gibts ja doch noch ;-)

                                  Dann gibt’s das CForum 4 hier doch noch irgendwann? ;-)

                                  Qapla'

                                  --
                                  „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                                  1. Moin Gunnar,

                                    Hey, dich gibts ja doch noch ;-)

                                    Dann gibt’s das CForum 4 hier doch noch irgendwann? ;-)

                                    Naja, zumindest ist das immer noch mein Plan. Ich hab vor jetzt im Urlaub weiter daran zu arbeiten.

                                    LG,
                                     CK

                                2. Moin Matthias,

                                  […] Joint-Table […]
                                  *rotfl* made my day

                                  Hey, dich gibts ja doch noch ;-)

                                  Ach, ich war die letzten Monate komplett Land-unter. Hatte einen Auftraggeber in UK, der mich für FOSS bezahlt hat, und ich hab mich da ziemlich 'reingesteigert weil es eine total interessante (und idealistisch coole weil FOSS) Arbeit war ;)

                                  LG,
                                   CK

                                  1. Hallo,

                                    … weil es eine total interessante (und idealistisch coole weil FOSS) Arbeit war ;)

                                    Link please, or it didn’t happen! :)

                                    Mathias

                                    1. Moin molily,

                                      … weil es eine total interessante (und idealistisch coole weil FOSS) Arbeit war ;)

                                      Link please, or it didn’t happen! :)

                                      Hehe, kannst du haben ;)

                                      https://github.com/2ndQuadrant/repmgr
                                      http://git.postgresql.org/gitweb/?p=2ndquadrant_bdr.git;a=summary

                                      LG,
                                       CK

                                      1. Hallo,

                                        https://github.com/2ndQuadrant/repmgr

                                        Das sieht sehr interessant aus. Wir sind nach einer Odyssee über MySQL und MongoDB auch wieder bei Postgres gelandet… Leider stecke ich nicht so tief in dem Thema, aber bekomme immer wieder mit, dass sehr coole und fähige Menschen an und mit Postgres arbeiten und der Funktionsumfang, die Flexibilität und die Leistungsfähigkeit gigantisch sind. Wenn wir mal jemanden brauchen, der sich damit auskennt, weiß ich, wen ich fragen muss. :)

                                        Grüße
                                        Mathias

                                        1. Moin molily,

                                          https://github.com/2ndQuadrant/repmgr

                                          Das sieht sehr interessant aus.

                                          Ist es!

                                          Wir sind nach einer Odyssee über MySQL und MongoDB auch wieder bei Postgres gelandet…

                                          Das höre ich interessanterweise immer wieder. Die Dokument-basierten Datenbanken stellen viele Leute nicht so richtig zufrieden. Woran auch immer das liegen mag.

                                          Leider stecke ich nicht so tief in dem Thema, aber bekomme immer wieder mit, dass sehr coole und fähige Menschen an und mit Postgres arbeiten und der Funktionsumfang, die Flexibilität und die Leistungsfähigkeit gigantisch sind.

                                          Und es wird noch besser! Mit der kürzlich erschienenen 9.4 beta 1 gibt es z.B. logische Dekodierung. Damit lassen sich so coole Sachen wie logische Replikation oder automatische Cache-Invalidierung von ORMs (*hint, hint* Rails, z.B.) umsetzen. An der Replikation hab ich auch mit gearbeitet, das wird extrem cool :)

                                          Wenn wir mal jemanden brauchen, der sich damit auskennt, weiß ich, wen ich fragen muss. :)

                                          Hm, 2ndQuadrant? ;)

                                          LG,
                                           CK

                    2. Tom,

                      ich habe einen technischen Hinweis gegeben. Ich weiß nicht, warum du das als Anlass nimmst, mich einmal grundlegend abzuwatschen. Dieses Forum ist bekanntermaßen, freundlich ausgedrückt, agnostisch gegenüber Frameworks und deren Best Practices, daher scheinen mir solche Hinweise durchaus angebracht.

                      Aber erstens weiß ich das schon

                      Wenn du das schon weißt, okay, das Posting war an alle Mitlesenden gerichtet. Ich habe zwei m.M.n. wertvolle Hinweise gegeben, die hier noch nicht genannt worden sind.

                      Auf die Lösung mit den doppelten Checkboxen hätte er selber kommen können.

                      Spielen wir hier Ostereiersuche? Wenn es eine Best Practice gibt, nenne ich sie auch kurzerhand.

                      Ich finde es schade, dass Du dich nicht an das Credo des Forums hältst

                      Frevel! Ketzerei! Häresie!

                      "Die Energie des Verstehens". Dazu gehört ein gewisses Maß an Selbermachen.

                      Dazu gehört erst einmal ein gewisses Maß an Demut. Wir sind bloß Zwerge auf den Schultern von Giganten. Ich nicht nicht der Mittelpunkt des Webentwicklungs-Universums und kann nicht aus schöpferischer Kraft heraus sämtliche Techniken ex nihilo hervorbringen. Das heißt, dass ich mich mit der Tradition auseinandersetzen muss. Dass ich Code lesen muss, bevor ich Code schreibe, um nicht dieselben Fehler zu wiederholen.

                      Wenn Du die (eine, deine) Lösung immer schon im Voraus bekannt gibst

                      Ich kann immer nur eine, meine Lösung bekannt geben, denn ich bin nur eine Person.

                      Und was heißt hier »im Voraus«? Vor was?

                      und leider auch meistens keinerlei andere Lösungswege gelten lässt,

                      DAS musst du mir konkret nachweisen, wenn du solche schwerwiegenden Unterstellungen machst.

                      stellt das den Sinn des Forums in Frage.

                      Der Sinn des Forums ist für mich die Findung einer angemessenen, wenn nicht bestmöglichen technischen Lösung und eine Beratung der Fragenden dahingehend. Seitens der Fragenden gibt es gewisse Umstände und Einschränkungen, die zu beachten sind: Vorwissen, existierender Code, der nicht einfach umgeschrieben und migriert werden kann usw.

                      Bastler dürfen gerne basteln und zum Lernen und Verstehen Lösungen von Hand implementieren. Falls ich das einmal *nicht* erwähne, gehöre ich sofort gescholten! Das letzte Mal, als ich es erwähnt habe, war in meinem ersten Posting in diesem Thread.

                      Zwei Dinge sind zu allerdings beachten:

                      • »Marke Eigenbau« kommt nicht an den Komfort, die Robustheit und Sicherheit einer Lösung heran, an der tausende Leute seit 10 Jahren gearbeitet haben. Das gilt nämlich für Open-Source-Webframeworks. Es lohnt sich also, über den eigenen Tellerrand zu blicken und sich von bestehenden Lösungen inspirieren zu lassen.

                      • Die Produktivität und also Wirtschaftlichkeit von »Marke Eigenbau« ist ebenfalls schlechter. Wenn es nicht aus technischen Gründen nötig ist, dann ist es einfacher und schneller, bestehende Software zu verwenden.

                      Ich fände es produktiver, wenn Du erst ziemlich zum Ende mit den Fertiglösungen kämst, die dann aber auch ausführlich erläutern könntest!

                      Ich fände es anständiger, wenn du mir nicht schwerwiegende Vorwürfe machst, ohne einen Nachweis zu erbringen!

                      Ich habe erläutert, wie Webframeworks Many-to-Many-Beziehungen grundsätzlich lösen und sie über Formulare updaten. Ich kann es gerne im Detail erläutern, aber bisher gab es keine inhaltlichen Nachfragen.

                      Anstatt eines »oh, das ist aber interessant, erzähle uns mehr« kam bisher nur ein »hör auf, solche Fertiglösungen zu posten, du hältst dich nicht an das Credo des Forums«. Schade.

                      Dafür würde sich dann in hervorragender Weise das Wiki eignen.

                      Zu MVC- und ORM-Frameworks gibt es bereits gute Tutorials. Das ist kein Feld, was von mir beackert werden muss, zumal es nicht mein Spezialgebiet ist. Man muss sich nur umschauen, was bereits da ist.

                      Bitte sieh dieses Posting von mir als Anregung und nicht als Angriff :-)

                      Das ist mir leider nicht gelungen. Du kannst nicht gleichermaßen vernichtende wie unhaltbare Kritik äußern und dann einen lächelnden Smiley nachschieben.

                      Mathias

            2. Ich bin es nochmals, mein Insert Code sieht nun wie folgt aus, scheint auch gut zu funktionieren.

                
                
                  $stmt = $mysqli->prepare("SELECT user_code FROM web_users WHERE user_session=?");  
                  $stmt->bind_param("s", session_id());  
                  $stmt->execute();  
                  $stmt->bind_result($user_code);  
                  $stmt->fetch();  
                  $stmt->close();  
                
              if(isset($_POST['abschicken'])){  
              		  
                  if ($stmt = $mysqli->prepare("INSERT INTO web_users_profil (wup_userID, wup_lang)  
              				  VALUES (?, ?)"))  
              		 {  
                
              			$lang 		= $_POST['lang'];  
              			$wup_lang 	= implode(', ',$lang);  
              			  
              			$wup_userID	= $user_code;  
              			  
              			$stmt->bind_param("ss", $wup_userID, $wup_lang);  
              			  
              			$stmt->execute();  
              			}  
              			else {  
              				echo $mysqli -> error;  
              			}  
              }  
              
              

              Jetzt kommt aber die letzte Frage, wie bekomme ich nun meine Daten beim Editieren dieses Formulars wieder angekreuzt?

            3. Entsprechend macht explode() diesen Schritt rückgängig:

              Ok, ich hab es so getestet und es scheint zu gehen:

                
              	$lang 		= $_POST['lang'];  
              	$wup_lang 	= implode(', ',$lang);  
              	echo $wup_lang;  
              	echo '<br><br>';  
              			  
              	$ausgabe = explode(",", $wup_lang);  
              	echo $ausgabe[0];  
              
              

              Mein Insert mache ich so: http://forum.de.selfhtml.org/?t=217687&m=1495913 auch das geht soweit. Jetzt aber die Frage, wie kann ich mit $ausgabe[0]; die Felder wieder belegen, wenn ein User das ganze bearbeiten möchte?

              Mein HTML sieht derzeit so aus:

                
                      <form name="form1" method="post" action="">  
                
                        <input name="lang[]" type="checkbox" id="deutsch" value="Deutsch">  
                        <label for="deutsch">Deutsch</label>  
                      <br>  
                        <input type="checkbox" name="lang[]" id="hollaendisch" value="Holländisch">  
                        <label for="hollaendisch">Holländisch</label>  
                      <br>  
                        <input type="checkbox" name="lang[]" id="tschechisch" value="Tschechisch">  
                        <label for="tschechisch">Tschechisch</label>  
                      <br>  
                        <input type="checkbox" name="lang[]" id="tuerkisch" value="Türkisch">  
                        <label for="tuerkisch">Türkisch</label>  
                      <br>  
                        <input type="checkbox" name="lang[]" id="russisch" value="Russisch">  
                        <label for="russisch">Russisch</label>  
                      <br>  
                      <br>  
                        <input type="submit" name="abschicken" id="abschicken" value="Daten eintragen">  
                
                      </form>  
              
              

              Du musst eigentlich nur darauf achten, dass das Array lang[] beim Eintragen nicht fehlt - falls mal jemand gar keine Sprache ankreuzt, was nicht sehr sinnvoll wäre. Diesen Fall (erkennbar daran, dass isset(lang) false liefert) solltest du als Fehler abweisen.

              Ich lass es dem User ehrlich gesagt frei, ob er hier etwas ausfüllt oder nicht. Sollte das Array leer sein, wird nichts in der DB gespeichert bzw. das Feld bleibt leer.

              1. Hi,

                Entsprechend macht explode() diesen Schritt rückgängig:
                Ok, ich hab es so getestet und es scheint zu gehen:

                $lang 		= $_POST['lang'];  
                

                $wup_lang = implode(', ',$lang);

                  
                abgesehen davon, dass das stumpfe Umkopieren hier sinnlos ist: Okay.  
                  
                
                > > Du musst eigentlich nur darauf achten, dass das Array lang[] beim Eintragen nicht fehlt - falls mal jemand gar keine Sprache ankreuzt, was nicht sehr sinnvoll wäre. Diesen Fall (erkennbar daran, dass isset(lang) false liefert) solltest du als Fehler abweisen.  
                > Ich lass es dem User ehrlich gesagt frei, ob er hier etwas ausfüllt oder nicht. Sollte das Array leer sein, wird nichts in der DB gespeichert bzw. das Feld bleibt leer.  
                  
                Wenn das keine "bösen" Folgen hat, beispielsweise dass bestimmte Ausgaben ganz wegfallen, ist das natürlich in Ordnung. Du solltest halt immer überlegen: Was kann im ungünstigsten Fall passieren? Wenn der Nutzer dadurch kein unmittelbares Problem hat, gut.  
                  
                Ciao,  
                 Martin  
                
                -- 
                Der Stress von heute ist die gute alte Zeit von morgen.  
                Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                
                1. Hallo Martin,

                  Wenn das keine "bösen" Folgen hat, beispielsweise dass bestimmte Ausgaben ganz wegfallen, ist das natürlich in Ordnung. Du solltest halt immer überlegen: Was kann im ungünstigsten Fall passieren? Wenn der Nutzer dadurch kein unmittelbares Problem hat, gut.

                  die Frage ist jetzt nur, wie kann ich die Felder vorbelegen, wenn der User wieder auf diese Seite kommt um das ganze zu bearbeiten? Bei meinem Registrierungsscript mache ich das so:

                  value="<?=(isset($_POST['user_passwortWDH'])) ? $_POST['user_passwortWDH'] :''?>"

                  aber hier ist mein value ja schon vorbelegt mit einem Wert und wie kann ich diese Werte $ausgabe[0]; den Felder zuordnen?

                  1. Tach!

                    die Frage ist jetzt nur, wie kann ich die Felder vorbelegen, wenn der User wieder auf diese Seite kommt um das ganze zu bearbeiten?

                    Geh doch mal bitte in eine HTML-Dokumentation (zufällig hängt eine solche an diesem Forum) und schau dir an, wie man einer Checkbox das Häkchen setzt.

                    dedlfix.

                    1. Geh doch mal bitte in eine HTML-Dokumentation (zufällig hängt eine solche an diesem Forum) und schau dir an, wie man einer Checkbox das Häkchen setzt.

                      Ich glaube das schwere Unwetter und die Hitze hier in Köln tut mir nicht gut. Ein Feld kann ich so angeklickt machen checked="checked"

                      Jetzt bleibt noch die Frage, wie kann ich mit den Daten die ich aus $ausgabe[0]; usw. kommen die Felder auf checked setzten.

                      1. Tach!

                        Jetzt bleibt noch die Frage, wie kann ich mit den Daten die ich aus $ausgabe[0]; usw. kommen die Felder auf checked setzten.

                        Für jede Sprache:
                          Schreib das HTML-Zeugs und bei der Checkbox den beginn.
                          Wenn diese Sprache in den Daten aus der Datenbank enthalten ist, dann schreib der Checkbox ein checked, ansonsten nichts.
                          Schließ die Checkbox und schreib den Rest vom HTML für diese Sprache.

                        dedlfix.

                        1. Für jede Sprache:
                            Schreib das HTML-Zeugs und bei der Checkbox den beginn.
                            Wenn diese Sprache in den Daten aus der Datenbank enthalten ist, dann schreib der Checkbox ein checked, ansonsten nichts.
                            Schließ die Checkbox und schreib den Rest vom HTML für diese Sprache.

                          Ich hab es nun so getestet

                            
                          $test = array('Deutsch');  
                          
                          

                          Die Ausgabe sieht so aus

                            
                           <input name="lang[]" type="checkbox" id="deutsch" value="Deutsch" <?php echo (in_array('Deutsch',$test)?'checked="checked"':NULL) ?>>  
                          
                          

                          scheint auch zu funktionieren. Wenn ich nun mit den Werten aus meiner Datenbank arbeite, also so:

                            
                          $test = array();  
                          $test[] = $wup_lang;  
                          
                          

                          geht nichts mehr. Eine Ausgabe von $test bringt folgendes:

                          array(1) { [0]=> string(21) "Deutsch, Holländisch" }

                          heißt also, ich habe den Wert Deutsch, wird aber nicht erkannt, was mache ich falsch?

                          1. Tach!

                            Wenn ich nun mit den Werten aus meiner Datenbank arbeite, also so:
                            geht nichts mehr. Eine Ausgabe von $test bringt folgendes:
                            array(1) { [0]=> string(21) "Deutsch, Holländisch" }
                            heißt also, ich habe den Wert Deutsch, wird aber nicht erkannt, was mache ich falsch?

                            Nein, dein Wert heißt "Deutsch, Holländisch" nicht nur "Deutsch". Das kann so mit einfachem Vergleich nicht gefunden werden. Ein Lösungsweg steht bereits in früheren Antworten: explode(). Und da du auch noch ein Leerzeichen zwischen , und H hast, musst du dich um dieses auch noch kümmern, denn " H..." ist auch nicht gleich "H...". Der Wert in der Datenbank muss nicht schön lesbar sein, der muss verarbeitet werden können, also mach da die Leerzeichen raus.

                            dedlfix.

                            1. Nein, dein Wert heißt "Deutsch, Holländisch" nicht nur "Deutsch". Das kann so mit einfachem Vergleich nicht gefunden werden. Ein Lösungsweg steht bereits in früheren Antworten: explode(). Und da du auch noch ein Leerzeichen zwischen , und H hast, musst du dich um dieses auch noch kümmern, denn " H..." ist auch nicht gleich "H...". Der Wert in der Datenbank muss nicht schön lesbar sein, der muss verarbeitet werden können, also mach da die Leerzeichen raus.

                              Danke für deine Antwort, ich hab es nun so hinbekommen

                              $teile = explode(",", $wup_lang);

                              Und mein INSERT sieht so aus

                                
                              	$lang 		= $_POST['lang'];  
                              	$wup_lang 	= implode(',',$lang);  
                              
                              
                              1. Tach!

                                Und mein INSERT sieht so aus

                                $lang = $_POST['lang'];
                                $wup_lang = implode(',',$lang);

                                  
                                Welchen Sinn hat den $lang hier? $wup\_lang = implode(',', $\_POST['lang']); macht genau dasselbe, ohne eine überflüssiges Zeile und Umkopier-Operation.  
                                  
                                  
                                dedlfix.
                                
                                1. Welchen Sinn hat den $lang hier? $wup_lang = implode(',', $_POST['lang']); macht genau dasselbe, ohne eine überflüssiges Zeile und Umkopier-Operation.

                                  Hat nicht wirklich einen Sinn, hat man mir gestern Abend auch schon gesagt. Hab es nun entfernt.

                                2. Welchen Sinn hat den $lang hier? $wup_lang = implode(',', $_POST['lang']); macht genau dasselbe, ohne eine überflüssiges Zeile und Umkopier-Operation.

                                  Umkopier-? Umreferenzier- vermutlich! ;)

                                  Mathias
                                  (Nitpicker)

                                  1. Tach!

                                    Martin_Online, bitte überlesen, es folgt technisches Fachgesimpel, was dich nicht weiterbringt und was ohne das Wissen um den technischen Hintergrund unverständlich ist. Den Hintergrund muss man auch nicht unbedingt kennen, das sind PHP-Interna, auf die man keinen Einfluss hat.

                                    Welchen Sinn hat den $lang hier? $wup_lang = implode(',', $_POST['lang']); macht genau dasselbe, ohne eine überflüssiges Zeile und Umkopier-Operation.
                                    Umkopier-? Umreferenzier- vermutlich! ;)

                                    Jein. Aus Anwendersicht sind das Kopien, auch wenn sie erst zu einem späteren Zeitpunkt wirklich kopiert werden - oder auch nicht. Aber dieses Verhalten Copy-on-Write soll ja abgeschafft werden. Referenzen hingegen bleiben auch für Anwender Referenzen. Implizite Referenzen gibt es nur bei Objekten, alles andere muss explizit referenziert werden. Wie auch immer man das Kind nennt oder was es genau macht, es bleibt in dem Fall überflüssig.

                                    dedlfix.

                                    1. Hallo,

                                      Martin_Online, bitte überlesen, es folgt technisches Fachgesimpel, was dich nicht weiterbringt

                                      Danke für den angebrachten Hinweis. :)

                                      Wenn ich noch ein wenig fachsimpeln darf aus Interesse:

                                      Aber dieses Verhalten Copy-on-Write soll ja abgeschafft werden.

                                      Aha. Du meinst der PHP-Interpreter wird sein Verhalten ändern bzw. auf Copy-on-Write zu vertrauen ist schlechter Stil?

                                      Implizite Referenzen gibt es nur bei Objekten, alles andere muss explizit referenziert werden.

                                      Müsste man dann in Zukunft explizit eine Referenz anlegen, sonst würde sofort kopiert?

                                      Mathias

                                      1. Tach!

                                        Aber dieses Verhalten Copy-on-Write soll ja abgeschafft werden.
                                        Aha. Du meinst der PHP-Interpreter wird sein Verhalten ändern bzw. auf Copy-on-Write zu vertrauen ist schlechter Stil?

                                        Ich meine dazu gar nichts, ich bin Anwendungsprogrammierer und habe nur vor kurzem gelesen, dass da grad jemand Änderungen an der Engine vornimmt, die unter anderem das Copy-on-Write beseiten sollen.

                                        Implizite Referenzen gibt es nur bei Objekten, alles andere muss explizit referenziert werden.
                                        Müsste man dann in Zukunft explizit eine Referenz anlegen, sonst würde sofort kopiert?

                                        Ich weiß nicht, was exakt kommen wird. Aber ich würde darauf verzichten, wenn es nicht eine technische Notwendigkeit zu einer Referenz gäbe.

                                        dedlfix.

                                      2. Moin molily,

                                        Aber dieses Verhalten Copy-on-Write soll ja abgeschafft werden.

                                        Aha. Du meinst der PHP-Interpreter wird sein Verhalten ändern bzw. auf Copy-on-Write zu vertrauen ist schlechter Stil?

                                        Das war immer schon schlechter Stil. Copy-on-write ist implementation specific, der Zend-Interpreter nutzt diese Technik als Performance-Optimierung. Und die Umstände, unter denen diese Optimierung verwendet wird, ist auch nicht immer sofort einsichtig. Die HHVM z.B. verwendet intern immutable strings mit Copy-On-Write-Mechanismus (schreibt man das so? sieht scheiße aus…), aber wenn der refcount (HHVMs GC funktioniert über refcounting) exakt 1 ist, dann wird der String doch in-place geändert.

                                        Implizite Referenzen gibt es nur bei Objekten, alles andere muss explizit referenziert werden.

                                        Müsste man dann in Zukunft explizit eine Referenz anlegen, sonst würde sofort kopiert?

                                        Relevant ist diese Überlegung nur für Strings, Arrays/Hashes und Objekte, alle anderen Datentypen sind trivial zu kopieren, da würde das copy-on-write mehr Performance fressen als gewinnen (ein int z.B. ist 4 bzw. 8 Byte gross, also Word-Größe, zzgl Meta-Informationen, die aber sowieso gespeichert werden müssen – da macht copy-on-write einfach keinen Sinn). Bei Objekten wird von Haus aus mit Referenzen gearbeitet. Strings sind in PHP immutable, das bedeutet, dass hier keine Kopie angelegt werden muss. Bei den üblichen String-Operationen (z.B. concatenation) wird ein neuer String erstellt (Ausnahmen siehe oben). Bleiben Arrays/Hashes übrig.

                                        Ein Grund, den ich mir vorstellen kann, warum man darauf verzichten wollen würde, wäre Threading. Es ist durchaus problematisch eine Kopie zu einem späteren Zeitpunkt anzulegen, in einer Multi-Threaded-Umgebung kann man ja nicht sicher sein, dass die Daten in der Zwischenzeit nicht geändert werden.

                                        LG,
                                         CK

  2. Tach!

    <input type="checkbox" name="was[]" id="was">
      <label for="was"></label>
        Deutsch
    Nun stellt sich mir die Frage, wie soll ich diese Daten in einer Datenbank speichern?

    Als erstes müsstest du mal das Fomular ändern und den Input-Feldern ein value-Attribut spendieren, sonst kannst du die empfangenen Kreuzchen nicht den Sprachen zuordnen. Und eine ID muss dokumentweit eindeutig sein. Außerdem muss der Name im Label stehen, sonst ist das Label-Element sinnlos.

    Für mich kommen zwei Optionen in Frage, ich lege eine Tabelle mit „sprachen“ an, In dieser befinden sich Spalten und zwar für jede Sprache eine. In diesem Fall wären dieses 5 Spalten. Nachteil dieser Lösung ist, wenn weitere Sprachen hinzukommen muss die Tabelle jeweils angepasst werden.

    Auch der Datentyp SET kommt auf dasselbe hinaus, ist jedoch einfacher zu erweitern.

    In diesem Beispiel könnte ich dann die [] auch wieder entfernen, da jede Sprache eine eigene Spalte hat.

    Ob du da ein Array oder einzelne Benennungen hast, ist relativ nebensächlich, was das Speichern in der Datenbank angeht.

    Ganz anderes sieht es beim Update aus, wie gehe ich da vor? Lösche ich erst ALLE Einträge von diesem User, schreibe die angeklickten Felder komplett neu?

    Das wäre eine Möglichkeit, eine andere ist, mit Mengen zu hantieren. Ermittle die Menge der nicht mehr angekreuzten und lösche diese.

    Und wie sieht es beim auslesen aus, also wenn der User auf die Seite kommt und die Felder bearbeiten möchte?

    Dann hast du eine Anzahl Datensätze, die du in einem Array ablegen kannst. Oder du hantierst mit GROUP_CONCAT(), dann hast du eine kommaseparierte Zeichenkette (die du auch zum Array machen kannst). Wenn du die HTML-Elemente einer Sprache ausgibst, musst du ermitteln, ob diese in der Liste der abgefragten enthalten ist.

    Ich merke jetzt schon, hier kommen sehr viele Probleme auf mich zu oder? Wie speichert ihr solche Daten?

    So wie es am besten im jeweiligen Fall passt, also SET (oder ENUM bei nur einer) oder zweite Tabelle.

    Ein Ansatz habe ich bei Joomla gesehen, hier werden alle Daten in EINEM Feld gespeichert mit einem , getrennt, aber ich gehe davon aus, dass dieses noch um einiges schwerer ist zu speichern, bearbeiten und löschen?

    Mit String-Verarbeitung und auch FIND_IN_SET() lässt sich einiges machen. Das kommaseparierte wäre jedenfalls analog zur Variante mit SET, dafür aber ohne Erweiterung der SET-Werte beim Hinzukommen einer Sprache und auch speicherintensiver (wobei letzteres heutzutage kein Problem mehr darstellt).

    dedlfix.

  3. Hallo,

    Überlegung zwei, ich lege eine Tabelle an mit „sprachen“ dort befinden sich drei Spalten „id, userID, Sprache“  Alle Felder die vom User angeklickt werden, werden schmerzlos untereinander in dieser Tabelle gespeichert.

    Dieser Beziehungstyp nennt sich Many to many bzw. aus Sicht eines Model-Objekts »has and belongs to many« oder, wenn es ein eigenständiges Zwischen-Model gibt, »has many through«. Viele Webframeworks bringen dafür eine Standardlösung mit, die i.d.R. auf einer solchen Join-Table basiert. Das ist eine vergleichsweise komplexe, aber flexible Lösung. Webframeworks nehmen einem auch das Aktualisieren der Beziehungen ab. D.h. wird eine Sprache oder ein User gelöscht, werden alle Einträge mit entsprechendem Foreign-Key in der Join-Table gelöscht.

    Ich merke jetzt schon, hier kommen sehr viele Probleme auf mich zu oder? Wie speichert ihr solche Daten?

    Die von dir beschriebenen Probleme sind bereits gelöst worden. Ich würde vorschlagen, du nimmst eine fertige Lösung, es sei denn, du willst es zum Lernen unbedingt selbst umsetzen. Benutzt du bereits irgendein MVC- oder ORM-Framework?

    Mathias

    1. Die von dir beschriebenen Probleme sind bereits gelöst worden. Ich würde vorschlagen, du nimmst eine fertige Lösung, es sei denn, du willst es zum Lernen unbedingt selbst umsetzen. Benutzt du bereits irgendein MVC- oder ORM-Framework?

      Nicht wirklich, bis jetzt habe ich alles selber zusammen gestellt, wie du sicherlich aus meinen älteren Postings schon mitbekommen hast. Wenn es etwas fertiges gibt, würde ich natürlich gerne darauf aufbauen, man muss ja nicht alles neu erfinden oder selber zusammen bauen.

      1. Hallo,

        Wenn es etwas fertiges gibt, würde ich natürlich gerne darauf aufbauen, man muss ja nicht alles neu erfinden oder selber zusammen bauen.

        Ich kenne mich bei PHP nicht aus, aber Propel und Doctrine sind m.W. eigenständige ORM-Lösungen und beide erlauben Many-to-Many-Beziehungen.

        http://propelorm.org/documentation/04-relationships.html
        http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html

        Wie komfortabel sich diese mit Formularen aktualisieren lassen, weil ich nicht. Größere Webframeworks machen das jedenfalls (halb-)automatisch. Man schickt einfach im Formular eine Liste relationsname_ids[] und das Framework erzeugt und löscht die entsprechenden Verbindungen.

        Mathias

  4. Vielen Dank für eure Hilfe,  mein fertiger Code sieht nun wie folgt aus, ist dieser soweit ok, sprich kann ich damit arbeiten, oder sollte ich noch etwas ändern. Da ich am Anfang stehe, ist dieses jetzt noch problemlos Möglich.

    Meine Tabelle für Sprachen, die vom User ausgewählt werden

      
    CREATE TABLE IF NOT EXISTS `sprachen_user` (  
    `su_id` int(11) NOT NULL,  
      `su_userID` varchar(200) NOT NULL,  
      `su_sprachenID` varchar(200) NOT NULL  
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=15 ;  
    
    

    Wenn ein Eintrag vorhanden ist, sieht dieser so aus

      
    INSERT INTO `sprachen_user` (`su_id`, `su_userID`, `su_sprachenID`) VALUES  
    (13, 'c320b10a9dcb0e729cc70b8e072c0c2b', '1'),  
    (14, 'c320b10a9dcb0e729cc70b8e072c0c2b', '4');  
    
    

    Meine Tabelle für „sprachen“ die dem User zur Verfügung stehen

      
    CREATE TABLE IF NOT EXISTS `sprachen` (  
    `s_id` int(11) NOT NULL,  
      `s_titel` varchar(200) NOT NULL,  
      `s_bezeichnung` varchar(200) NOT NULL  
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;  
    
    

    Dieser Inhalt sieht so aus

      
    INSERT INTO `sprachen` (`s_id`, `s_titel`, `s_bezeichnung`) VALUES  
    (1, 'Deutsch', 'deutsch'),  
    (2, 'Holländisch', 'hollaendisch'),  
    (3, 'Tschechisch', 'tschechisch'),  
    (4, 'Türkisch', 'tuerkisch'),  
    (5, 'Russisch', 'russisch');  
    
    

    Meine Checkboxen lasse ich dynamisch zusammen bauen, dieses habe ich so umgesetzt

      
            <form name="form1" method="post" action="">  
            <?php  
    		$stmt = $mysqli->prepare("SELECT s_id, s_titel, s_bezeichnung FROM sprachen");  
    		$stmt->execute();  
            $stmt->bind_result($s_id, $s_titel, $s_bezeichnung);  
    		while($stmt->fetch()) {  
    		?>  
              <input name="lang[]" type="checkbox" id="<?php echo $s_bezeichnung;?>" value="<?php echo $s_id;?>" <?php echo (in_array($s_id,$teile)?'checked="checked"':NULL) ?>>  
              <label for="<?php echo $s_bezeichnung;?>"><?php echo $s_titel;?></label>  
            <br>  
    		<?php  
    		}  
    		?>  
            <br>  
              <input type="submit" name="abschicken" id="abschicken" value="Daten eintragen">  
            </form>  
    
    

    Mein Insert & gegebenenfalls löschen sie so aus

      
    if(isset($_POST['abschicken'])){  
    	  
      $id = $user_code;	  
      $stmt = $mysqli->prepare("DELETE FROM sprachen_user WHERE su_userID=?");  
      $stmt->bind_param("s",$id);  
      $stmt->execute();  
      
      if(is_array($_POST["lang"]) && $_POST["lang"][0]){  
    	  
    	foreach($_POST["lang"] as $v){  
    		  
    	$stmt = $mysqli->prepare("INSERT INTO sprachen_user (su_userID, su_sprachenID)  VALUES (?, ?)");  
    			  
    			$su_sprachenID 	= $v;  
    			$su_userID	= $user_code;  
    			  
    			$stmt->bind_param("ss", $su_userID, $su_sprachenID);			  
    			$stmt->execute();  
    	}}  
    
    

    Jetzt kommt noch das anklicken meiner Boxen, wenn ein User auf die Seite kommt um seine Sprachen zu bearbeiten, dieses setzte ich wie folgt um

      
    	$teile = array();  
      
        $stmt = $mysqli->prepare("SELECT  
    			web_users.user_code,  
    			sprachen_user.su_userID,  
    			sprachen_user.su_sprachenID  
    								  
    			FROM web_users  
    			LEFT JOIN sprachen_user  
    								  
    			ON web_users.user_code = sprachen_user.su_userID  
    								  
    			WHERE user_session=?");  
    	  
        $stmt->bind_param("s", session_id());  
        $stmt->execute();  
        $stmt->bind_result($user_code, $su_userID, $su_sprachenID);  
      
    	while($stmt->fetch()) {  
    	      $teile[] = $su_sprachenID;  
              }  
    
    
  5. hi,

    Ein Ansatz habe ich bei Joomla gesehen, hier werden alle Daten in EINEM Feld gespeichert mit einem , getrennt, aber ich gehe davon aus, dass dieses noch um einiges schwerer ist zu speichern, bearbeiten und löschen?

    Billiglösung ;)

    Wenn Du direkt adressieren möchtest (was Insert, Delete, Update erleichtert), brauchst Du _zwei_ Felder, eins für den Array-Index und eins für den Wert. Ich würde mich da schon eher in Richtung ORM (wurde hier auch genannt) bewegen, die Datenhaltung ist da soweit abstahiert, dass Du im Code mit dem User als Objekt hantierst, Attribute sind Name, Vorname usw., die Sprache ist dann ein Array und SQL-Statements sind komplett raus aus Deinem Code.

    $User->lang(3) = 'de';

    wäre z.B. ein Methoden-Aufruf für eine User-Instanz und einer Left-Value-Methode und

    $User->write();

    der Aufruf einer Methode, welche die geänderten Daten eines Benutzer-Objekts wieder persistent macht.

    Es ist auch nicht weiter schwierig, einen ORM selbst zu entwickeln, wir kochen alle nur mit Wasser.

    Zu Deinem Code weiter unten, Stichwort Session: Auch wenn $_SESSION eine globale Variable ist, ich würde da einen Wrapper draufsetzen, sprich, eine Funktion wo direkt die User-ID eines in der Session angemeldeten Benutzers liefert. Der Wrapper könnte eine class Session{} sein, nicht der OOP willens, sondern einfach nur deswegen, dass der Code übersichtlicher wird und die in der Session abgelegten Datenstrukturen klar definiert sind.

    Horst