Accediendo a $ _COOKIE inmediatamente después de setcookie ()

80

Estoy tratando de acceder al valor de una cookie (usando $_COOKIE) inmediatamente después de llamar a la setcookie()función en PHP. Cuando lo hago, $_COOKIE['uname']no está configurado. ¿Por qué?

Sin embargo, $_COOKIE['uname']tenga en cuenta que se establece como se esperaba en la próxima ejecución del script, como después de una actualización de página.

setcookie('uname', $uname, time() + 60 * 30);
echo "Cookie value: " . $_COOKIE['uname'];
heapzero
fuente
Desafortunadamente, las respuestas aquí no ofrecen una solución o sugieren malas soluciones, incluso las aceptadas, consulte stackoverflow.com/questions/3230133#34465594 .
hasta el
@witrin su enlace provisto parece redirigir a esta misma q / a.
trainoasis
Esto no es posible. Tienes que "falsificarlo", ya sea configurando las entradas correspondientes en $_COOKIEti mismo o realizando una redirección (a la misma página) inmediatamente.
caw

Respuestas:

37

$_COOKIEse establece cuando se carga la página, debido a la naturaleza sin estado de la web. Si desea acceso inmediato, puede configurarlo $_COOKIE['uname']usted mismo o usar una variable intermedia.

Por ejemplo:

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
fuente
21
esto no hace que la cookie sea accesible antes de una actualización de la página ... vea la respuesta de Mark Baker más abajo para eso :)
pathfinder
Eso no es cierto. He hecho la suposición, basada en el código del OP, que usan $unameen su script. Mientras que Mark Baker usa $_COOKIE['uname']directamente.
Jason McCreary
1
Siento haberlo dicho un poco mal. Para mis propósitos, que son para un script asincrónico, la configuración de $ _COOKIE en realidad no configuró la cookie y la envió de vuelta al navegador (también necesitaba la cookie allí), solo la hizo disponible en mi script. También debe usar setcookie (), lo que hace la respuesta de Mark Baker. Además, su código es mucho más corto y más útil para las personas que vienen aquí desde una búsqueda en Google.
Pathfinder
Yo uso setcookie(). Es posible que esta respuesta no satisfaga sus necesidades exactas. Pero eso no lo hace mal . El OP y el SO han encontrado que esta respuesta es útil.
Jason McCreary
2
No entiendo por qué esta respuesta está marcada como "la respuesta". No explica cómo usar la cookie directamente, y el código proporcionado es como el mismo OP publicado. Después setcookie()en ese código no es posible acceder$_COOKIE['uname']
Isthar
153

La cookie no se configura hasta que la respuesta se envía al cliente y no está disponible en su PHP hasta la próxima solicitud del cliente después de eso.

Sin embargo, cuando configura la cookie en su secuencia de comandos, puede hacer lo siguiente:

setcookie('uname', $uname, time()+60*30);
$_COOKIE['uname'] = $uname;
Mark Baker
fuente
2
Solución muy sencilla. ¡Gracias!
dawoodman71
1
Buena cosa. Me pregunto cómo establece la segunda línea el tiempo de vencimiento cuando no se ha pasado.
Martinedwards
2
@martinedwards La segunda línea no establece ningún tiempo de vencimiento ... se establece para la duración de la solicitud; exactamente de la misma manera que existe un valor de cookie pasado con una solicitud de un navegador durante la duración de la solicitud
Mark Baker
@MarkBaker ¡¡Solución simple !! Muchas gracias
Shan
Quieres decir. para acceder al valor de la cookie, se debe acceder dos veces a la página (archivo php). Primera vez para configurar la cookie y segunda vez para acceder a la cookie configurada. ¿Correcto?
Pratik
31

Si desea acceder al valor de una cookie inmediatamente después de llamar al, setcookie()no puede usar $_COOKIE. La razón de esto está en la naturaleza del protocolo (consulte https://tools.ietf.org/html/rfc6265 ). Cuando lo usa setcookie(), define una cookie que se enviará junto con el resto de los encabezados HTTP al cliente (consulte http://php.net/manual/en/function.setcookie.php ). Pero, $_COOKIEpor otro lado, contiene variables pasadas al script actual a través de cookies HTTP desde el cliente ( http://php.net/manual/en/reserved.variables.cookies.php ).

Cuando cambia $_COOKIEdespués de llamar setcookie(), como recomiendan algunas respuestas aquí, ya no contiene solo las Cookies del cliente. Esto podría interferir con las suposiciones hechas en el código de terceros utilizado en su aplicación y puede resultar en efectos no deseados en el sitio. Entonces, en general, no es una buena práctica y solo es una opción cuando las llamadas de setcookie()son parte de su propio código.

Una forma limpia y transparente de obtener un valor establecido setcookie()dentro de la misma solicitud es usar headers_list()(consulte 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');

Pero tenga en cuenta que esto no funcionará en PHP CLI (por ejemplo, PHPUnit). En tal caso, podría utilizar extensiones de terceros como XDebug (consulte http://xdebug.org/docs/all_functions#xdebug_get_headers ).

Witrin
fuente
6
Aquí solo hay una solución real. Limpio, sin modificaciones del código de terceros que podría contener setcookie.
Michael
1
No estoy seguro de por qué la operación votó a favor de la otra solución, pero esta es la solución correcta que realmente me ayudó.
ChrisP777
Este 100% es la única respuesta viable para un entorno de producción. Great solution @witrin
skidadon
No sé por qué, pero el parámetro $ limit no explode()funciona para mí, solo devuelve un elemento de matriz con toda la cadena dentro: ideone.com/7SnV9y
NaturalBornCamper
5

Debe configurar la variable de la cookie usted mismo si la necesita de inmediato; para cuando cargue otra página, la cookie real se habrá configurado como resultado del método setcookie.

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

Podemos hacer esto usando llamadas AJAX.

Si queremos crear cookies al hacer clic en el botón, primero cree una llamada AJAX para crear cookies y luego, con el éxito de la primera llamada AJAX, podemos llamar a otro AJAX para obtener las cookies.

    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
fuente
Sepa que incluso cuando las intenciones son buenas, OP requiere una única respuesta de PHP. :) Quizás es por eso que tienes votos negativos, yo no te voté.
Máxima Alekz
votado porque este es también un enfoque que debería ser considerado.
Dhruv Thakkar
1

Tuve un problema similar en el que usé una función de un archivo incluido y lo resolví con una función que devuelve el valor de la cookie y configura la cookie.

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
fuente
-1

Usando ob_start () y ob_flush () puede enviar la cookie al cliente y recuperarla en el mismo tiempo de ejecución. Prueba esto:

ob_start();
setcookie('uname', $uname, time() + 60 * 30);
ob_flush();
echo "Cookie value: " . $_COOKIE['uname'];
Will Soares
fuente
Esto no parece funcionar (PHP 5.4 con nginx). ¿Puedes expandir?
Paul DelRe
-1

Tu guión setcookie() función de ejecuta cuando el navegador web solicita la página por primera vez, en su caso, la recarga. Esta cookie se almacena en el navegador de los usuarios y no está disponible para su secuencia de comandos que se ejecuta en el servidor hasta la próxima solicitud, o en su caso, la próxima recarga.

En la siguiente solicitud, el navegador envía esa cookie al servidor y la matriz $_COOKIEtendrá el valor que configuró inicialmente y el navegador lo devolverá en la segunda solicitud.

Robert Rocha
fuente
-3

Configuré una constante al mismo tiempo que se creó la cookie

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

Entonces puedo hacer algo de inmediato:

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