Antworten auf deine Fragen:
Neues Thema erstellen

Einem Eintrag Mehrere Kategorien zu weiseen

L

Lukas1468

Guest

Servus PSD-tutorial Community,
ich habe folgendes Problem da ich derzeit ein Webseite baue die Einträge verwaltet und diese in Kategorien abspeichert. Die Datenbank besteht aus zwei Tabellen, in einer Tabelle werden die EInträge gespeichert und in der anderen Tabelle werden Kategorien gespeichert. Die eintragen Seite sieht wie folgendermaßen aus:
Textfelder zum erstellen des Beitrages und Checkboxen wo man maximal 3 Kategorien auswählen kann
Nun möchte ich das der Eintrag in den Kategorien abgespeichert und ich diesen später mittels dropdown wieder abfragen kann, Ich nutze Objekt Orientiertes Programmieren in PHP und als Datenbankschnittstelle PDO,
Alle ausgaben laufen über foreach abfragen

ich möchte dis erreichen

tab_beitrag:

id | beitrag
------------
1 | das ist beitrag nummer eins


tab_kateg:

id | kategorie
--------------
1 | sport
2 | unterhaltung
3 | wohnen

id_beitrag | id_kateg
---------------------
1 | 1
1 | 2
1 | 3
2 | 2
2 | 3
3 | 1
3| 3

Ich dachte mir das ich die POST parameter in die SQL query einsetzte da ich allerdings keine Ahnung habe wie ich dies tue und wie ich später dann dies abspeichere und dies dann später abfrage, hoffe ich hier auf Hilfe und auf Codebeispiele an denen ich mich Orientieren kann.

Danke im voraus :)
Gruß Lukas
 

lachender_engel

Aktives Mitglied

Ich muss zugeben, ich vestehe nicht wo Dein Problem liegt, bzw. was genau Du erwartest.
Suchst Du eine SQL-Lösung oder geht es Dir darum, wie Du die Formularfelder abschickst und auswertest? :confused:
 
L

Lukas1468

Guest

Danke fürs schnelle Antworten :)

Strenggenommen suche ich eine SQL Lösung für meine Query :) ich stehe da derzeit auf dem Schlauch weil ich nicht weis wie die SQL abfrage aussieht und wie ich die Checkboxen mittels POST in dem Beitrag zwischenspeichere und so später abfragen kann, habe mich auch bereist dumm gegoogelt bücher darüber gelesen und komme nicht auf einen grünen Zweig :D, ich hatte was gelesen von JOIN und die POST Parameter in der SQL query zusammenbasteln , da habe ich allerdings keinerlei ahnung wie ich dies umstetze

Gruß Lukas
 

lachender_engel

Aktives Mitglied

Also, ich gehe dann davon asu, dass Du das Formular absendest, richtig?! Dann hast Du in einerm $kategorien[] die Checkboxen, richtig?!
Um sie zu speichern durchläufst Du das Array mit foreach und speicherst in Deiner Verbindungstabelle den Beitrag mit der ausgwählten Kategorie ID. Ok?!
Nächster Schritt ist dann das Auslesen.
Willst Du jetzt alle Beiträge einer Kategorie suchen machst Du eine SQL-Query
Code:
SELECT id_beitrag FROM xyz WHERE id_kateg=7;
Damit bekommst Du eine LIste aller Beiträge die einer Kategorie zugehören.
So ist es dann fertig.
Oder brauchst Du noch mehr oder was anderes?
 
L

Lukas1468

Guest

Der Code zur Ausgabe von dem Beitrag nach dem aauwählen einer Kategorie:
PHP:
public function cat_content() {
            $cat_con = $this->db->query("Was muss hier rein ?");
            foreach($cat_con as $row) {
                echo "<div class='panel panel-default'>";               
                echo "<div class='panel-heading'>";       
                echo "<h3 class='panel-title'>".$row['betreff']."</h3>";
                echo "<i name='".$row['cat_id']."'>".$row['cat_rowname']."</i>";
                echo "</div>";           
                echo "<div class='panel-body'>".str_replace("\n", "<br/>",$row['content']);
                echo "</div>";               
                echo "<div class='panel-footer'>".$row['s_name']. "<br/>";
                echo "<i>".$row['c_mail']."</i>";
                echo "<i style='float: right;'>".date("d.m.Y H:i", strtotime($row['date']))."</i>";
                echo "</div>";               
                echo "</div>";
               
            }
        }

