[PHP] Sessions / temporärer Speicher für Session-Varaiblen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Sebastian.S
Beiträge: 437
Registriert: 13.04.2003 13:17:41

[PHP] Sessions / temporärer Speicher für Session-Varaiblen

Beitrag von Sebastian.S » 09.09.2003 12:22:42

Hallo,
wie bereits vor kurzem erwähnt, hat ein freier Mitarbeiter meines neu angemeldeten Gewerbebetriebes das "bestellsystem", das hier auf dfde für die T-Shirts benutzt wurde so angepasst, dass es schon fast ein kleiner Internet-Shop war.
Alles lief wunderbar, jedoch gab es einige Kritikpunkte, die mir nicht so gut gefielen. Außerdem musste ich sowieso schon (mit faktisch nicht vorhandenen PHP-Kentnissen) die Ursache dafür suchen, dass in einer Funktion eine globale statt lokale Variable verwendet wird.
Also habe ich mir kurzerhand das Buch "Programmieren mit PHP" aus dem O'Reilly-Verlag besorgt und entwickle den "Shop" jetzt von Grund auf neu, weil der Quelltext meines freien Mitarbeiters so unübersichtlich ist, dass eine einzige if-Bedingen auf 10 Bildschirmzeilen verteilt ist (!!!!).

Jetzt aber zu meiner Frage:

Wie bereits angedeutet geht es bei meinem Vorhaben um eine Art Warenkorbsystem. Ein Benutzer kann Produkte in den Warenkorb reinlegen, die Anzahl ändern, Produkte wieder löschen etc. Man kennt das ja.
Zum Zwecke der temporären Datenspeicherung, welche Produkte in welcher Menge der Kunde nun zu kaufen beabsichtigt, habe ich mich an die Idee des freien Mitarbeiters gehalten, der hierfür eine Datenbank verwendet hat, in der Artikelnummer, Session-ID und anzahl gespeichert werden.
Jedoch habe ich ein Problem, wenn ein Kunde Dinge in den Warenkorb legt und es sich dann doch anders überlegt und die Seite verlässt. Temporär-Daten werden dann *nicht* aus der SQL-DB gelöscht, sondern bleiben unnötigerweise dort solange erhalten, bis sich die Speicherplatzbeschränkung zu Worte meldet.
Gibt es eine Lösung für das Problem? Kann ich etwas machen, dass die Reihen der Datenbank (WHERE uid=session_id();) gelöscht werden, wenn die Session abgelaufen ist?
Humanity stands at a crossroads. [...] Will we evaluate, learn and profit
from [...] these new ideas and opportunities, or will we [...] suppress all of this in favor of
intellectually weak, [...] and sometimes brutally unfair
and inefficient policies?

Benutzeravatar
Sebastian.S
Beiträge: 437
Registriert: 13.04.2003 13:17:41

Beitrag von Sebastian.S » 09.09.2003 12:32:23

ich kann ja mal die Funktion posten, die bisher den Warenkorb ausgibt (in meinem neuen System, nicht im "erweiterten bestellsystem"). Für die Bennenung der Tablle (produkt_owner) bin ich nicht verantwortlich, sondern ich habe mich bemüht die Tabellenstruktur des erweiterten bestellsystems einigermaßen eiunzuhalten:

