2011-12-27 15 views
10

Vorrei sapere se esiste un modo per impedire a PHP di inviare un cookie quando chiama session_start().Impedisci a php session_start() di inviare un cookie

mio caso d'uso è per un'ottimizzazione del sito:

  • (1a) in primo luogo ho aprire una sessione/inviare le intestazioni.
  • (1b) Quindi genera ed emette del contenuto di testo.
  • (1c) Per migliorare la lettura/scrittura della sessione, chiamo "session_write_close" non appena non avrò più bisogno di scrivere nella sessione.
  • (2) Finalmente ho un processo di rendering post-page (per le statistiche) che richiede un accesso in scrittura alla sessione. La sessione è chiusa, non posso richiamare session_start() di nuovo poiché invia un cookie ed è troppo tardi per quello. Questo è un processo molto complicato, quindi devo farlo dopo che la pagina è stata inviata al client.

Il client ha già ricevuto un cookie di sessione. Quindi non ho bisogno di session_start() per inviare una nuova (e ridondante).

Qualcuno conosce un modo per intercettare il cookie o qualcosa di simile? Ovviamente voglio evitare "Impossibile inviare cookie di sessione - intestazioni già inviate". Questo errore è invisibile per l'utente perché la pagina è già sottoposta a rendering ma risulta sgradevole nei registri.

La mia domanda sembra essere ridondante, ma non lo è. So come funzionano le intestazioni e i contenuti (invia prima le intestazioni, i contenuti dopo). È solo che PHP non mi lascia fare quello che voglio.

risposta

11

Mi piacerebbe sapere se c'è un modo per impedire a PHP di inviare un cookie quando si chiama session_start().

Sì c'è, dicendo a PHP di non utilizzare i cookie per le sessioni. L'impostazione PHP è session.use_cookies:

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

Con i cookie sono abilitati di default perché sono considerati più sicuri quindi utilizzando parametri URL (vedi Sessions and security­Docs).

(2) Infine ho un processo di rendering post-page (per le statistiche) che richiede un accesso in scrittura alla sessione. La sessione è chiusa, non posso richiamare session_start() di nuovo poiché invia un cookie ed è troppo tardi per quello. Questo è un processo molto complicato, quindi devo farlo dopo che la pagina è stata inviata al client.

Probabilmente è possibile indicare a PHP che il cookie è già impostato aggiungendolo nello $_COOKIE superglobal array­Docs. Non l'ho mai sperimentato, ma nel caso in cui si usi session_start() e PHP si acceda che il cookie di sessione è già stato impostato (dal browser, non da PHP, $_COOKIE rappresentano i cookie del browser), non invierà le intestazioni (di nuovo) per impostare il cookie (che come ho capito è quello che vuoi).


Edit: Alcuni script di test di giocare 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(); 

è necessario chiamare con un browser web (e le sessioni di PHP deve essere configurato per funzionare).

+0

Grande, la prima soluzione funziona 'ini_set ('session.use_cookies', 0)'. La seconda soluzione non sembra avere alcun effetto (l'ho già provata ieri in realtà) ma può essere relativa alla mia configurazione di php. Passerò più tempo più tardi su questa seconda soluzione. Grazie ! – Mat

+0

Ho eseguito alcuni test con '$ _COOKIE'. Funziona in realtà ma sarebbe come usare 'ini_set();' e con 'ini_set()' è più chiaro cosa faccia. Aggiungerò uno script alla risposta che ho usato per giocare, un codice su '$ _COOKIE' è commentato. Decommentalo per generare un nuovo ID di sessione per la prima sessione. Questo mostra anche come '$ _COOKIE' è correlato a' session_start() '. – hakre

+0

'ini_set ('session.use_cookies', '0');' funziona perfettamente per l'intestazione del cookie, ma non per l'intestazione della cache che farà scadere il cookie SID. Vedere la risposta di @techdude per usare 'session_start (['use_cookies' => '0', 'cache_limiter' => '']);' – Code4R7

-3

È possibile utilizzare ob_start() la funzione di tamponare l'intestazioni/contenuti, si può cancellare il contenuto del buffer utilizzando ob_clean()

+4

ob_start non bufferizza l'intestazione. Solo contenuto corporeo. Quindi non funziona. – Mat

4

ho pensato di citare un altro ottimo modo per evitare che il cookie (e il limitatore di cache) intestazioni vengano inviati quando si chiama session_start.

La sessione session_start accetta una serie di opzioni in cui è possibile impostare qualsiasi sessione. variabili prefisso e puoi disabilitare queste cose solo per quella chiamata.

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

noti che use_cookies mantiene il cookie venga inviato, e impostando il limitatore di cache per una stringa vuota impedisce di aggiornare gli header di cache (non la caratteristica migliore documentato).

Qui ci sono due avvisi che questo risolverà (questo è utile quando è necessario lavorare attraverso più sessioni).

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

e

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

Questa dovrebbe essere la risposta migliore! +1 – Code4R7

Problemi correlati