Zugriff auf $ _COOKIE unmittelbar nach setcookie ()

79

Ich versuche $_COOKIEsofort nach dem Aufruf der setcookie()Funktion in PHP auf den Wert eines Cookies zuzugreifen (using ) . Wenn ich das tue, $_COOKIE['uname']ist nicht eingestellt. Warum?

Beachten Sie jedoch, dass dies $_COOKIE['uname']bei der nächsten Ausführung des Skripts wie erwartet festgelegt wird, z. B. nach einer Seitenaktualisierung.

setcookie('uname', $uname, time() + 60 * 30);
echo "Cookie value: " . $_COOKIE['uname'];
Heapzero
quelle
Leider bieten die Antworten hier keine Lösung oder schlagen schlechte Problemumgehungen vor, selbst die akzeptierten, siehe stackoverflow.com/questions/3230133#34465594 .
Witrin
@witrin Ihr angegebener Link scheint zu demselben Q / A umzuleiten.
Trainoasis
Das ist nicht möglich. Sie müssen es "fälschen", indem Sie entweder die entsprechenden Einträge in sich $_COOKIEselbst festlegen oder sofort eine Umleitung (auf dieselbe Seite) durchführen.
Caw

Antworten:

36

$_COOKIEwird festgelegt, wenn die Seite geladen wird, da das Web zustandslos ist. Wenn Sie sofortigen Zugriff wünschen, können Sie sich selbst festlegen $_COOKIE['uname']oder eine Zwischenvariable verwenden.

Zum Beispiel:

if (isset($_COOKIE['uname'])) {
    // get data from cookie for local use
    $uname = $_COOKIE['uname'];
}
else {
    // set cookie, local $uname already set
    setcookie('uname', $uname, time() + 1800);  
}
Jason McCreary
quelle
21
Dies macht den Cookie nicht zugänglich, bevor eine Seite aktualisiert wird ... siehe Mark Bakers Antwort weiter unten dazu :)
Pathfinder
Das ist nicht wahr. Ich habe basierend auf dem OP-Code die Annahme getroffen, dass sie $unamein ihrem Skript verwendet werden. Während Mark Baker $_COOKIE['uname']direkt verwendet.
Jason McCreary
1
Es tut mir leid, dass ich es etwas falsch gesagt habe. Für meine Zwecke, die für ein asynchrones Skript gelten, hat das Setzen von $ _COOKIE das Cookie nicht gesetzt und an den Browser zurückgesendet (ich brauchte das Cookie auch dort), sondern nur in meinem Skript verfügbar gemacht. Sie müssen auch setcookie () verwenden, was Mark Bakers Antwort tut. Außerdem ist sein Code viel kürzer und nützlicher für Leute, die von einer Google-Suche hierher kommen.
Pathfinder
Ich benutze setcookie(). Diese Antwort entspricht möglicherweise nicht Ihren genauen Anforderungen. Aber das macht es nicht falsch . Das OP und SO haben diese Antwort als nützlich empfunden.
Jason McCreary
2
Ich verstehe nicht, warum diese Antwort als "die Antwort" markiert ist. Es wird nicht erklärt, wie das Cookie direkt verwendet wird, und der bereitgestellte Code entspricht dem veröffentlichten OP. Nach setcookie()in diesem Code ist es nicht möglich zuzugreifen$_COOKIE['uname']
Isthar
152

Das Cookie wird erst gesetzt, wenn die Antwort an den Client zurückgesendet wird, und ist in Ihrem PHP erst bei der nächsten Anfrage des Clients danach verfügbar.

Wenn Sie das Cookie in Ihrem Skript festlegen, können Sie jedoch Folgendes tun:

