Php - Logikproblem

Liebe/-r Experte/-in,

ich ahbe mal eine generelle Logikfrage.

Also:
Nehmen wir an, ich möchte einen shop umsetzten.
Zur Vereinfachung sind nur 3 Kathegorien drin:
PCs, Autos, Schuhe.
Nun habe ich das Problem, dass jeder Artikel unterschiedliche Merkmale hat.
Natürlich kann ich eine Tabelle anlegen mit Schuhen, eine mit PCs und eine mit Autos.
Mit if-else dann die Abfrage der Kathegorie und dann daraufhin die Tabelle wählen. Also if kathegorie=pcs select * from pcs
else if kathegorie =schuhe select * from schuhe usw.

Kommt dann eine Kathegorie dazu habe ich das Problem, dass ich etliche Scripte anpassen muss, jedemal halt um ein if-Else erweitern. Vor allem bei der Artielverwaltung habe ich ein Problem. (In welche Tablle speichern).

Also habe ich die Zeilen transponiert:
attribute | objekt_id | wert | kathegorie_id
1(hersteller) | 1(PC Nr 1) |„Dell“ | 1 (PCs)

2(farbe) | 1(Schuh Nr 1)|„schwarz“| 2 (Schuhe)

3(leistung) | 11(PKW Nr 11)|„1111“ | 3 (Autos)

Meine Idee ist nun die Objekt_ids in ein Array zu packen und zB alle PCs ab zu fragen
select * from artikel where kathegorie_id=1.

while(…){
$objekt_array[]=$ausgabe[‚objekt_id‘];
}

for($x=0;$x$ausgabe[‚hersteller‘]$ausgabe[‚prozessor‘]…";
}
So bekomme ich dann die PC-Blöcke aus der Tabelle zeilenweise ausgegeben.

So weit so gut. Nur wenn ich mir vorstelle, dass da uU 3000 PCs in der DB sind, bekomme ich 3000 Abfragen.

Kann man dass uU eleganter lösen? Vor allem, wenn auf dem Server noch 10 Kunden sind, geht in die 5 stelligen
Abfragen-Bereiche.

Danke für ure Mühe!
Oliver

Lieber Oliver,

ich würde dein Problem nicht als PHP-Problem, sondern eher als Problem auf Ebene des Datenbank-Designs verorten.

Ein Vorschlag wäre z.B., folgende Tabellen anzulegen:

Kategorien

ID
Bezeichnung

Eigenschaften

ID
Bezeichnung

Produkte

ID
KategorieID (Fremdschlüssel)
Bezeichnung

ProduktEigenschaften

ID
ProduktID (Fremdschlüssel)
EigenschaftID (Fremdschlüssel)
Wert

Damit kannst du je nach Kategorie ganz flexibel verschiedene Eigenschaften anlegen und die Werte pro Produkt speichern. Ist aber abfragetechnisch nicht ganz ideal, weil du, wenn du die Tabellen joinst, für jede Eigenschaft eines Produktes eine Trefferzeile bekommst:

SELECT 
 Produkte.ID, 
 Produkte.Bezeichnung,
 Kategorien.Bezeichnung, 
 Eigenschaften.Bezeichnung, 
 ProduktEigenschaften.Wert 
FROM 
 Produkte 
 JOIN Kategorien ON Kategorien.ID = Produkte.KategorieID
 JOIN ProduktEigenschaften ON ProduktEigenschaften.ProduktID = Produkte.ID
 JOIN Eigenschaften ON Eigenschaften.ID = ProduktEigenschaften.EigenschaftID
WHERE
 Produkte.KategorieID = 1
ORDER BY
 Produkte.Bezeichnung, Produkte.ID;

Dann kannst du in PHP die Schleife bauen:

$letzteproduktid = null;
foreach ($treffer AS $t) {
 if ($t["Produkte.ID"] != $letzteproduktid) {
 // naechstes Produkt
 print "Produktbezeichnung: " . $t["Produkte.Bezeichnung"] . "
";
 } 
 // Produkteigenschaft
 print $t["Eigenschaften.Bezeichnung"] . ": " . $t["ProduktEigenschaften.Wert"] . "
";
}

–> Vorteil: Nur eine DB-Abfrage für alle Daten
–> Nachteil: Viele Schleifendurchläufe in PHP; nicht optimal.

Deshalb würde ich empfehlen:
a) einen fertigen Open-Source-Shop zu verwenden (man muss ja das Rad nicht neu erfinden, wenn’s es schon gibt) oder
b) mal in einer bestehenden Shop-Software im Quellcode zu schauen, wie die das umsetzen.

Weiter kann ich leider nicht helfen, sorry.

Herzliche Grüße
Stefan

Hi Stefan,

danke für Deine Superschnelle Antwort!!!
Mit join habe ich zugegebenermaßen noch nicht gearbeitet.

Aber das scehint die Lösung zu sein! Ich habe zwar viele Schleifen, aber die Anwesenheit anderer Kunden stört nicht. Und ich denke es ist für den Server wesentlich weniger Arbeit 1000 Schleifen zu durchlaufen und 1x Text aus dem DB-Array auszugeben, als 100 Schleifen mit je einer DB Abfrage, oder?

Es geht mir hier auch nicht um den Shop als solches, sondern um die Logik, da man diese überall einsetzten kann, wo die Problematik der Vereinigung unterschiedlichster Eigenschaften besteht. ZB könnte man daraus einen Menügenerator bauen oder oder oder oder.

„Weiter kann ich leider nicht helfen, sorry.“ Ist das ein Witz?? :wink:

Du hast Die die Mühe gemacht und den zugegeben recht langen Text von mir gelesen, Dich da reingedacht und mir kurz, knapp und verständlich eine Lösungsmöglichkeit genannt. Danke!

Ich frage mich gerade, was denn dann eine ausführliche Lösung ist. :smile:

Also nochmals ein fettes Dankeschön!
Schönes Wochenende!
Oliver

Hallo nochmal,

ich hab im PHP-Teil ein wichtiges Element vergessen:

$letzteproduktid = null;
foreach ($treffer AS $t) {
 if ($t["Produkte.ID"] != $letzteproduktid) {
 // naechstes Produkt
 print "Produktbezeichnung: " . $t["Produkte.Bezeichnung"] . "
";
 $letzteproduktid = $t["Produkte.ID"];
 } 
 // Produkteigenschaft
 print $t["Eigenschaften.Bezeichnung"] . ": " . $t["ProduktEigenschaften.Wert"] . "
";
}

(die Zeile $letzteproduktid = $t[„Produkte.ID“]:wink: - sonst wird bei jedem Durchlauf die Produktbezeichnung ausgegeben.

Für Menügeneratoren u.ä., wo also eine Hierarchie abgebildet wird, würde ich aber eher XML oder YAML benutzen als eine relationale Datenbank.

Viele Grüße
Stefan

PS
Ursprünglich hatte ich es ganz andes vor.
Wäre uU auch was für join…
Und zwar eine Tabelle Blumentoepfe Eine Tabelle PCs,Schuhe usw.

Und dann die Tabellen genau so nennen wie die Kathegorienamen.
Aber ob das klappt…

Und dann sowas wie

$kathegorie=$_GET[‚kathegorie‘];
$sql = "select * from ".$kathegorie;

Dann habe ich aber weitere Probleme, wie zB die Farbe müssten als Text hinterlegt werden, id-Verweise auf eine Tabelle zB Farben sind dann nicht mehr möglich.