Der Code zur ausgabe der Kategorie (Checkboxen):
PHP:
public function query_check() {
            $stmt = $this->db->query("SELECT * FROM category"); 
            foreach($stmt as $row) {
                echo "<form action='' method='post'>";
                echo "<p><input type='checkbox' name='cat[]' value='".$row['cat_id']."'>".$row['cat_rowname']."</p>";
                echo "</form>";
            }
        }

Der Code zur Ausgabe der Buttons mit denen man die Kategorie auswählen kann:
PHP:
public function query_category() {
            $get = $this->db->query("SELECT * FROM category");
            foreach($get as $row) {
                echo "<form action='' method='post'>";
                echo "<button type='submit' class='btn btn-link' name='kat' value='".$row['cat_id']."'>".$row['cat_rowname']."</button><br/>";
                echo "</form>";
            }
        }

Nun möchte ich dem Beitrag die maximal drei Kategorien zuweisen ohne sie in der Datenbank zu speicherm
Ist das möglich ? wenn ja wie setze ich es um wenn nein was für alternativen gibt es ?

Danke im Voraus
Gruß Lukas
 

Duddle

Posting-Frequenz: 14µHz

Nun möchte ich dem Beitrag die maximal drei Kategorien zuweisen ohne sie in der Datenbank zu speicherm
Diesen Nebensatz verstehe ich nicht. Du hast doch eine Tabelle für die Zuweisung von Kategorie zu Beitrag.

Prinzipiell hast du schon alles genannt was du benötigst: die POST-Daten und (wahrscheinlich) ein JOIN.

Fall 1: neuer Eintrag. Du speicherst den Eintrag, merkst dir dessen ID, liest $_POST['cat'] aus und erstellst für jede Kategorie einen Eintrag in der Kategorie-Beitrag-Tabelle.
Fall 2: Eintrag anzeigen. Du holst dir per ID den Eintrag und mit einem JOIN alle Kategorien, die dieser Eintrag hat. Für einfache JOINs gibt es mehr als genügend Tutorials für MySQL (und allgemein SQL).


Duddle
 
L

Lukas1468

Guest

Nein ich habe stehst zwei Tabellen eine für die Kategorie und eine für den Eintrag :)

Wie erreiche ich denn Fall 1 und Fall 2 das weis ich nicht wie ich dies umsetzte aber trotzdem Danke für die Antwort Duddle :)

Gruß Lukas
 
Zuletzt bearbeitet von einem Moderator:

Duddle

Posting-Frequenz: 14µHz

Ich bin wieder verwirrt.
Nein ich habe stehst zwei Tabellen eine für die Kategorie und eine für den Eintrag
Auf was bezieht sich das? Laut deinem ersten Beitrag hast du drei Tabellen:
id | beitrag
------------
1 | das ist beitrag nummer eins

id | kategorie
--------------
1 | sport
2 | unterhaltung
3 | wohnen

id_beitrag | id_kateg
---------------------
1 | 1
1 | 2
1 | 3
2 | 2
2 | 3
3 | 1
3| 3
Falls hier die dritte Tabelle nur als ein "so stellst du dir die Zuweisung im theoretischen vor" angeführt wurde, dann ist der Ansatz korrekt. Du benötigst diese Tabelle.

Wie erreiche ich denn Fall 1 und Fall 2 das weis ich nicht wie ich dies umsetzte
Wo hängst du genau?
Die beiden Fälle sind sehr einfach. Meine Beschreibung ist quasi Pseudo-Code, den du nur noch in PHP/SQL übersetzen musst.


Duddle
 
L

Lukas1468

Guest

Meine Erklärungskünste scheinen ziemlich bescheiden zu sein :D

Ich habe zwei Tabellen:
Tabelle 1. Beiträge:
Code:
tab_beitrag:

id | beitrag
------------
1 | das ist beitrag nummer eins

Tabelle 2. Kategorien:
Code:
tab_kateg:

id | kategorie
--------------
1 | sport
2 | unterhaltung
3 | wohnen

Richtig die Dritte Tabelle kann ich erstellen weis allerdings nicht wie ich dies dann Umsetzte, sodass es hinterher funktioniert:)
Gruß Lukas
 
Zuletzt bearbeitet von einem Moderator:

Duddle

Posting-Frequenz: 14µHz

Du brauchst (wenn du sauber arbeiten willst) definitiv die Zuweisung mittels der dritten Tabelle. Was du hast ist eine n:m-Beziehung (ein Eintrag kann mehrere Kategorien haben, eine Kategorie kann mehreren Beiträgen zugeordnet sein) und die wird i.d.R. mit einer dritten Tabelle aufgelöst.

