[PHP+mySQL] Warenkorb basteln!

m7media

since 2001
ID: 324964
L
7 Mai 2006
855
70
Hallo,

Ich habe mir gerade ein Schönes und funktionierendes Shopsystem gebaut. OHNE Warenkorb. Allerdings will ich nun langsam was mit Warenkorb 8) Daher meine Frage: Wie kann ich das am einfachsten basteln? Ich dachte dabei an folgendes System:

mySQL-Tabelle mit IP und Waren-ID (Artikel-ID's folgendermaßen aufgelistet: 1,2,3,4). Dann bei der Anzeige des Warenkorb-Inhalts eben die Kommas Entfernen, die Zahlen im Array irgendwie speichern und mit ner While-Schleife das jeweilige Produkt anzeigen. Allerdings raff ich das mit den Arrays nich. Und ich weiß nich ob das System so gut ist... Also eure Hilfe ist gefragt ;) Wie geht das mit den Arrays am einfachsten und ist es überhaupt gut so zu machen?
 
Zum Deinem momentanen Problem:

Wieso willst Du bei Deiner Tabellenstruktur die Waren-IDs denn zusammengefasst speichern? Mit genau der gleichen Struktur kannst Du sie ja auch atomar speichern und auslesen und somit Dein Problem mit dem Array umgehen.

Zum eigentlichen Problem:

Lediglich IP-basiert in der DB speichern ist für einen Warenkorb eigentlich keine gute Idee, da sich bei den meisten Usern die IP mindestens einmal am Tag ändern wird. Somit wird sich in der Tabelle im Laufe der Zeit 'ne ganze Menge ansammeln und im ungünstigsten Fall bekomme ich als Besucher Deines Shops irgendwann einen Warenkorbinhalt angezeigt, der gar nicht meiner ist.

Besser wäre es, den Warenkorb im Cookie oder in der Session zu speichern - je nachdem, ob der Warenkorb bis zum nächsten Besuch erhalten bleiben soll oder nicht.
 
Stimmt, Sessions wäre natürlich ne Gute Sache. Garnich überlegt. Aber wie geht das denn mit dem Atomar speichern? das hab ich grad kein Meter gerafft :oops:
 
Atomar speichern hiesse, dass Du die Werte nicht zusammenfasst, sondern einfach in der Tabelle für jeden Artikel eine neue Zeile einträgst. Somit musst Du lediglich alle Zeilen auslesen und hast direkt die zu verarbeitenden Werte. Kein String-Rumgefrickel mehr... ;)
 
Atomar speichern hiesse, dass Du die Werte nicht zusammenfasst, sondern einfach in der Tabelle für jeden Artikel eine neue Zeile einträgst. Somit musst Du lediglich alle Zeilen auslesen und hast direkt die zu verarbeitenden Werte. Kein String-Rumgefrickel mehr... ;)
das wäre natürlich einfacher, aber ich denke das würde die Datenbank doch schon stärker belasten oder? ;)

Edit: Mir fällt gerade ein - Man will natürlich auch die Menge bestimmen und Artikel entfernen. Wird also wohl doch noch etwas härter :$
 
das wäre natürlich einfacher, aber ich denke das würde die Datenbank doch schon stärker belasten oder? ;)
Ne, das passt schon. ;)

Edit: Mir fällt gerade ein - Man will natürlich auch die Menge bestimmen und Artikel entfernen. Wird also wohl doch noch etwas härter :$

Naja, in etwa so könnte die Tabelle aussehen:

benutzerId - artikelId - artikelMenge

Wenn du den Warenkorb für einen Benutzer auslesen möchtest, suchst du alle Zeilen mit der entsprechenden benutzerId. Wenn du einen Artikel entfernen möchtest brauchst du die artikelId und die artikelMenge, die entfernt werden soll. Wenn die artikelMenge in der DB 1 ist, dann kannst du die Zeile löschen, sonst den Wert artikelMenge verändern.

edit: Sehe gerade du willst es über Sessions ohne Benutzeraccounts machen. Dann nimm als benutzerId einfach die sessionId. ;)

Gruß, Zera
 
Naja, in etwa so könnte die Tabelle aussehen:

benutzerId - artikelId - artikelMenge

Wenn du den Warenkorb für einen Benutzer auslesen möchtest, suchst du alle Zeilen mit der entsprechenden benutzerId. Wenn du einen Artikel entfernen möchtest brauchst du die artikelId und die artikelMenge, die entfernt werden soll. Wenn die artikelMenge in der DB 1 ist, dann kannst du die Zeile löschen, sonst den Wert artikelMenge verändern.
nun gut, mit datenbank sieht es für mich um einiges leichter aus, bin eher ein Datenbank-vergewaltiger :biggrin: ich werde wohl erstmal per Datenbank programmieren. Andere Frage.. wäre es auch gut wenn ich einfach für jeden eintrag mit IP noch n timestamp speicher, wenn der älter als 24h is wird alles gelöscht? so könnte man doch das problem mit der IP und dem falschen Warenkorb geschickt umgehen (um nicht zu sagen, es wäre gefickt eingeschädelt :p)
 
Andere Frage.. wäre es auch gut wenn ich einfach für jeden eintrag mit IP noch n timestamp speicher, wenn der älter als 24h is wird alles gelöscht? so könnte man doch das problem mit der IP und dem falschen Warenkorb geschickt umgehen (um nicht zu sagen, es wäre gefickt eingeschädelt :p)

