Martl: Cookie auswerten

Hallo Forum,

ich habe folgendes Szenario, in dem Script 2 von Script 1 aufgerufen wird.

PHP-Script 1:

setcookie('Keks','Krümel');

PHP-Script 2:

if(isset($_COOKIE['Keks']){

	/*Es gibt Kaffee.*/

} else {

	/*Verkrümel Dich!*/

}

Auf einem Apache-Server wird das Cookie erfolgreich abgefragt und es gibt Kaffee.

Auf einem anderen Apache-Sever hingegen ist mit dem selben Script das Ergebnis:

if(isset($_COOKIE['Keks']){

	/*Es gibt Kaffee.*/

} else {

	var_dump($_COOKIE['Keks']) => Array(0){}

}

Erst, wenn die Bedindung lautet:

if($_COOKIE['Keks'] == 'Krümel'){

	var_dump($_COOKIE['Keks']) => array(1) { ["Keks"]=> string(6) "Krümel" }

} else {

	/*Verkrümel Dich!*/
	
}

klappt das. Kann mir jemand einen Tip geben, woran das liegen könnte.

Grüße, Martl

  1. Hallo Martl,

    if(isset($_COOKIE['Keks']){
    ...
    }
    

    wäre ein Syntaxfehler, aber ich nehme mal an, die zweite ) Klammer ist beim Übertragen ins Forum vertackert worden.

    Abgesehen davon klingt das nach einer Ursache, die mit dem Code nicht unbedingt zu tun hat.

    Denn die Abfrage

    if (isset($_COOKIE['Keks']))

    ist weniger streng als

    if ($_COOKIE['Keks'] == 'Krümel')

    Damit meine ich: Wenn die zweite zutrifft, trifft die erste auf jeden Fall zu. Und es ist auch richtig, eine isset-Abfrage zu machen, denn Du möchtest ja in dem Fall, dass der Keks nicht in der Dose ist, keine Fehlermeldung haben.

    Funktioniert die "erweiterte" Abfrage vielleicht rein zufällig? Weil Du den Keks in einem anderen Test gesetzt hast und nun fliegt er rum und krümelt vor sich hin? Schick mal das Krümelmonster in den Webseitenspeicher (Entwicklerwerkzeuge) und lass es die vorhandenen Kekse beseitigen.

    Kommt auf dem zweiten Server der Cookie überhaupt an? Guck in den Netzwerktrace des Browsers, in die Response-Header des Requests, der setCookie macht. Da muss ein set-cookie Header drin sein.

    Macht dein Script1 Ausgaben, bevor es den Cookie setzt? Wenn ja: Möglicherweise ist auf Server 1 im PHP Output-Buffering aktiv und Du kannst dort Header "nachlegen", nachdem schon Ausgaben gemacht wurden. Ohne Buffering geht das nicht, und es gibt eine Warning "Warning: Cannot modify header information - headers already sent" (die natürlich nicht unterdrückt werden darf).

    Ob Output Buffering läuft, kriegst Du mit ini_get('output_buffering') heraus.

    Ist alles wilder Spekulatius - keine Ahnung inwieweit das zutrifft.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      danke für Deine Antwort.

      ...vertackert...

      stimmt.

      Krümelmonster

      Wird jedes Mal aktiv.

      ...Ausgaben, bevor es den Cookie setzt?

      Nein.

      Kommt auf dem zweiten Server der Cookie überhaupt an?

      Ja.

      Wenn die zweite zutrifft, trifft die erste auf jeden Fall zu.

      Und genau deshalb verstehe ich im Moment nur Bahnhof.

      ...klingt das nach einer Ursache, die mit dem Code nicht unbedingt zu tun hat.

      Den Eindruck habe ich auch, aber wo die zu suchen wäre? Könnte es an Konfigurationsunterschieden bei den Servern liegen? Da hätte ich jetzt weniger Ahnung.

      Grüße, Martl

      1. Hallo Martl,

        Konfigurationsunterschieden ... Da hätte ich jetzt weniger Ahnung.

        Ja, ich auch nicht unbedingt.

        Kommt der Keks denn vom 2. Server an? Hast Du meine Prüfvorschläge durchführen können?

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          siehe meine Antwort an Raketenwilli.

          Grüße, Martl

      2. ...klingt das nach einer Ursache, die mit dem Code nicht unbedingt zu tun hat.

        Den Eindruck habe ich auch, aber wo die zu suchen wäre?

        OSI, Level 8. Ich würde den Fehler in Deinem eigenem Vorgehen, also Testaufbau, also Testgeschehen suchen.

        Rolf hat das schon richtig beschrieben.

        <?php
        # Beim Testen immer aktivieren, auch da, wo Du den Cookie setzt:
        error_reporting( E_ALL );
        ini_set( 'display_errors', 1 );
        
        # Beim Testen nicht über die eigenen Füße stolpern:
        header( 'Expires: 0' );
        header( 'Pragma: no-cache' );
        header( 'Cache-Control: no-cache, must-revalidate' );
        
        header( 'Content-Type: text/html' );
        if( ! empty( $_COOKIE['Keks'] ) ) {
            echo '"Keks" ist da. Inhalt: "' . $_COOKIE['Keks'] . '"';
        } else  {
            setcookie( 'Keks', date( 'Y-m-d H:i:s' ) );
            echo 'Keinen Keks empfangen. Hab ihn gesetzt. Drücke [F5]';
        }
        

        Und schau Dir bitte den Cookie auch im Browser und die gesendeten/empfangenen Header in den Entwicklertools des Browsers an.

        Übrigens: Was meinst Du mit „anderer Server“?

        Wenn Du auf einer Webseite von Server A das Cookie setzt, dann darf es gar nicht an einen Server B gesendet werden.

        1. Hallo Raketenwilli,

          Wenn Du auf einer Webseite von Server A das Cookie setzt, dann darf es gar nicht an einen Server B gesendet werden.

          Da scheint ein Missverständnis vorzuliegen. Beide Scripte liegen zusammen je auf einem Server, einer Entwicklung, einer Produktiv, die Scripte sind 1:1-Kopien.

          error_reporting

          Bleibt erfreulich stumm.

          Das Cookie kommt definitiv an, sehe ich in den Dev-Tools. Allerdings scheitert auf dem Testsystem die isset-Abfrage in der Eingangs beschriebenen Form.

          Und jetzt wird es kurios, denn das separat abgefragt:

          if(isset($_COOKIE['Keks'])){
          	
          	$test = true;
          
          }
          

          führt dazu, daß das funktioniert:

          if($test){
          
          	var_dump($_COOKIE['Keks']) => array(1) { ["Keks"]=> string(6) "Krümel" }
          
          } else {
          
          	/*Verkrümel Dich!*/
          	
          }
          

          Das nehme ich jetzt mal so hin.

          Grüße, Martl

          1. Hallo Martl,

            $test = false;              // <<<----- der hier fehlt!
            if(isset($_COOKIE['Keks'])){
            		$test = true;
            }
            
            if($test){
            // do something
            }
            

            und

            if(isset($_COOKIE['Keks'])){
            // do something
            }
            

            können nur in exakt einem Fall zu unterschiedlichen Ergebnissen führen: Falls $test zuvor schon auf true gesetzt war. Deswegen habe ich die Zeile hinzugefügt, wo es mit false vorbelegt wird, und "Der hier fehlt" dazugeschrieben.

            Andernfalls muss das Ergebnis identisch sein. Ich kann mir keinen PHP Bug vorstellen, der den von Dir behaupteten Unterschied hervorrufen könnte.

            Wenn das bei Dir nicht der Fall zu sein scheint, spielen äußere Faktoren hinein, die man aus deinem geposteten Code nicht erkennt. Deswegen sagte ich "behauptet". Du behauptest, dass es einen Unterschied macht, aber deine Beweiskette muss irgendwo ein Loch haben. Auch wenn Du es nicht siehst.

            Was passiert hiermit:

            echo "[";
            if(isset($_COOKIE['Keks'])) {
              echo "1";
            }
            if($test) {
              echo "2";
            }
            if(isset($_COOKIE['Keks'])) {
              $test = true;
              echo "3;
            }
            if($test) {
              echo "4";
            }
            echo "]";
            
            

            Die Ausgabe MUSS [134] sein, wenn der Cookie da ist, und [], wenn er fehlt. Eine 2 darf nicht erscheinen. Und [34] kann definitiv nicht sein, das wäre ein PHP Bug.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo,

              $test = false;              // <<<----- der hier fehlt!
              if(isset($_COOKIE['Keks'])){
              		$test = true;
              }
              

              warum so umständlich von hinten durch die Brust ins Knie?
              Eine boolsche Testvariable setzt man doch, indem man ihr direkt das Ergebnis der Abfrage zuweist:

              $test = isset($_COOKIE['Keks']);
              

              Einen schönen Tag noch
               Martin

              --
              Мир для України.
              1. Hallo Der,

                der ganze IF inclusive der Variablen ist flüssiger als flüssig - aber Martl meint ja, das hätte sein Problem geheilt. Deswegen sollte man für Experimente, die MÖGLICHERWEISE auf einen PHP Bug führen, erstmal beim Pattern bleiben.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. Deswegen sollte man für Experimente, die MÖGLICHERWEISE auf einen PHP Bug führen, erstmal beim Pattern bleiben.

                  Jepp. Um das zu übersetzen:

                  1. Hallo Raketenwilli,

                    Methode: Wenn man den Fehler nach 15 Minuten nicht gefunden hat, Augen weg vom Monitor

                    Was die Vorstufe für diese erprobte Methode ist: Sourcecode ausdrucken, eine flache Schüssel mit etwas Bier darin draufstellen, einen Blumentopf dort hineinstellen und das Ganze über Nacht stehen lassen. Im Verlauf des Abends kann das übrige Bier ausgetrunken werden.

                    Was passiert? Die Bugs werden von der Pflanze angelockt, fallen ins Bier, ertrinken und am nächsten Morgen ist der Code frei von Bugs. Und durch das Bier ist man prima entspannt.

                    Die Methode heißt "organic debugging". Studien zeigen, dass diese Methode mindestens so erfolgreich ist wie viele andere Fehlersuchmethoden.

                    Update: Mist, den Joke bring ich nicht zum erstem Mal

                    Rolf

                    --
                    sumpsi - posui - obstruxi
                    1. Mahlzeit,

                      Sourcecode ausdrucken, eine flache Schüssel mit etwas Bier darin draufstellen, einen Blumentopf dort hineinstellen und das Ganze über Nacht stehen lassen. Im Verlauf des Abends kann das übrige Bier ausgetrunken werden.

                      Update: Mist, den Joke bring ich nicht zum erstem Mal

                      aber die Umstellung von Wasser auf Bier ist ein echter Fortschritt. 😉

                      Einen schönen Tag noch
                       Martin

                      --
                      Мир для України.
                      1. Hi,

                        aber die Umstellung von Wasser auf Bier ist ein echter Fortschritt. 😉

                        Hm - wirklich?

                        Ich stufe das Verschwenden von Bier an eine Pflanze eher als Alkoholmißbrauch ein …

                        (und das als Weintrinker …)

                        cu,
                        Andreas a/k/a MudGuard

                        1. Hallo,

                          aber die Umstellung von Wasser auf Bier ist ein echter Fortschritt. 😉

                          Hm - wirklich?

                          Ich stufe das Verschwenden von Bier an eine Pflanze eher als Alkoholmißbrauch ein …

                          erstens kommt ja nur ein kleiner Anteil des Biers für die Pflanze zur Anwendung (den deutlich größeren Rest soll man ja zur Entspannung selber trinken); zweitens habe ich schon öfter gelesen, dass es manchen Pflanzen sogar gut tut, wenn sie hin und wieder mit Bier gegossen werden.

                          (und das als Weintrinker …)

                          Wer's mag ...

                          Einen schönen Tag noch
                           Martin

                          --
                          Мир для України.
                          1. Hi,

                            Ich stufe das Verschwenden von Bier an eine Pflanze eher als Alkoholmißbrauch ein …

                            erstens kommt ja nur ein kleiner Anteil des Biers für die Pflanze zur Anwendung

                            Wehret den Anfängen …

                            cu,
                            Andreas a/k/a MudGuard

                            1. Hallo,

                              Wehret den Anfängen …

                              Oder auf neudeutsch "Währet den Anfengen" 🤦

                              Gruß
                              Kalk

          2. Da scheint ein Missverständnis vorzuliegen.

            Naja ... für ein Missverständnis muss etwas falsch verstanden worden sein. Es mangelt aber an dem „etwas“, welches ich falsch verstehen konnte. Denn Du hattest nichts dazu geschrieben, von welchem Client aus das Cookie auf welchem Server ankommen und ausgewertet werden sollte.

            Das ist dann auch ein Punkt, an man (ausdrücklich inkludiert: ich selbst) sich selbst bei Test sehr häufig selbst ein Bein stellt - denn das gezeigte Skript hätte in Variante B nicht funktionieren dürfen, wenn Variante A nicht funktioniert hätte. Ich vermute also, das Cookie war nicht vorhanden. Und an einen Bug von PHP will ich hier so früh nicht glauben.

            Neben dem „Servermitschmatsch“ wäre noch HTTP / HTTPS-„Crossing“ eine mögliche Ursache für fehlschlagende Tests - obwohl das Skript selbst funktioniert.