PHP Cookiesetzung schlägt fehl - Anfänger, Grundlagenproblem

Moretto Delucci

Lt. Junior Grade
Registriert
Feb. 2010
Beiträge
378
Hallo mal wieder :)

Seit einiger Zeit betreibe ich eine kleine Webseite, auf der ich ebensokleine Scripte zum üben hochlade.
Jetzt hänge ich aber fest. Habe mir heute aus dem Netz den Befehl zum setzen von Cookies in PHP gezogen, komme aber nicht damit klar, obwohl meine Logik stimmen müsste.

Boardsuche bringt mir nicht viel, da ich nicht weiß nach was ich Suchen soll.
Ups:Ehe ichs vergesse, es ist ein Spiel(Einarmiger Bandit), bei 3 gleichen Früchten hat man gewonnen.

Wo ist mein Fehler?
Denkanstöße erwünscht, Komplettlösungen weniger, da ich ja nichts bei lerne.

PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

 <head>
	<title>An XHTML 1.0 Strict standard template</title>
	<meta http-equiv="content-type" 
		content="text/html;charset=utf-8" />

 </head>

 <body>
	<div id="wrapper">
		<div id="header">
		</div>
		<div id="nav">
		</div>
			<form action="bandit.php" method="post"> <!-- Ruft diese Seite auf-->
				<input type="submit" value="Spielen!" /><!-- .. wenn dieser button aktiviert wird-->
				<span>Einsatz</span><!-- Textfeldbeschreibung-->
				<input type="text" name="tfEinsatz" value="0"/><!--textfeld -->
			</form>
				<?php
					$mBesucht=$_COOKIE["besucht"]; //schreibt den wert von cookie besucht in variable mBesucht, wobei cookie leer ist bei erstaufruf (exisitiert nicht)
					IF ( empty($mBesucht) //checkt ob variable leer ist
							){ //ist leer also:
							setcookie("guthaben",50000,time()+(3600*24)); //setzt cookie guthaben auf wert 50000 für 24h
							setcookie("besucht",1,time()+(3600*24)); //setzt cookie besucht auf wert 1 für 24h, sodass beim nächsten aufruf der wert 1 in $mBesucht steht (Z. 24)
							}else
							{
							//hier muss nichts passieren
							}
				?>
				<?php
					$mGuthaben=$_COOKIE["guthaben"]; //holt den wert 50000 aus dem cookie guthaben
					echo "Guthaben: $mGuthaben"; //wird ausgegeben
				?>
				<?php // folgend der funktionierende code für den einarmigen bandit
					$mErdbeere=0;
					$mBanane=0;
					$mKirsche=0;
					$mEinsatz=$_POST['tfEinsatz'];
					
					echo "<div>";
						for ($mZahler=1;$mZahler<=3;$mZahler++){
							$mNovo=rand(1,3);
							
							switch($mNovo){
								case 1:
										echo"<img src='../images/banane.png' alt=' ' />";
										$mBanane=1;
										$mGewinn=0;
									break;
									case 2:
										echo"<img src='../images/kirsche.png' alt=' ' />";
										$mKirsche=2;
										$mGewinn=0;
									break;
									case 3:
										echo"<img src='../images/erdbeere.png' alt=' ' />";
										$mErdbeere=3;
										$mGewinn=0;
									break;
									default:
									break;
						}
					//endet hier
					}
					IF (
						$mKirsche==0 AND $mErdbeere==0 OR //wenn alle cases nur die variable mBanane beschrieben haben, sind die anderen 2 leer, d.h. man hat 3 bananen in einer reihe
						$mBanane==0 AND $mErdbeere==0 OR // same here
						$mKirsche==0 AND $mBanane==0  //..und hier
							){ //wenn gewonnen, dann:
							echo "<br />Gewonnen.<br />";
							$mGewinn=($mEinsatz*3)-$mEinsatz; //rechne den rohgewinn aus und schreibe ihn in die variable mGewinn
							$mGuthaben=$mGuthaben+$mGewinn; //rechne gewinn zu aktuellem guthaben
							setcookie("guthaben",$mGuthaben,time()+(3600*24)); //setze die summe aus aktuellem guthaben und gewinn in cookie guthaben und ersetze dabei vorherigen wert
							echo "Du hast $mGewinn gewonnen!"; // ..
							$mEinsatz=0; //einsatz zurücksetzen
							}
							else{//wenn verloren dann
							$mGuthaben=$mGuthaben-$mEinsatz; //ziehe einsatz von guthaben ab
							setcookie("guthaben",$mGuthaben,time()+(3600*24)); //... setze cookie neu
							echo "Verloren :(";
							$mGewinn=0; //setze mGewinn zurück
							$mEinsatz=0; //setzte einsatz zurück
							} 
					echo "</div>";
				?>
		<div id="content">
		</div>
		<div id="footer">
		</div>
	</div>				
    

 </body>