Darauf würde ich mich nicht verlassen. Die IP ist keine zuverlässige Möglichkeit einen Benutzer zu identifizieren (wechselt bei den meisten Providern alle 24h, manche Provider nutzen IP-Pools, es gibt Proxys). Du solltest wiederkehrende Besucher entweder über einen Login oder über einen Cookie (Session) identifizieren.

Auch wenn die Chance nicht sehr groß ist, dass ein Benutzer die IP eines früheren Benutzers der letzten 24h hat. Ich fände es als Besucher sehr komisch wenn ich das erste mal auf eine Seite komme und dort der Warenkorb bereits gefüllt ist. ;)

Gruß, Zera
 
Darauf würde ich mich nicht verlassen. Die IP ist keine zuverlässige Möglichkeit einen Benutzer zu identifizieren (wechselt bei den meisten Providern alle 24h, manche Provider nutzen IP-Pools, es gibt Proxys). Du solltest wiederkehrende Besucher entweder über einen Login oder über einen Cookie (Session) identifizieren.

Login ist ja vorhanden, allerdings sollen ja auch Gäste n Warenkorb zusammen stellen dürfen ;) und die 24h kann man ja auch durch 6h o.Ä ändern ;)
 
[...]bin eher ein Datenbank-vergewaltiger :biggrin:
Das ist aber nicht gut. Ich würde dir raten, diesen Link mal ausgiebig zu vergewaltigen ;)

Wie schon gesagt, IP reicht nicht, da die wechselt (wenn ein Warenkorb verloren geht, ärgert zwar den Kunden, is aber ned so schlimm...) und es durchaus vorkommt, dass mehrere Besucher dieselbe IP haben - z.B. aus einem Heimnetzwerk heraus (..., wie wenn sich diese Besucher einen Warenkorb teilen müssen :ugly:).
Andere Frage.. wäre es auch gut wenn ich einfach für jeden eintrag mit IP noch n timestamp speicher, wenn der älter als 24h is wird alles gelöscht?
Für das brauchst du eine weitere Tabelle, die nur die SessionID (Fremdschlüssel in der Warenkorb-Artikel-Tabelle) und den Timestamp der letzten Änderung enthält. Zum Aufräumen holtst du dir einfach die SessionIDs und fegst mit 2 Queries beide Tabellen leer.
Ich poste Code, weil ich mir sicher bin, dass du sonst mit while()-Schleife jede Zeile einzeln DELETEn würdest :ugly:
PHP:
// $db is meine Datenbank-Klasse 8-)

// alte SessionIDs holen
$res=$db->queryf("SELECT `sessionid` FROM `sessions` WHERE `lastchange`<UNIX_TIMESTAMP()-24*3600");
// welche zu löschen ?
if($db->num_rows($res))
{
  // ID-Liste erstellen
  $ids=array();
  while($row=$db->fetch_array($res))
    $ids[]="'".$row['sessionid']."'"; // 'xx' setzen, da SessionID ein String ist
  $ids=implode(',',$ids);

  // Aus beiden Tabellen alle Datensätze mit dieser SessionID löschen
  $db->queryf("DELETE FROM `sessions` WHERE `sessionid` IN (%s)",$ids);
  $db->queryf("DELETE FROM `basket_articles` WHERE `sessionid` IN (%s)",$ids);
}
// aufräumen
$db->free_result($res);
Anmerkung: Mit MySQL5 müsstest du evtl. den ganzen obigen Codeblock durch eine einzige Query ersetzen können :think:
Code:
[FONT=Courier New][B][COLOR=#9932cc]DELETE[/COLOR][/B] [B][COLOR=#9932cc]FROM[/COLOR][/B] `sessions`,`basket_articles`
[B][COLOR=#9932cc]WHERE[/COLOR][/B] `sessionid` [B][COLOR=#9932cc]IN[/COLOR][/B] [COLOR=DarkOrchid]([/COLOR]
  [B][COLOR=#9932cc]SELECT[/COLOR][/B] `sessionid`
  [B][COLOR=#9932cc]FROM[/COLOR][/B] `sessions`
  [B][COLOR=#9932cc]WHERE[/COLOR][/B] `lastchange`<[B][COLOR=#9932cc]UNIX_TIMESTAMP[/COLOR][/B][COLOR=#9932cc]([/COLOR][COLOR=#9932cc])[/COLOR]-24*3600
[COLOR=DarkOrchid])[/COLOR][/FONT]
(ungetestet; hab MySQL5 erst n paar Wochen installiert :oops: )

Wegen den Keksen:
Normal (mit default-Konfiguration) setzt PHP den Session-Keks automatisch, da musst du nur session_start() und dein $_SESSION[]-Array benutzen und es funktioniert.
Wer keine Kekse akzeptiert, naja, auf diese Besucher würde ich verzichten.
 
Zuletzt bearbeitet:
:-?

PHP:
DELETE FROM `basket_articles` INNER JOIN `sessions` USING sessionid WHERE `lastchange`<UNIX_TIMESTAMP()-24*3600

PHP:
DELETE FROM `sessions` WHERE `lastchange`<UNIX_TIMESTAMP()-24*3600