PHP - Objekte in $_SESSION weitergeben geht einmal und dann nicht mehr

kazu

kazu

Aktives Mitglied
Thread Starter
Dabei seit
09.11.2005
Beiträge
1.425
Reaktionspunkte
56
Hallo,

ich programmiere gerade einen Warenkorb: Die waren sind Objekte, die ich in $_SESSION['warenkorb'] verstaue, um sie dann im Warenkorb anzuzeigen usw.

Zuerst liest ein Skript die $_POST-Variablen, erstellt ein Objekt, legt es in $_SESSION['warenkorb'] ab und includet dann die Datei, die den Warenkorb anzeigt.

PHP:
<?php

session_start();

# $_POST['Gr'] enthält die Größe der ausgewählten Ware.

# Die Klasse bereitstellen, aus der der Artikel in der gewünschten 
# Größe erzeugt wird:
include("class_Artikel.php");

if( isset($_POST['Gr']) && $_POST['Gr'] != ""){ // wurde die Größe übertragen?

	$size = $_POST['Gr'];
	# Artikel-Objekt mit der ausgewählten Größe erstellen
	$auswahl = new Artikel($size);
	
	# Wenn es den Warenkorb noch nicht gibt, dann diesen erstellen
	if( !isset($_SESSION['warenkorb']) ) $_SESSION['warenkorb'] = Array();
	
	# In die Variable ['warenkorb'] ein Array ans Ende legen, das 
	# [0] die Anzahl (1) und [1] das Artikel-Objekt enthält:
	array_push($_SESSION['warenkorb'], Array(1, $auswahl));
	
}

# Die Warenkorb-Anzeigedatei einfügen:
include("korb.php");

?>

Soweit funktioniert alles (ich hoffe ich habe beim Kürzen des Codes keinen Fehler gemacht).
Wenn nun ein Artikel vom User ausgewählt wird, kann ich ihn auch wieder aus $_SESSION['warenkorb'] auslesen und anzeigen. Soweit funktioniert es.

In der korb.php steht:

PHP:
<?php

@session_start();

if( isset($_SESSION['warenkorb']) ){ // wenn es eine Warenkorb-Variable gibt
	
	$lim = sizeof($_SESSION['warenkorb']); // Anzahl der Artikel
		
		for($i=0;$i<$lim;$i++){ // für jeden Artikel einmal ausführen:
			
			print $_SESSION['warenkorb'][$i][0]." "; # Anzahl ausgeben
			print $_SESSION['warenkorb'][$i][1]->gib_Groesse(); # Größe ausgeben
			print "<br>\r"; # Umbruch zur besseren Lesbarkeit der Ausgabe
		}
		
	}
	
}else{
	
	print "Der Warenkorb ist leer";
	
}

?>

Nun zum Problem:
Wenn ich einen zweiten Artikel hinzufüge, wird dieser wie gewünscht an das Array angehängt (habe ich mir ausgeben lassen), das Skript wird aber nach der Ausgabe der Anzahl des ersten Artikels beendet und gibt folgende Fehlermeldung:

Fatal error: main() [FUNCTION.MAIN]: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "Artikel" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in /Users/<benutzername>/Sites/Warenkorb/korb.php on line 12

Ich habe einmal testweise in der for-Schleife das erste Objekt übersprungen, das zweite wird korrekt ausgegeben (genau wie das erste, als dieses noch das einzige war).
Erst dachte ich, es läge daran, dass das Objekt in $_SESSIONS vielleicht nur eine seichte Kopie wäre. Aber das kann doch nicht der Grund sein, denn bei eben frisch hinzugefügten Objekten funktioniert es ja! Woher also kommt es, dass mein Objekt "incomplete" sein soll?

Ich wäre froh, wenn jemand hier auf die Lösung kommt, ich hänge schon seit einigen Stunden an dieser Stelle fest :(
Vielleicht hat ja auch mal jemand ein ähnliches Vorhaben (Objekte in Session speichern) schlauer gelöst?


Meine PHP-Version ist 5.0.4
 
Zuletzt bearbeitet:
Hi,
ich denke mal es liegt daran, dass PHP keine Ahnung hat was das Objekt "Artikel" ist. Denn ich sehe in deinen Scripten keine Defintion der Klasse Artikel und PHP versucht dir dies mit "provide a __autoload() function to load the class definition" zu sagen.
 
Die Klasse wird ja mit
PHP:
include("class_Artikel.php");
im ersten Skript geladen.

Wie gesagt, einmal funktioniert es ja, so ganz ahnungslos kann PHP da also nicht sein.
Was mich wundert, ist, dass es beim ersten Mal geht, sonst hätte ich vermutet, dass das Objekt nach dem Laden in $_SESSION['warenkorb'] kein echtes Objekt mehr ist.

In korb.php wird kein
PHP:
include("class_Artikel.php");
mehr erwartet. Das habe ich ausprobiert, da hat sich PHP beschwert, dass ich zweimal die Klasse deklariere.
Und das war auch nur ein verzweifelter Versuch, denn wenn die Deklaration fehlen würde, ginge es ja GAR nicht.
 
Hey, das hat mich jetzt doch ein Stück weiter gebracht!

Ich habe jetzt mal nur das erste Skript laufen lassen und unten (anstatt die warenkorb-Datei zu includen) einen Link zum Warenkorb gesetzt. Dort habe ich nochmal meine Klassen deklariert und jetzt geht es!

Allerdings, ich wollte eigentlich erreichen, dass der Warenkorb, den ich in einem iframe anzeige, immer sofort aktualisiert wird, ohne dass man erst einen Link drücken muss...

Edit: Letzteres habe ich nun gelöst, indem ich nach dem ersten Skript noch HTML ausgebe mit einem Refresh-Metatag. Funktioniert, kommt mir aber nicht sehr elegant vor... wie würdet Ihr das machen? :)
 
