PHP Aktualisierung der Darstellung bei der Nutzung von Cookies

TheGTI

Lt. Commander
Registriert
Apr. 2006
Beiträge
1.703
Ich hab mal eine kurze Frage an die Programmierprofis unter euch: PHP war bis heute ein Buch mit sieben Siegeln für mich, jetzt kann ich endlich mal damit anfangen.
Zum Einstieg sollen wir ein bisschen mit Cookies herumspielen. Meine Pizza-Bestellseite tut soweit auch das was sie soll. Allerdings gibt es noch ein Problem, welches ich nicht gelöst bekomme:

Klickt man auf den "Bestellung löschen" Button, werden die Cookies zwar alle gelöscht, die Darstellung der Tabelle ändert sich aber erst beim zweiten Klick.
Das hinzufügen der Pizzen klappt sofort nach jedem Klick.

HTML:
<?php
if (isset($_POST["loeschen"])) {
    foreach ($_COOKIE as $name => $value) {
        setcookie($name, "", time() - 1);
    }
} else if (isset($_POST["auswahl"])) {
    setcookie($_POST["auswahl"], ++$_COOKIE[$_POST["auswahl"]], time() + 180);
}
$pizzen = ["Hawaii", "Vegetarisch", "Schinken", "Salami"];
?>

<!DOCTYPE=html>

<html>
<head>
    <title>Pizzabestellung</title>
    <meta charset="utf-8">
</head>
<body>
    <h1>Pizzabestellung</h1>
<p>
    <section>Bitte wählen Sie Ihre Pizza:</section>
</p>

<form title="bestellung" action="aufgabe_2.php" method="POST">
    <p>
        <select name="auswahl" size="1">
            <option value="Hawaii">
                Hawaii
            </option>
            <option value="Vegetarisch">
                Vegetarisch
            </option>
            <option value="Schinken">
                Schinken
            </option>
            <option value="Salami">
                Salami
            </option>
        </select>
    </p>
    <input type="submit" value="Pizza hinzufügen">
    <?php
    ?>
</form>
<hr/>
<p>
    <section>Ihre aktuelle Bestellung:</section>
</p>
<p>
<table border="1">
    <tr>
        <th>Pizza</th>
        <th>Menge</th>
    </tr>
    <?php
    foreach ($_COOKIE as $name => $value) {
        if (in_array($name, $pizzen)) {
            echo "<tr><th>$name</th><th>$value</th></tr>";
        }
    }
    ?>
</table>

<form action="aufgabe_2.php" method="POST">
    <p>
        <input type="submit" name="loeschen" value="Bestellung löschen">
    </p>
</form>
</p>
</body>
</html>
 
Wundert mich ehrlich gesagt, dass das hinzufügen nach einem Klick funktioniert.

Cookies sind auf deinem PC. D.h. wenn du in PHP ein Cookie setzt, macht das der Browser.
Der Server kriegt aber die gesetzten Cookies erst mit dem nächsten Request wieder. Da wird das Problem liegen.
 
foolproof schrieb:
Wundert mich ehrlich gesagt, dass das hinzufügen nach einem Klick funktioniert.

Hab ich mich auch erst gefragt, aber das liegt an dem komischen ++$_COOKIE[$_POST["auswahl"]] Konstrukt im setcookie Aufruf ;-)

Damit das ganze wie gewünscht funktioniert müsste man neben dem setcookie zum löschen auch noch den Wert aus dem $_COOKIE Array entfernen, weiß blos grad nicht wie das in PHP geht (auf "" setzen dürfte nicht reichen bei dem Schleifenkonstrukt unten, da müsste man die IF-Bedingung erweitern)
 
Richtig, so habe ich das auch gelernt.
Wenn beides nicht funktionieren würde, hätte ich vermutlich kein Verständnisproblem. Aber so komme ich mit meinem Wissen nicht mehr weiter.

@Jester: Das wäre natürlich eine Idee. Ich werde den Code mal umschreiben.
 