Die Abfrage erfolgt dann per (INNER) JOIN, zumindest wenn du die Namen der Kategorien willst. Du verknüpfst damit die Informationen aus mehreren Tabellen mit von dir genannten Regeln. Zum Beispiel könntest du schreiben (angenommen tab_beitrag_kategorie ist die oben genannte):
Code:
SELECT * FROM tab_beitrag JOIN tab_beitrag_kategorie ON tab_beitrag.id = tab_beitrag_kategorie.id_beitrag
Du kannst dir das wie ein Kreuzprodukt vorstellen, aus dem alles rausgefiltert wird was nicht der "ON"-Klausel entspricht. Beispiel:

Das Kreuzprodukt aus (1, 'Foo'), (2, 'Bar'), und (1, 5), (1, 20), (2, 42) ist
(1, 'Foo'), (1, 5)
(1, 'Foo'), (1, 20)
(1, 'Foo'), (2, 42)
(2, 'Bar'), (1, 5)
(2, 'Bar'), (1, 20)
(2, 'Bar'), (2, 42)

Wenn du da jetzt sagst die x-Werte sollen gleich sein, würde das gefilterte Ergebnis so aussehen:
(1, 'Foo'), (1, 5)
(1, 'Foo'), (1, 20)
(2, 'Bar'), (2, 42)

Genau so funktioniert auch der INNER JOIN. Jetzt denkst du einen Schritt weiter, d.h. verknüpfst das Ergebnis aus dem Beispiel mit einer weiteren "Tabelle" und filterst wieder nur die gewünschten Werte per ON-Klausel, schon hast du Informationen aus Tabelle 1 mit Informationen aus Tabelle 3 mithilfe von Tabelle 2 verbunden.
Ausführlicher ist das hier erklärt.


Duddle
 
L

Lukas1468

Guest

Vielen Dank für die Super Erklärung :)
Wenn ich das jetzt richtig verstehe muss ich die beitrag_id ebenfalls in die Tabelle: tab_beitrag_kategorie mit eingetragen, wie kann ich diese auslesen oder besser gesagt gleich die autoincrement id mit in die Tabelle tab_beitrag_kategorie eintragen wenn der Eintrag gespeichert wird :) (Unter PDO)

Gruß Lukas
 
Zuletzt bearbeitet von einem Moderator:

Duddle

Posting-Frequenz: 14µHz

Wenn ich das jetzt richtig verstehe muss ich die beitrag_id ebenfalls in die Tabelle: tab_beitrag_kategorie mit eingetragen
Deine Zuweisungstabelle braucht irgendwas, damit jede Zeile darin einem Eintrag und einer Kategorie zugewiesen werden kann. Eine ID (für jeweils Beitrag und Kategorie) bietet sich da an. Deshalb hatte ich auch gedacht, dass deine erster Post schon die (korrekte) Zuweisungstabelle darstellt:
Code:
id_beitrag | id_kateg
---------------------

Wenn du mit PDO und PHP arbeitest, sollte lastInsertId die letzte ID geben, die per autoincrement eingefügt wurde. Diese nimmst du dann und trägst pro gewünschter Kategorie eine Zeile in der Zuweisungstabelle ein. Das entspricht dem, was ich oben schon gesagt hatte
Fall 1: neuer Eintrag. Du speicherst den Eintrag, merkst dir dessen ID, liest $_POST['cat'] aus und erstellst für jede Kategorie einen Eintrag in der Kategorie-Beitrag-Tabelle.


Duddle
 
L

Lukas1468

Guest

Danke dafür :)
Das funktioniert soweit, nur wird nun wenn eine die Kategorie den Beitrag dreimal zu gewiesen, der Beitrag 3 mal ausgegeben anstatt nur 1 mal.

Mein zweites Problem ist das ich das Array was von den Checkboxen ausgeht nicht in die Datenbank bekomme;/, genauso wird die lastinsertid auf 0 gesetzt aus welchem Grund auch immer:/

Funktion zum Eintragen:
PHP:
public function cat_cont($id_beitrag, $id_kateg) {
            try {
                $cat_cont = $this->db->prepare("INSET INTO catgorie_content(id_beitrag, id_kateg) VALUES (:id_beitrag, :id_kateg)");
                $cat_cont->bindparam(":id_beitrag", $id_beitrag);
                $cat_cont->bindparam(":id_kateg", $id_kateg);
               
                $cat_cont->execute();
               
                return $cat_cont;
            } catch (PDOException $e) {
                echo $e->getMessage();
            }
       
        }