</html>

Danke :]
 
http://de3.php.net/manual/en/function.setcookie.php schrieb:
setcookie() defines a cookie to be sent along with the rest of the HTTP headers. Like other headers, cookies must be sent before any output from your script (this is a protocol restriction). This requires that you place calls to this function prior to any output, including <html> and <head> tags as well as any whitespace.
Der Text, den du eingegeben hast, ist zu kurz. Bitte erweitere den Text auf die minimale Länge von 1 Zeichen.
 
Yuuri schrieb:
Der Text, den du eingegeben hast, ist zu kurz. Bitte erweitere den Text auf die minimale Länge von 1 Zeichen.

Ähm.. wie bitte?

Bedeutet dein englisches Zitat, dass cookies ausschließlich im Header funktionieren? Wie mies. Auf der Seite wurde das nicht erwähnt, oder ich übersah es.
Gibt es andere möglichkeiten einen Wert außerhalb des laufenden Skriptes zu speichern?
 
Moretto Delucci schrieb:
Ähm.. wie bitte?
Versuch mal nur ein Quote abzuschicken, dann wirst du sehen was gemeint ist.
Moretto Delucci schrieb:
Bedeutet dein englisches Zitat, dass cookies ausschließlich im Header funktionieren? Wie mies. Auf der Seite wurde das nicht erwähnt, oder ich übersah es.
Ja genau. Cookies können nur gesetzt werden, bevor irgendwas an den Browser geschickt wurde. Das ist nicht mies, sondern eigentlich wird eine Webseite bis zum Abschluss gepuffert und in einem Rutsch an den Browser geschickt. So kann man hierbei auch noch irgendwo ganz weit hinten im Script Umleitungen einfügen oder hier eben noch weitere Cookies setzen. Wenn du alles immer sofort an den Browser schickst, klappt das nun mal nicht.
Moretto Delucci schrieb:
Gibt es andere möglichkeiten einen Wert außerhalb des laufenden Skriptes zu speichern?
Du könntest dir einen Wrapper basteln, der alles vorm Setzen in die Session schreibt und beim erneuten Seitenaufruf die Cookies setzt. Bevorzugen würde ich aber immer obige Variante.
 
Na wenigstens habe ich jetzt das Prinzip von Cookies verstanden.
Aber wie meinst du das(obige Variante)? Wie kann ich besagte Cookis im Header verwenden? Kann ich einen Wert im Header speichern der sich erst eben ergeben hat, lange nach laden der Seite?

Womit kann ich mich am besten mit Wrapper und Sessions befassen?

Danke für die flotte Hilfe
 
Du verwendest die Cookies nicht im Header. Du verstehst hier grundlegend was nicht.

BEVOR dein Script IRGEND einen Wert (eben meist <DOCTYPE...) ausgibt, müssen alle Cookies gesetzt sein. Das Protokoll will es so, das muss so sein.
Dein elementarer Fehler: Du trennst die Programm-Logik (z.B. das Berechnen und Setzen von Cookies) nicht von der Darstellung.
 
Also sind Cookies total unnütz für mein Vorhaben? Ich müsste ja nur Werte so abspeichern, dass sie auch nach Aktualisieren noch abrufbar sind..
 
