2011-12-27 20 views
10

Me gustaría saber si existe alguna forma de evitar que PHP envíe una cookie al llamar al session_start().Prevenir php session_start() para enviar una cookie

Mi caso de uso es para una optimización del sitio:

  • (1a) La primera vez que abra una sesión/enviar cabeceras.
  • (1b) A continuación, genere y envíe contenido de texto.
  • (1c) Para mejorar la lectura/escritura de sesión, llamo "session_write_close" tan pronto como ya no necesito escribir en la sesión.
  • (2) Finalmente tengo un proceso de representación posterior a la página (para estadísticas) que requiere un acceso de escritura a la sesión. La sesión está cerrada, no puedo volver a llamar a session_start() ya que envía una cookie y es demasiado tarde para eso. Este es un proceso de cómputo pesado, así que tengo que hacerlo después de que la página se envíe al cliente.

El cliente ya recibió una cookie de sesión. Así que no necesito session_start() para enviar una nueva (y redundante).

¿Alguien sabe una forma de interceptar la cookie o algo similar? Por supuesto, quiero evitar el mensaje "No se puede enviar la cookie de sesión: los encabezados ya enviados". Este error es invisible para el usuario porque la página ya está renderizada, pero se ve fea en los registros.

Mi pregunta parece ser redundante, pero no lo es. Sé cómo funcionan los encabezados y el contenido (enviar encabezados primero, contenido después). Es solo que PHP no me deja hacer lo que quiero.

Respuesta

11

Me gustaría saber si existe una forma de evitar que PHP envíe una cookie al llamar a session_start().

Sí, diciéndole a PHP que no use cookies para las sesiones. La configuración de PHP es session.use_cookies:

ini_set('session.use_cookies', 0); # disable session cookies 
session_start(); 

por las cookies están habilitadas por defecto, ya que se consideran más seguros a continuación, utilizando parámetros de URL (véase Sessions and security­Docs).

(2) Finalmente tengo un proceso de representación de post-página (para estadísticas) que requiere un acceso de escritura a la sesión. La sesión está cerrada, no puedo volver a llamar a session_start() ya que envía una cookie y es demasiado tarde para eso. Este es un proceso de cómputo pesado, así que tengo que hacerlo después de que la página se envíe al cliente.

Probablemente sea posible decirle a PHP que la cookie ya está establecida agregándola al $_COOKIE superglobal array­Docs. Nunca experimenté con eso, pero en caso de que use session_start() y PHP vea que la cookie de sesión ya se ha configurado (por el navegador, no por PHP, $_COOKIE representan las cookies del navegador), no enviará los encabezados (nuevamente) para establecer la cookie (que, como yo te entiendo, es lo que quieres).


Editar: Algunos script de prueba para jugar con:

<?php 
header('Content-Type: text/plain;'); 

echo "Incomming Cookies:\n"; 
print_r($_COOKIE); 

// to simulate that this is a new session, the session cookie is removed 
// which makes PHP think it is a new session when invoking session_start() 
// unset($_COOKIE['PHPSESSID']); 

// run the first session 
session_start(); // creates the session cookie (as we don't have one yet) 
printf("Session %s has been started: %s\n", session_name(), session_id()); 
var_dump($_SESSION); 
$_SESSION['variable'] = isset($_SESSION['variable']) ? $_SESSION['variable']++ : 0; 
session_commit(); 

printf("Session has been closed, remaining id is: %s\n", session_id()); 

// visual confirmation that session cookie has been created 
echo "Outgoing Cookies:\n"; 
print_r(headers_list()); 

// run the second session 
ini_set('session.use_cookies', 0); # disable session cookies 
session_start(); 
printf("Second session %s has been started: %s\n", session_name(), session_id()); 
var_dump($_SESSION); 
$_SESSION['2nd-variable'] = isset($_SESSION['2nd-variable']) ? $_SESSION['2nd-variable']++ : 0; 
session_commit(); 

es necesario llamar con un navegador web (y las sesiones de PHP debe estar configurado para funcionar).

+0

Grande, la primera solución funciona 'ini_set ('session.use_cookies', 0)'. La segunda solución no parece tener ningún efecto (ya lo intenté ayer en realidad) pero puede ser relativa a mi configuración de php. Pasaré más tiempo más tarde en esta segunda solución. Gracias ! – Mat

+0

Realicé algunas pruebas con '$ _COOKIE'. En realidad funciona, pero esto sería lo mismo que usar 'ini_set();' y con 'ini_set()' es más claro lo que hace. Añadiré un script a la respuesta que usé para jugar, se comenta un código sobre '$ _COOKIE'. Descoméntelo para generar una nueva identificación de sesión para la primera sesión. Esto también muestra cómo '$ _COOKIE' está relacionado con' session_start() '. – hakre

+0

El 'ini_set ('session.use_cookies', '0');' funciona perfectamente para el encabezado de la cookie, pero no para el encabezado del caché que expirará la cookie SID. Ver la respuesta de @techdude para usar 'session_start (['use_cookies' => '0', 'cache_limiter' => '']];' – Code4R7

-3

Puede utilizar ob_start() función de amortiguar la encabezados/contenido, es posible borrar el contenido del búfer usando ob_clean()

+4

ob_start no buffer encabezado. Solo contenido corporal Por lo tanto, no funciona. – Mat

4

pensé que debería mencionar otra gran manera de prevenir la cookie (y el limitador de caché) cabezazos de ser enviado cuando se llama session_start.

La llamada session_start toma una matriz de opciones donde puede establecer cualquiera de la sesión. prefijar variables, y puede deshabilitar estas cosas solo para esa llamada.

session_start(array(
    'use_cookies' => '0', 
    'cache_limiter' => '' 
)); 

Tenga en cuenta que use_cookies mantiene la cookie de ser enviado, y establecer el limitador de caché en una cadena vacía evita que la actualización de las cabeceras de caché (no la característica mejor documentado).

Aquí hay dos avisos que esto solucionará (esto es útil cuando necesite trabajar en varias sesiones).

Warning: session_start(): Cannot send session cookie - headers already sent 

y

Warning: session_start(): Cannot send session cache limiter - headers already sent 
+0

¡Esta debería ser la mejor respuesta! +1 – Code4R7

Cuestiones relacionadas