Code für das Formular:
PHP:
if(isset($_POST["eintragen"])) {
        $betreff = trim($_POST['betreff']);
        $content = trim($_POST['content']);
        $c_mail = trim($_POST['c_mail']);
        $s_name = $_SESSION['user_name'];
        $id_beitrag = $DB_con->lastInsertId();
        $id_kateg = array($_POST['cat']);
       
        if($betreff == "") {
            $error[] = "Bitte geben Sie einen Betreff ein !"; 
        }
       
        elseif($content == "") {
            $error[] = "Bitte füllen sie den Textberech aus !";
        }
       
        elseif($c_mail == "") {
            $error[] = "Bitte geben Sie eine Kontakt Email Adresse ein";
        }
        elseif(!filter_var($c_mail, FILTER_VALIDATE_EMAIL)) {
            $error[] = "Bitte geben Sie eine verfügbare E-Mail Adresse ein !";
        }
        elseif(strlen($betreff) < 10) {
            $error[] = "Der Betreff muss mindestens 10 Zeichen haben !";
        }
       
        elseif(strlen($content) < 50) {
            $error[] = "Das Textfeld muss mindestens 50 Zeichen haben ";
        }
       
        elseif((count($id_kateg) > 3)) { 
            $error[] = "Bitte nur maximal 3 Kategorien auswähl"; 
        }
       
        elseif((count($id_kateg) == 0)) {
            $error[] = "Bitte wählen sie eine Kategorie aus";
        }
        else {
            if($query->beitrag($betreff, $content, $s_name, $c_mail) && $query->cat_cont($id_beitrag ,$id_kateg)) {
                $user->redirect('getin.php?=true');
            }
        }
    }

Gruß Lukas
 

Duddle

Posting-Frequenz: 14µHz

Das funktioniert soweit, nur wird nun wenn eine die Kategorie den Beitrag dreimal zu gewiesen, der Beitrag 3 mal ausgegeben anstatt nur 1 mal
Zeig mal den Code dafür.

Mein zweites Problem ist das ich das Array was von den Checkboxen ausgeht nicht in die Datenbank bekomme;/,
$_POST['cat'] ist schon ein Array, du musst es also nicht nochmal umwandeln. Ausserdem übergibst du es an eine Funktion, die nur einen Wert behandelt, statt das ganze Array abzufragen. Entweder musst du also in cat_cont() durch das Array gehen oder in deinem letzten else-Zweig vom Eintragen-Code.

genauso wird die lastinsertid auf 0 gesetzt aus welchem Grund auch immer:/
Dein Code zeigt zu wenig um die Fehlerquelle eingrenzen zu können. Arbeitest du mit MySQL? Benutzt du Transaktionen? Falls ja, musst du lastInsertId abfragen bevor du den Commit durchführst.
Falls du eine Klasse benutzt und die automatisch für dich nach jedem Query commitet, könntest du (abhängig vom DBMS) bspw. bei MySQL LAST_INSERT_ID() anfragen, obwohl das in Ausnahmefällen zu Fehlern führen könnte.


Duddle
 
L

Lukas1468

Guest

$_POST['cat'] ist schon ein Array, du musst es also nicht nochmal umwandeln. Ausserdem übergibst du es an eine Funktion, die nur einen Wert behandelt, statt das ganze Array abzufragen. Entweder musst du also in cat_cont() durch das Array gehen oder in deinem letzten else-Zweig vom Eintragen-Code.

Könntest du mir dafür ein Beispiel geben ?:)
Dies ist die Fehlermeldeung beim eintragen:

Das $DB_con ist durch die Klasse eine art globale Variable mit der ich auf die Datenbank zu greifen kann.

Code:
Notice: Array to string conversion in C:\xampp\htdocs\SWB\classes\query.php on line 36
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSET INTO catgorie_content(id_beitrag, id_kateg) VALUES ('0', 'Array')' at line 1



Dies ist die Funktion für die Ausgabe des Beitrages:
PHP:
public function cat_content() {
            $cat_con = $this->db->query("SELECT * FROM content JOIN categorie_content ON content.content_id = categorie_content.id_beitrag");
            foreach($cat_con as $row) {
                echo "<div class='panel panel-default'>";            
                echo "<div class='panel-heading'>";    
                echo "<h3 class='panel-title'>".$row['betreff']."</h3>";
                echo "</div>";        
                echo "<div class='panel-body'>".str_replace("\n", "<br/>",$row['content']);
                echo "</div>";            
                echo "<div class='panel-footer'>".$row['s_name']. "<br/>";
                echo "<i>".$row['c_mail']."</i>";
                echo "<i style='float: right;'>".date("d.m.Y H:i", strtotime($row['date']))."</i>";
                echo "</div>";            
                echo "</div>";
            
            }
        }

Das ist die Abfrage falls eine Kategorie ausgewählt wurde:
PHP:
if(isset($_POST["kat"])) {
                            $getout->cat_content();
                        } else {
                            $getout->query_content();
                        }