Cookies sind nicht zwingen sinnlos, aber du kannst dafür auch eine session benutzen. Diese würde vermutlich völlig ausreichen für deine Zwecke. Dazu muss von vor dem ersten Output, wie auch bei den cookies, die session gestartet werden:
Code:
<?
session_start();
?>

Und dann können Daten in spezielle session Variablen gespeichert werden:
Code:
<?
$_SESSION['guthaben'] = $mGuthaben;
?>

Diese Daten bleiben allerdings nur so lange erhalten wie die Session gültig ist, allgemein hin bis der Browser geschlossen wurde.
 
Mach es doch erstmal so, wie Daaron vorschlägt. Trenne deinen Code für Anzeige und Programm. Ist auch gleich viel übersichtlicher:

PHP:
<?php
...
if (...) {
   setcookie(...);
}
else {
  .... 
}
?>


<html>
<body>
   Dein Guthaben beträgt <strong><?php echo $guthaben; ?></strong> Euro.
</body>
</html>
 
Ok, anders: Cookies werden vom HTTP-Header gesetzt, und zwar bevor auch nur ein Bit HTML-Output übertragen wird. Du musst nur eben Protokoll-Header und <head> auseinander halten.
Und deine Cookies sind nicht nutzlos. Cookies (und HTML5 Local Storage) sind dazu da, Daten direkt auf dem PC des Besuchers zu speichern. Bei Cookies ist hierbei die Größenbeschränkung viel viel enger als mit Local Storage. In beiden Fällen muss man darüber nachdenken, wie alles vom Datenschutz her passt. In Deutschland geht es NOCH durch, dass man ungefragt Cookies setzt, das wird aber höchstwahrscheinlich eher so werden wie bereits jetzt z.B. in Großbritannien: Erst fragen, dann setzen.
Besser als drölfzillionen verschiedene Cookies zu setzen wäre es, direkt den Session Cookie zu verwenden. Jeder separate Cookie verzögert den Seitenaufruf enorm.

Dein Kernproblem bleibt: Du mischst HTML-Output und PHP-Code total wild. Das ist grundsätzlich schlechtes Design und bei deiner Cookie-Geschichte eben zusätzlich noch eine extreme Bug-Quelle. ERST alle Berechnungen machen, DANN überhaupt das erste Byte HTML-Output an den Client schicken. So, und nicht anders.


P.S.:
Da dein Spiel ja eh keinerlei "Relevanz" (keine Datenbank im Hintergrund, keine Gewinne, keine Kundenverwaltung,...) hat, warum belastest du den Server damit? Schreib deinen Spielautomaten in JavaScript und lass alles direkt beim Client berechnen. Das spart deinem Server unnötige Last und deinem Besucher unnötigen Seitenaufbau.
 
Zuletzt bearbeitet:
Daaron schrieb:
Ok, anders: Cookies werden vom HTTP-Header gesetzt, und zwar bevor auch nur ein Bit HTML-Output übertragen wird. Du musst nur eben Protokoll-Header und <head> auseinander halten.
Und deine Cookies sind nicht nutzlos. Cookies (und HTML5 Local Storage) sind dazu da, Daten direkt auf dem PC des Besuchers zu speichern. Bei Cookies ist hierbei die Größenbeschränkung viel viel enger als mit Local Storage. In beiden Fällen muss man darüber nachdenken, wie alles vom Datenschutz her passt. In Deutschland geht es NOCH durch, dass man ungefragt Cookies setzt, das wird aber höchstwahrscheinlich eher so werden wie bereits jetzt z.B. in Großbritannien: Erst fragen, dann setzen.
Besser als drölfzillionen verschiedene Cookies zu setzen wäre es, direkt den Session Cookie zu verwenden. Jeder separate Cookie verzögert den Seitenaufruf enorm.

Dein Kernproblem bleibt: Du mischst HTML-Output und PHP-Code total wild. Das ist grundsätzlich schlechtes Design und bei deiner Cookie-Geschichte eben zusätzlich noch eine extreme Bug-Quelle. ERST alle Berechnungen machen, DANN überhaupt das erste Byte HTML-Output an den Client schicken. So, und nicht anders.