Jesterfox schrieb:
Hab ich mich auch erst gefragt, aber das liegt an dem komischen ++$_COOKIE[$_POST["auswahl"]] Konstrukt im setcookie Aufruf ;-)

Du Fuchs. Kannte ich auch noch nicht. ;)

@Jesterfox: Ersetze mal "++$_COOKIE[$_POST["auswahl"]]" durch "$_COOKIE[$_POST["auswahl"]]+1" und schau dann was passiert. Dann passiert genau das, was man erwarten würde. ;)

Ich glaub einfach, das Problem ist so nicht lösbar. Wie schon beschrieben sind die Cookies beim Client und die schickt er dem Server bei jedem Seitenaufruf. D.h. wenn du ein Cookie setzt, kannst du des erst beim nächsten Aufruf verwenden. Das mit dem "++$..." ist da wohl eine Ausnahme.

Was aber geht: Cookies per JavaScript setzen und löschen, und die Anzeige dynamisch zu aktualisieren (ohne dass der Server überhaupt etwas mitbekommt davon). So würde ich das Problem lösen.
 
Zuletzt bearbeitet:
Als Erklärung:

++$_COOKIE[$_POST["auswahl"]]

Das ++ ist der Inkrement-Operator, der erhöht den Wert von $_COOKIE[$_POST["auswahl"]] um 1 und liefert das Ergebnis dann zurück. Dadurch wird im Cookie-Array der Entsprechende Wert mit 1 angelegt und steht unten bei der Ausgabe sofort zur Verfügung.

Im Löschen Fall ist aber momentan nichts vorhanden das den Wert sofort aus dem Array entfernt, deswegen verschwindet das erst nach einem Reload.


Edit @foolproof: jepp, die 2. Variante verhält sich anders, da sie das Cookie-Array nicht verändert.
 
Wir sollen das ganze nur mit serverseitigen Scripts lösen, deshalb ist das ganze nicht in JS implementiert. Gibts denn überhaupt eine Möglichkeit, das ganze in PHP vernünftig zu realisieren? $_COOKIE[$_name] = 0 macht ja vermutlich nichts anderes als "" !?
 
Kanns grad hier nicht testen, aber glaub eher weniger, dass unset funktioniert.
Du machst das schon richtig, ich kenne keine Lösung, die sofort die Cookies verwenden kann. (s. Post oben).

Die Lösung wäre halt, bei der Anzeige der Bestellungen ein if rein zu machen und da zu prüfen, ob löschen aufgerufen wird. Wenn ja, dann einfach nix anzeigen ;)
 
Ich koche hier mal fertig und poste dann meine neue Lösung. Schonmal vielen Dank für eure Hilfe!
Ergänzung ()

Eine kleine If-Anweisung und schon funktionierts! Ist das ganze eigentlich in Ordnung oder eine arg unsaubere Lösung?


PHP:
<?php
    if (!$_POST["loeschen"]) {
        foreach ($_COOKIE as $name => $value) {
            if (in_array($name, $pizzen) AND $value != "") {
                echo "<tr><th>$name</th><th>$value</th></tr>";
            }
        }
    }
    ?>
 
Naja, die ganz feine Art ists nicht, aber für diese Aufgabenstellung wohl die einfachste ;)
 
Könntest du mir das ein wenig näher erläutern? Vielleicht auch einen Tipp zur Verbesserung
 
Schreib lieber:
PHP:
if(!isset($_POST["loeschen"])){}

Das, was du machst, kann wie gesagt Notice-Einträge im Error Log auslösen, denn wenn $_POST["loeschen"] nicht gesetzt ist, dann kann !$_POST... natürlich auch auf keinen Wert im Array zugreifen. In strikteren Sprachen wie C hättest du wohl n Speicherzugriffsfehler und n Systemcrash. PHP... mault nur und macht weiter.