Gruß Lukas
 
Zuletzt bearbeitet von einem Moderator:

Duddle

Posting-Frequenz: 14µHz

Könntest du mir dafür ein Beispiel geben
Du benutzt doch schon foreach, ich bin mir nicht klar warum du das nicht übertragen kannst.

Für den zweiten Teil bin ich mir nicht sicher, was du genau machen willst. Ich habe es so verstanden, dass du für einen Eintrag alle Kategorien anzeigen lassen willst, aber dein letzter Code-Abschnitt ("falls eine Kategorie ausgewählt wurde") deutet darauf hin, dass du eine Art Suche nach Beiträgen mit dieser Kategorie ausführen willst.
Dein cat_content() sieht auch eher nach einer Ausgabe-Funktion für alle Beiträge mit einer bestimmten Eigenschaft aus. Aber da ist die SQL-Abfrage unpassend und es wird auch nichts als Parameter übergeben.

Kannst du bitte nochmal exakt formulieren, welche einzelnen Anwendungsfälle noch nicht funktionieren und wie diese exakt ablaufen sollen?


Duddle
 
L

Lukas1468

Guest

Der Plan war so:
Man soll beim erstellen eines Eintrages maximal 3 Kategorien auswählen können

Man kann Kategorien eintragen bearbeiten und löschen.

Funktionieren tut derzeit das Eintragen aber nicht die abspeicherung des Beitrages in die Kategorien. Man trägt über ein Formular seinen Beitrag ein und wählt die Kategorien aus, diese sollen mittels der POST methode empfangen werden und an eine Funktion weiter geleitet werden die dies in die Datenbank einträgt. Wenn man nun einen Button drückt sollen alle Beiträge die einer Kategorie angehören ausgegeben werden, wenn kein Button gedrückt wurde sollen alle Beitrge ausgegeben werden

Hoffe es wahr verständlich :)

Gruß Lukas
 

Duddle

Posting-Frequenz: 14µHz

wählt die Kategorien aus, diese sollen mittels der POST methode empfangen werden und an eine Funktion weiter geleitet werden die dies in die Datenbank einträgt
Wenn man Kategorien auswählen kann, warum werden sie dann nochmal extra gespeichert? Eine auswählbare Kategorie ist doch schon gespeichert. Entweder ist dir nicht ganz klar was du willst, oder du drückst dich unklar aus.

Hier ist, für mich, der Ablauf:
1. Nutzer sieht Formular mit Feld für Beitrag und Mehrauswahlfeldern für die Kategorien
2. Nutzer schreibt Beitrag
3. Nutzer klickt gewünschte Kategorien
4. Nutzer sendet das Formular ab
5. Fehlerprüfung, dann Verarbeitung:
5.1. Beitrag wird in Beitrags-Tabelle geschrieben
5.2. pro ausgewählter Kategorie wird eine Zeile in der Beitrag-Kategorie-Tabelle geschrieben

Für sowohl 5.1 hast du wahrscheinlich schon den Code, für 5.2 habe ich die Vorgehensweise mehrfach erläutert.

Wenn man nun einen Button drückt sollen alle Beiträge die einer Kategorie angehören ausgegeben werden, wenn kein Button gedrückt wurde sollen alle Beitrge ausgegeben werden
Das ist ein komplett anderer Anwendungsfall und unabhängig vom Eintragen. Um alle Beiträge einer bestimmten Kategorie anzuzeigen musst du dir (per JOIN) die Kategorien pro Beitrag holen und (per WHERE) nach dieser Kategorie filtern.

Ich verstehe nicht, bei welchem Schritt du hängst. Offensichlich hast du ja schon PHP geschrieben, und den SQL-Teil habe ich erklärt und mit Anleitungen verlinkt.


Duddle
 
L

Lukas1468

Guest

Genauso soll es funktionieren.
ich habe per phpmyadmin die ids zugestellt um die SQL zur Beitrag-Kategorie-Tabelle zu prüfen. Die Kategorien werden noch nicht übergeben und in der Beitrag-Kategorie-Tabelle eingetragen. ich bekomme das Array der Checkboxen nicht in die Eintragenfunktion genauso wie die ID des Beitrages wird ebenfalls nicht in die Beitrag-Kategorie-Tabelle eingetragen. Das sind derzeit meine Probleme. Ich weis nicht wie ich den PHP teil schreibe.

Gruß Lukas
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Neueste Themen & Antworten

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.616
Beiträge
1.538.358
Mitglieder
67.536
Neuestes Mitglied
QuestionMark
Oben