Hilfe bei OOP-Warenkorb
Andreas
- php
0 Mulder0 Andreas
0 Philipp Hasenfratz
Hallo!
Inzwischen probiere ich mal einen Warenkorb mit Hilfe der OOP in PHP zu realisieren. OOP ist die eine Sache, Modularität die andere. Ich möchte ein Warenkorb-Modul, auf das ich von einem PHp-Script drauf zugreifen kann, ohen dass ich irgendwelche Transaktionen(SQL-Abfagen...) vornehmen muß.
Ich wollte das jetzt erstmal zum testen mit Sessions probieren, d.h. den Warenkorb als Array in der Session speichern, nur zum probieren.
Erstmal bedanke ich mich vor allem bei Henryk, Achim, Philipp und Sven für die Hilfe bisher!(http://forum.de.selfhtml.org/archiv/2002/4/8947/, http://forum.de.selfhtml.org/archiv/2002/6/14064/, http://forum.de.selfhtml.org/?m=82625&t=14849)
Ich habe aber vor allem Probleme mit den verschiedenen 'Ebenen'. Philipps Beispiel war wirklich hilfreich, aber ich verstehe nicht, warum man da so viele Klassen für braucht?! Ich denke im Augenblick, das man mit 2 Klassen auskommen sollte, eine Warenkorb-Klasse in der man allgemeine Angaben bekommt, Artikelzahl, Summe über die Preise x Anzahl - und eine Artikel-Klasse, in der für einen Artikel der Einzelpreis, die Anzahl, eine Bezeichnung und ID stehen.
Das Problem, ich brauche eine Instanz Warenkorb, aber mehrere, sagen wir mal 3 Instanzen für die Artikel Klasse, für 3 Artikel.
Mit einer Klasse komme ich inzwischen klar(hab mal was für die Artikel geschrieben):
<?
@session_start();
class Artikel{
var $bezeichnung;
var $anzahl;
var $preis;
function plus($num) {
$anzahl = $num + $_SESSION["anzahl"];
$_SESSION["anzahl"] = $anzahl;
$this->anzahl = $anzahl;
}
function anzeigen(){
return $this->anzahl;
}
}
$artikel = new Artikel();
if ($add){
$artikel -> plus($add);
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<? echo $artikel -> anzeigen() ; ?>
<br>
<a href="<? echo $PHPSELF."?add=10"; ?>">plus
</a>
</body>
</html>
Entsprechend müßte ich sowas mit dem Warenkorb machen, eine Instanz... das sollte auch klappen, nur wie bekomme ich jetzt mehrere Instanzen für die verschiedenen Artikel? Halt dynamisch, wie ich mehrere Instanzen bekomme weiß ich wohl, aber halt genau die entsprechenden für die Artikel im Warenkorb! Kann ich das in der Warenkorbklasse machen? Wie - und wie greife ich im Script drauf zu?
Und noch ein Problem, wenn ich das jetzt mit der DB mache, und die Artikel in einer Schleife aufliste, immer mit verschieden Funktionen wie getPreis, getID, getAnzahl... und in jeder einzelnen Funktion eine SQL-Abfrage machen würde, und das für jede Instanz nochmal, dann wird das aber wohl eine Ecke unperformanter und umständlicher, als wenn ich wie 'früher' eine einzige Abfrage mache, und die in der Schleife auslese bzw. anzeige, oder?
Viele Grüße
Andreas
Entsprechend müßte ich sowas mit dem Warenkorb machen, eine Instanz... das sollte auch klappen, nur wie bekomme ich jetzt mehrere Instanzen für die verschiedenen Artikel? Halt dynamisch, wie ich mehrere Instanzen bekomme weiß ich wohl, aber halt genau die entsprechenden für die Artikel im Warenkorb! Kann ich das in der Warenkorbklasse machen? Wie - und wie greife ich im Script drauf zu?
Halte doch im Warenkorb ein Array mit den Artikeln und Mengen.
Also ein Array, das aus Instanzen der Klasse "Artikel" besteht und eines mit den zugehörigen Mengen.
Und noch ein Problem, wenn ich das jetzt mit der DB mache, und die Artikel in einer Schleife aufliste, immer mit verschieden Funktionen wie getPreis, getID, getAnzahl... und in jeder einzelnen Funktion eine SQL-Abfrage machen würde, und das für jede Instanz nochmal, dann wird das aber wohl eine Ecke unperformanter und umständlicher, als wenn ich wie 'früher' eine einzige Abfrage mache, und die in der Schleife auslese bzw. anzeige, oder?
Der WK kann doch eine Methode haben, die alle Artikel als Array zurückgibt.
Also
$artikel_daten = $warenkorb->getArticles();
echo $artikel_daten[0]->getPreis();
etc.
Hallo!
Halte doch im Warenkorb ein Array mit den Artikeln und Mengen.
Also ein Array, das aus Instanzen der Klasse "Artikel" besteht und eines mit den zugehörigen Mengen.
Ja, aber wie soll ich das machen? Der Warenkorb soll hier eine Sessionvariable sein, also ein Array mit der produktID als key und der Menge als value.
Dann will ich diesen Warenkorb anzeigen, und das über eine Klasse, so dass ich das ohne das Ausgabescript zu verändern auf eine MySQL-Lösung umstellen könnte. Brauche ich überhaupt die Artikel-Klasse?
Der WK kann doch eine Methode haben, die alle Artikel als Array zurückgibt.
Also ohne eigene Artikel-Klasse?
$artikel_daten = $warenkorb->getArticles();
Also da lese ich in getArticles() nur den Array aus der Session, bzw. aus dem Warenkorb zurück? Wann lade ich denn am besten den Array aus der Session in die Array-Variable, also Eigenschaft der Klasse? Erst bei Aufruf der Funktion, oder direkt am Anfang der Klasse? Denn das werde ich ich ja öfter bracueh können, un dgerade bei MySQL könnten viele Abfragen nachteilig sein! Kann ich nach Initiieren der Variablen in der Klasse einfach irgendwelchen PHP-Code schreiben, also der Art
class WK{
var $Farbe;
mysql_query(SELECT....)
$result=..
while($row=mysql...){
var $Artikel[] = $row[0]}
function getPreis(){
...
}
...
}
Ginge sowas?
echo $artikel_daten[0]->getPreis();
und das geht? Woher weiß getPreis() jetzt welchen Preis wir genau wollen? Wie übergeben wir denn da den Parmeter? $artikel_daten ist doch jetzt ein von der Klasse unabhängiger Array, oder?
Vielen Dank jedenfalls!
Grüße
Andreas
Halihallo Andreas
Ich habe aber vor allem Probleme mit den verschiedenen 'Ebenen'. Philipps Beispiel war wirklich hilfreich, aber ich verstehe nicht, warum man da so viele Klassen für braucht?!
ach, wirklich brauchen tut man wenig ;-)
Aber ich verfolge immer den Ansatz, möglichst gleiche Sachen auch in einer Klasse zu coden (das ist auch der Sinn von OOP). Wenn du nun z. B. getPrice aus der Warenkorbklasse aufrufen würdest (was ja unbestritten auch ginge), wäre das ein Verstoss gegen die "Vorschriften" von OOP ;)
getPrice ist _Artikel_ bezogen und nicht _Warenkorb_ bezogen. Deshalb sollte die Methode auch in einer entsprechenden Klasse zur Verfügung stehen (CartItem, oder Artikel, oder wie auch immer; auf jeden Fall nicht Cart oder Warenkorb)...
Aber am Schluss steht es jedem frei, wie komplex/einfach er die Klassen definieren will...
Wenn du wenige Klassen hast, wird eventuell die Performance besser, da du z. B. in der SQL Lösung den Price mit sum() berechnen kannst, und nicht über die OOP-Instanzen iterieren musst. Wenn du viele Klassen hast, wird die "Architektur" logischer und die Sourcelistings kürzer... Jedem das seine eben ;)
Ich denke im Augenblick, das man mit 2 Klassen auskommen sollte, eine Warenkorb-Klasse in der man allgemeine Angaben bekommt, Artikelzahl, Summe über die Preise x Anzahl - und eine Artikel-Klasse, in der für einen Artikel der Einzelpreis, die Anzahl, eine Bezeichnung und ID stehen.
Jup. Ich denke, dass dies sogar bereits genug "schön" und logisch aufgesplittet ist. User fällt ja eh weg, da dies implizit mit der Session gehandhabt wird...
Das Problem, ich brauche eine Instanz Warenkorb, aber mehrere, sagen wir mal 3 Instanzen für die Artikel Klasse, für 3 Artikel.
Entsprechend müßte ich sowas mit dem Warenkorb machen, eine Instanz... das sollte auch klappen, nur wie bekomme ich jetzt mehrere Instanzen für die verschiedenen Artikel? Halt dynamisch, wie ich mehrere Instanzen bekomme weiß ich wohl, aber halt genau die entsprechenden für die Artikel im Warenkorb! Kann ich das in der Warenkorbklasse machen? Wie - und wie greife ich im Script drauf zu?
Also ich mach das so:
getArticles
foreach (@articles) { # für jeden Artikel in der Session mach...
- $tmp = neue Instanz von Artikel...
- die Instanz in ein Array packen...
}
return InstanceArray; # das "InstanzenArray" zurückgeben
$cart = new Warenkorb;
@array_of_instances = $cart->getArticles
foreach $article (@array_of_instances) { # so, und nun möchten wir die Artikel im Warenkorb behandeln
print $article->getProductDescription;
}
Und noch ein Problem, wenn ich das jetzt mit der DB mache, und die Artikel in einer Schleife aufliste, immer mit verschieden Funktionen wie getPreis, getID, getAnzahl... und in jeder einzelnen Funktion eine SQL-Abfrage machen würde, und das für jede Instanz nochmal, dann wird das aber wohl eine Ecke unperformanter und umständlicher, als wenn ich wie 'früher' eine einzige Abfrage mache, und die in der Schleife auslese bzw. anzeige, oder?
Ja, das stimmt. Aber es ist "schöner" :-))))))
Naja, auch die schönste OOP-Architektur hat ihre Nachteile. Aber einige davon kann man vielleicht lösen...
Theoretisch wäre ja auch folgende Klasse denkbar:
getAllArticleData (einmal aufrufen, liest alle Einträge mit einem SQL-Query aus)
getAllArticlePrices (gibt nur die Price-Information als Array zurück [dazu ist dann auch keine SQL-Abfrage nötig, da vorher getAllArticleData aufgerufen wurde])
getAllArticle...
oder
getArticles (erstellt für jeden Artikel eine neue Instanz und gibt die Instanzen als Array zurück, wobei die Artikeldaten bereits und zwar nur _einmal_ mit getAllArticleData eingelesen wurden und die Daten an die Instanz mit Parametern übergeben werden => damit sind dann keine SQL-Abfragen in der Article-Instanz mehr nötig)
so, vielleicht lässt sich ich hiermit die vielen SQL-Abfragen im Warenkorb und verwante Klassen verhindern...
Viele Grüsse
Philipp