P.S.:
Da dein Spiel ja eh keinerlei "Relevanz" (keine Datenbank im Hintergrund, keine Gewinne, keine Kundenverwaltung,...) hat, warum belastest du den Server damit? Schreib deinen Spielautomaten in JavaScript und lass alles direkt beim Client berechnen. Das spart deinem Server unnötige Last und deinem Besucher unnötigen Seitenaufbau.

Wow, also so hab ich das noch garnicht gesehen. Mein üblen Schreibstil habe ich wohl meinem Lehrer zu verdanken, das habe ich anders nie gelernt.
Vieleicht habe ich mich etwas weit aus dem Fenster gelehnt, ich finde das doch sehr komplex und von JavaScript brauch ich erst garnicht reden. Mit dem Sessioncookie werde ich mich wohl anfreunden (können).

Ich halte jetzt erstmal den Ball flach und begnüge mich mit holprigen Sessiontutorials im Netz.
Danke euch, ich gebe Rückmeldung!
 
Pft... Spätestens, wenn man eine Bibliothek wie jQuery oder Mootools verwendet, ist JavaScript auch keine große Herausforderung mehr. Deine Programmlogik ist dieselbe, egal ob du sie in JS, PHP, Perl, Python, C, Fortran oder Ook! schreibst.
Eine anständige Slotmachine hätte z.B. rotierende Scheiben, die der User auch sehen kann. Das erfordert garantiert JavaScript.

Und was Lehrer mit ihrem miesen Stil angeht: Kenn ich... Vor 20 Jahren war das schon so, aber ich hätte langsam mal erwartet, dass diese Leute wegsterben/in Rente gehen und durch kompetentere Leute ersetzt werden, die direkt leidlich vernünftige Code-Muster beibringen.
Ich musste auch ziemlich viel Mühe darin investieren, alles zu vergessen was ich mal gelernt habe, um dann sauber arbeiten zu können.
 
Daaron schrieb:
In beiden Fällen muss man darüber nachdenken, wie alles vom Datenschutz her passt. In Deutschland geht es NOCH durch, dass man ungefragt Cookies setzt, das wird aber höchstwahrscheinlich eher so werden wie bereits jetzt z.B. in Großbritannien: Erst fragen, dann setzen.

Nein, so wird es nicht werden.
Großbritanien hatte den Draft des "EU Cookielaw" in nationales Gesetz umgesetzt, bevor dieses EU-Gesetz komplett fertig war. Dieses Gesetz sah bis einen Tag vor Inkraftreten noch so aus, dass gefragt werden muss, Großbritanien hielt sich also genau an die Anforderung. An diesem wunderbaren einen Tag vor Inkrafttreten ist man aber zurückgerudert und hat diese Beschränkung entfernt, somit hat nur Großbritanien diese sehr strengen Gesetze, weil sie zu voreilig waren.
In Deutschland gibt es also noch keinen Zwang es wie in Großbritanien zu machen, auch nicht von der EU aus, und wird auch nicht passieren, da das EU Cookielaw schon ziemlich Kritik einstecken musste: Vieles was amerikanische Dienste mit dem Datenschutz machen, ist hier schon nicht möglich (für das deutsche Unternehmen eine Wettbewerbsbehinderung), aber mit diesem EU Cookielaw wären deutsche Dienste gar nicht mehr konkurrenzfähig gewesen.
 
Tja, hoffentlich hast du Recht, sonst wirds mit vielen CMS oder Shopsystemen extrem düster. Da darf man dann ne statische Vorschaltseite machen...

Aber ich bin da eher pessimistisch. Die "Button-Lösung" für Shops hat gezeigt, wie die deutsche Rechtslage tickt, genauso wie die Geschichte mit dem Double Opt-In für Newsletter, bei dem die Anmeldebestätigung nicht per Mail erfolgen darf (Hirnlos-Entscheidung eines LG von letztem Herbst)
 

Ähnliche Themen

Zurück
Oben