(Natürlich fehtl auch noch der HTMl-Output, deshlab habe ich solange "optische plaintexttrenner" (EEEEEEEEE) verwendet.

Code: Alles auswählen

function write_storecart($result) {
	// INITIATOR: *get_content(storecart);*
	$storecart_has_content = false; // Initialization
	while (list($uid, $pid, $anzahl) = mysql_fetch_row($result)) {
		echo "Session: $uid EEEEEEEEE Artikel: $pid EEEEEEEEE Anzahl: $anzahl
		EEEEEEEEE NEXT NEXT EEEEEEEEE";

		$storecart_has_content = true;

	} // end while
	if ($storecart_has_content) {
		// The customer has bought at least one product
		echo "<a href=\"pay.php\">Zahlen, bitte!</a>";
	}
	else {
		// The customer has not bought any product
		echo "Nix drin!";
	}
	} // end function
Die Funktion die für das Hinzufügen für Produkte zuständig ist:

Code: Alles auswählen

session_start();
$user = session_id();

// ... gekürzt ...

if (isset($buy)) {
	global $number;
	$delete = false;
	$query = sprintf("SELECT * FROM produkt_owner WHERE pid='$buy' AND 		uid='$user'");
	$result = mysql_query($query);
	list($uid, $pid, $number_already_set) = mysql_fetch_row($result);
	unset ($uid, $pid);
	if (!$number_already_set) {
		$query = sprintf("INSERT INTO produkt_owner (uid, pid, anzahl) VALUES 			('$user', '$buy', '$number1')");
		$result = mysql_query($query);
  	}
	if ($number_already_set) {
		if (isset($number)) {
			$number_is = $number;
			if ($numer == 0) {
				$delete = true;
			}
		}
		else {
			$number_is = $number_already_set + $number1;
		}

		if (!$delete) {
			$query = sprintf("UPDATE produkt_owner SET anzahl=$number_is WHERE pid='$buy' AND uid='$user'");
		}
		else {
			$query = sprintf("DELETE FROM produkt_owner WHERE pid='$buy' AND uid='$user'");
		}
		$result = mysql_query($query);
	}
}
Bitte nicht über den Code meckern, das ist das allererste, was ich in PHP mache und: ES LÄUFT!!
Humanity stands at a crossroads. [...] Will we evaluate, learn and profit
from [...] these new ideas and opportunities, or will we [...] suppress all of this in favor of
intellectually weak, [...] and sometimes brutally unfair
and inefficient policies?

LittleBoy
Beiträge: 718
Registriert: 30.04.2002 14:32:26

Beitrag von LittleBoy » 11.09.2003 10:51:17

Ich hätte es grundsätzlich anders organisiert - sprich den Warenkorb als SESSION-Variable genommen (die Session-Variablen kann man ja, wenn man mag trotzdem in MySQL stecken) und erst wenn die Bestellung getätigt wird, das ganze in MySQL packen. Das wäre imho die sauberste Lösung.
In der Art:
function add_to_basket($produkt)
{
array_push($_SESSION["Basket"], $produkt);
}

An sonsten würde ich ein Timestamp und ein confirmed-flag mit in die MySQL setzen, und halt über einen cron-job alle Bestellungen, die nicht confirmed aber älter als ein Tag sind, löschen.

Das Problem ist, dass PHP nicht so ohne weiteres feststellen kann, wann eine Session abgelaufen ist.
Und wenn du mit Session arbeitest - egal in welcher Form - solltest du auf jeden Fall die Hinweise auf: http://www.php.net/manual/de/ref.session.php berücksichtigen, um die Daten des Kunden zu schützen.

Benutzeravatar
L@w
Beiträge: 916
Registriert: 24.07.2002 08:12:30

Beitrag von L@w » 11.09.2003 11:03:01

du könntest ja in deine Session einen timstamp einbauen und wenn der allter als eine stunde ist, werden die daten von der sql datenbank gelöscht. das passiert halt dann wenn sich der kunde neu "einloggt". nur kann es halt passieren, dass die tabelle mal total gross wird.

würde es auch nur über sessions machen.
cu L@w
---

LINUX - because booting is for adding hardware!

Benutzeravatar
Sebastian.S
Beiträge: 437
Registriert: 13.04.2003 13:17:41

Beitrag von Sebastian.S » 11.09.2003 15:32:48

LittleBoy hat geschrieben:Das wäre imho die sauberste Lösung.
In der Art:
function add_to_basket($produkt)
{
array_push($_SESSION["Basket"], $produkt);
}
Das Problem ist aber, dass neben $produkt (sprich: Artikelnummer) auch eine mit der Artikelnummer assoziierte Anzahl (wie of will der Kunde dieses Produkt haben) gespeichert werden muss.
http://www.php.net/manual/de/ref.session.php berücksichtigen, um die Daten des Kunden zu schützen.
Danke für den Hinweis.
Humanity stands at a crossroads. [...] Will we evaluate, learn and profit
from [...] these new ideas and opportunities, or will we [...] suppress all of this in favor of
intellectually weak, [...] and sometimes brutally unfair
and inefficient policies?

Antworten