setcookie('uname', $uname, time()+60*30);
$_COOKIE['uname'] = $uname;
Mark Baker
quelle
2
Sehr einfache Lösung. Vielen Dank!
Dawoodman71
1
Tolles Zeug. Ich frage mich, wie die zweite Zeile die Ablaufzeit festlegt, wenn sie nicht übergeben wird.
Martinedwards
2
@martinedwards In der zweiten Zeile wird keine Ablaufzeit festgelegt. Sie wird für die Dauer der Anforderung festgelegt. Genauso wie ein Cookie-Wert, der mit einer Anfrage von einem Browser übergeben wurde, für die Dauer der Anfrage existiert
Mark Baker
@ MarkBaker Einfache Lösung !! Vielen Dank
Shan
Du willst sagen. Um auf den Cookie-Wert zuzugreifen, muss zweimal auf Page (PHP-Datei) zugegriffen werden. 1. Mal, um ein Cookie zu setzen, und 2. Mal, um auf das gesetzte Cookie zuzugreifen. Richtig?
Pratik
31

Wenn Sie unmittelbar nach dem Aufruf von auf den Wert eines Cookies zugreifen möchten, setcookie()können Sie diesen nicht verwenden $_COOKIE. Der Grund dafür liegt in der Art des Protokolls (siehe https://tools.ietf.org/html/rfc6265 ). Wenn Sie es verwenden setcookie(), wird ein Cookie definiert, das zusammen mit den restlichen HTTP-Headern an den Client gesendet werden soll (siehe http://php.net/manual/en/function.setcookie.php ). Aber $_COOKIEauf der anderen Seite enthält Variablen, die das aktuelle Skript übergaben über HTTP Plätzchen vom Client ( http://php.net/manual/en/reserved.variables.cookies.php ).

Wenn Sie $_COOKIEnach dem Anruf wechseln setcookie()- wie einige Antworten hier empfehlen - enthält es nicht mehr nur die Cookies des Kunden. Dies kann die Annahmen in dem in Ihrer Anwendung verwendeten Code von Drittanbietern beeinträchtigen und zu unerwünschten Site-Effekten führen. Im Allgemeinen ist dies keine gute Vorgehensweise und nur dann eine Option, wenn die Aufrufe von setcookie()Teil Ihres eigenen Codes sind.

Eine saubere und transparente Möglichkeit, einen Wert setcookie()innerhalb derselben Anforderung festzulegen, ist die Verwendung headers_list()(siehe http://php.net/manual/en/function.headers-list.php ) :

function getcookie($name) {
    $cookies = [];
    $headers = headers_list();
    // see http://tools.ietf.org/html/rfc6265#section-4.1.1
    foreach($headers as $header) {
        if (strpos($header, 'Set-Cookie: ') === 0) {
            $value = str_replace('&', urlencode('&'), substr($header, 12));
            parse_str(current(explode(';', $value, 1)), $pair);
            $cookies = array_merge_recursive($cookies, $pair);
        }
    }
    return $cookies[$name];
}
// [...]
setcookie('uname', $uname, time() + 60 * 30);
echo "Cookie value: " . getcookie('uname');

Beachten Sie jedoch, dass dies in PHP CLI (z. B. PHPUnit) nicht funktioniert. In einem solchen Fall können Sie Erweiterungen von Drittanbietern wie XDebug verwenden (siehe http://xdebug.org/docs/all_functions#xdebug_get_headers ).

Witrin
quelle
6
Nur eine echte Lösung hier. Sauber, ohne Änderungen des Codes von Drittanbietern, die setcookie enthalten könnten.
Michael
1
Ich bin nicht sicher, warum die Operation für die andere Lösung gestimmt hat, aber dies ist die richtige Lösung, die mir tatsächlich geholfen hat.
ChrisP777
Dies ist zu 100% die einzige Antwort, die für eine Produktionsumgebung realisierbar ist. Tolle Lösung @witrin
skidadon
Ich weiß nicht warum, aber der Parameter $ limit explode()funktioniert bei mir nicht. Er gibt nur ein Array-Element mit der gesamten Zeichenfolge zurück: ideone.com/7SnV9y
NaturalBornCamper
5

Sie müssen die Cookie-Variable selbst festlegen, wenn Sie sie sofort benötigen. Wenn Sie eine andere Seite laden, wäre das echte Cookie als Ergebnis der setcookie-Methode festgelegt worden.

setcookie('name', $value, time()+60*30);
$_COOKIE ['name'] = $value;
Joshua
quelle
1

Wir können dies mit AJAX-Aufrufen tun.

Wenn Sie Cookies auf Knopfdruck erstellen möchten, erstellen Sie zuerst einen AJAX-Aufruf zum Erstellen von Cookies. Nach dem Erfolg des ersten AJAX-Aufrufs können wir einen anderen AJAX aufrufen, um die Cookies zu erhalten.

    function saveCookie() {
            var base_url = $('#base_url').val();
            var url = base_url + '/index/cookie';
            $.ajax({
                'url': url,
                'type': 'POST',
                'success': function (data) {
                    if (data) {
                        var url = base_url + '/index/get_cookie';
                        $.ajax({
                            'url': url,
                            'type': 'POST',
                            'success': function (response) {
                                var container = $('#show');
                                if (response) {
                                    container.html(response);
                                }
                            }
                        });
                    }
                }
            });
        }

    <button type="button" onclick="saveCookie()">Save Cookie</button>
    <div id="show"></div>
Fakirchand Patidar
quelle
Wisse, dass OP auch bei guten Absichten eine Antwort nur auf PHP erfordert. :) Vielleicht hast du deshalb Downvotes, ich habe dich nicht downvotiert.
Máxima Alekz
upvoted, weil dies auch ein Ansatz ist, der berücksichtigt werden sollte!
Dhruv Thakkar
1

Ich hatte ein ähnliches Problem, bei dem ich eine Funktion aus einer enthaltenen Datei verwendet und mit einer Funktion gelöst habe, die sowohl den Wert des Cookies zurückgibt als auch das Cookie setzt.

function setCookie($input) {
  setcookie('uname', $input, time() + 60 * 30);
  return $input;
}

if(!isset($_COOKIE['uname'])) {
    $uname  = setCookie($whatever);
} else {
    $uname = $_COOKIE['uname'];
}

echo "Cookie value: " . $uname;
Sebastiaan Koopman
quelle
-1

Mit ob_start () und ob_flush () können Sie das Cookie an den Client senden und zur gleichen Laufzeit abrufen. Versuche dies:

ob_start();
setcookie('uname', $uname, time() + 60 * 30);
ob_flush();
echo "Cookie value: " . $_COOKIE['uname'];
Will Soares
quelle
Dies scheint nicht zu funktionieren (PHP 5.4 mit Nginx). Können Sie bitte erweitern?
Paul DelRe
-1

Die setcookie()Funktion Ihres Skripts wird ausgeführt, wenn der Webbrowser die Seite zum ersten Mal anfordert, in Ihrem Fall das Neuladen. Dieses Cookie wird im Browser des Benutzers gespeichert und steht Ihrem auf dem Server ausgeführten Skript erst bei der nächsten Anforderung oder in Ihrem Fall beim nächsten Neuladen zur Verfügung.

Bei der nächsten Anforderung sendet der Browser dieses Cookie an den Server, und das Array $_COOKIEhat den Wert, den Sie ursprünglich festgelegt haben, und der Browser wird bei der zweiten Anforderung zurückgesendet.

Robert Rocha
quelle
-3

Ich habe gleichzeitig mit der Erstellung des Cookies eine Konstante festgelegt

define('CONSTANT', true);
return setcookie('cookiename', 'cookie value goes here', time() + 60 * 60 * 24 * 30, '/');

Ich kann dann sofort etwas tun durch:

if(isset($_COOKIE['cookiename']) || $_COOKIE['cookiename'] || defined('CONSTANT') && CONSTANT)
virtualLast
quelle