Das ist ne Schulaufgabe, oder? Dann mach es an anderer Stelle auch gleich richtig.
<section> darf in <p> nicht vorkommen. Ich bin ziemlich überrascht, dass <select> in <p> vorkommen darf, auch wenn es irgendwie hässlich aussieht.

Was echo "<tr><th>$name</th><th>$value</th></tr>"; angeht: Macht wenig Sinn, die Daten in <th> zu setzen, <td> wäre sinnvoller. Sind ja keine Table Header, sondern Tabellenzellen.
<table>

Und nimm mal die Leerzeilen vor und hinter deinem !DOCTYPE raus, so etwas kann zu blöden Komplikationen führen. Sorg dafür, dass der !DOCTYPE immer die erste Zeile ist, die im Browser ankommt, dicht gefolgt von <html>.
 
Dummer Fehler, habe oben ja auch immer mit isset() gearbeitet.
Die Leerzeilen sind eine Angewohnheit von Java, muss ich mir bei HTML und Co. mal abgewöhnen.
Ich bin hier schon so lange angemeldet und bin nie auf die Idee gekommen, Fragen zur Programmierung einzustellen. Kann man in Zukunft öfter machen.
Das ganze ist im übrigen eine Übungsaufgabe in der Uni.
 
"Tragisch" sind die Leerzeilen eigentlich nur vor dem Doc-Type, der sollte am Anfang der ersten Zeile stehen ohne irgend etwas anderes davor. Vor allem auch keine BOM (Byte Order Mark), das ist ne Einstellung beim Texteditor, der sollte auf UTF-8 ohne BOM stehen. Die kann einem nicht nur beim HTML sondern auch im PHP Ärger machen, spätestens wenn man mit Sessions arbeiten will.
 
Nicht nur bei Sessions, auch bei jeglicher Form von Header-Manipulation, z.B. Redirects oder natürlich der Ausgabe von per PHP erstellten Bildern, Audiostreams,...
 
Wie verhält es sich denn sonst mit Leerzeilen?

Wenn Ihr schonmal alle hier seid, hätte ich noch eine kurze Frage hinterher:

HTML:
<form method="post" name="anmeldung" onsubmit='return checkForm()' action="aufgabe_3_anmeldung.php">
    Vorname <input type="text" name="vorname"> <br/>
    Nachname <input type="text" name="name"> <br/>
    <input type="submit" value="Anmelden" name="absenden">
</form>
<script type="text/javascript">
    function checkForm(aForm) {
        *some code*
    }
</script>

Das ganze dient zur Validierung des Vorname-Textfeldes. Kann man das so machen? Und was ist denn die 1a Lösung um Formulare vor dem Absenden zu überprüfen?
 
Willst du bloß die Existenz von Werten prüfen? Dafür gibts HTML5-Attribute die jeder Browser >=IE9 kann.
Wenn es etwas komplexer sein soll: nicht selbst schreiben, andere Leute waren im Zweifel viel klüger als du. http://mootools.net/docs/more/Forms/Form.Validator

Das alles ist aber nur halbgar. Es verhindert, dass der Kunde unbeabsichtigt ein leeres Formular oder ein falsch formatiertes Datum verschicken will und dann nach einem Reload eine Fehlermeldung sieht.
Form-Validierung dient aber in erster Linie dem Schutz deiner Anwendung vor Missbrauch. Hier muss die Validierung aber immer auf Serverebene erfolgen, also im PHP-Code.

PHP-Validierung: Muss zwingend!
HTML5 & JS: Kann, verbessert die User Experience
 
Genau, aber darum ging es mir jetzt gar nicht unbedingt.
Ich meinte tatsächlich nur ganz konkret:

Ist das hier ein ein vernünftiger Aufruf einer JS-Funktion vor dem Abschicken eines Formulars, oder gibt es da besser Möglichkeiten (Wenn man eine Validierung einbindet oder selber geschrieben hat) ?

PHP:
onsubmit='return checkForm()'
 
Zurück
Oben