Zuletzt bearbeitet:
Sowas macht man doch eigentlich immer mit Ajax...

Da wird dann der <div> des Warenkorbs (oder iFrame) neu geladen ohne dass die ganze Webseite neu geladen werden muss...

Beispiel
 
Sowas macht man doch eigentlich immer mit Ajax...

Da wird dann der <div> des Warenkorbs (oder iFrame) neu geladen ohne dass die ganze Webseite neu geladen werden muss...

Erstmal sollte man jede Seite ohne JavaScript schreiben und alle Funktionen implementieren. Danach kann man anfangen und gezielt bestimmte Funktionen mit JavaScript lösen. (Ohne die Seite damit mit deaktiviertem JavaScript unbenutzbar zu machen!)
 
Erstmal sollte man jede Seite ohne JavaScript schreiben und alle Funktionen implementieren. Danach kann man anfangen und gezielt bestimmte Funktionen mit JavaScript lösen. (Ohne die Seite damit mit deaktiviertem JavaScript unbenutzbar zu machen!)

Kommt doch drauf an was er damit will und welche Zielgruppe er bedienen will...

Dann würde ich dennoch mir nicht "nen Wolf" programmieren und versuchen ein Javascript verhalten vorzutäuschen.
Bei allen Leuten mit deaktviertem Javascript wird halt dann der Warenkorb bei jeder Änderung zwischendruch als eigenständige Seite geladen...
 
Kommt doch drauf an was er damit will und welche Zielgruppe er bedienen will...

Dann würde ich dennoch mir nicht "nen Wolf" programmieren und versuchen ein Javascript verhalten vorzutäuschen.
Bei allen Leuten mit deaktviertem Javascript wird halt dann der Warenkorb bei jeder Änderung zwischendruch als eigenständige Seite geladen...

An sich natürlich richtig. Aber es ist generell einfach zu empfehlen, wenn man sieht, was so rauskommen kann, wenn gleich mit JavaScript gestartet wird. Häufig wird da vor lauter genialen Funktionen (gerade wenn man mit jQuery o.ä. arbeitet) die Bedeutung von "Benutzbarkeit" schon beim ersten Tastendruck vergessen.

Wobei selbst das nicht unbedingt hilft, wenn man sich ansieht, was im StudiVZ bei aktiviertem JavaScript so verbrochen wird.
 
Ajax ist die nächste Sache, die ich mir mal ansehen wollte. Bin ja erstmal froh, dass ich die objektorientierte Programmierung auf die Reihe bekommen habe, das ist wirklich eine feine Sache!
Das Ajax-Beispiel gucke ich mir zu Hause an (bin gerade via iPhone hier)!
Generell versuche ich aber auch, ganz ohne Skript auszukommen, aus Prinzip! :)
Zweigleisig werde ich die Seite nicht programmieren, dazu ist das Budget zu gering.
 
Zuletzt bearbeitet:
Sowas macht man doch eigentlich immer mit Ajax...
[...]
Beispiel

Ein gutes Beispiel... geht bei mir schonmal nicht so wie es wahrscheinlich soll. Das ist genau das, was ich vermeiden will. Ich möchte mit dem sich selbst wiederladenden iframe auch nichts vortäuschen, sondern auf solider Basis (ohne Skripte) eine für den Seitenbesucher möglichst bequeme und intuitive Funktionalität erreichen.

Na, der Thread hat sich (nachdem ich eine akzeptable Lösung gefunden habe) etwas vom Thema entfernt.
Wer bis hierhin liest und eine Antwort darauf weiß, warum das erste Objekt im Array in der includeten Datei nicht gültig ist, auf einer eigenständigen Seite dann aber doch, darf es mir gern verraten! :)
 
PHP:
if( isset($_POST['Gr']) && $_POST['Gr'] != ""){
    $auswahl = new Artikel($size);
}
Das Objekt wird nur bei einem Post-Submit erzeugt, ansonsten ist es nicht vorhanden.
 
Zurück
Oben Unten