Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent php session_start() to send a cookie

I would like to know if there is a way to prevent PHP from sending a cookie when calling session_start().

My use case is for a site optimisation:

  • (1a) I first open a session/send headers.
  • (1b) Then generate and output some text content.
  • (1c) To enhance session read/write I call "session_write_close" as soon as I don't need to write in the session anymore.
  • (2) Finally I have a post-page rendering process (for stats) that requires a write access to the session. The session is closed, I cannot call session_start() again since it sends a cookie and it's to late for that. This is a computation-heavy process, so I have to do it after the page is sent to the client.

The client already received a session-cookie. So I don't need session_start() to send a new (and redundant) one.

Does someone know a way to intercept the cookie or something similar ? Of course I want to avoid the "Cannot send session cookie - headers already sent". This error is invisible for the user because the page is already renderered but it looks ugly in the logs.

My question seems to be a redundant one, but it is not. I know how headers and content work (send headers first, content after). It's just that PHP does not let me do what I want.

like image 763
Mat Avatar asked Dec 27 '11 11:12

Mat


People also ask

What does session_start () do in PHP?

session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie. When session_start() is called or when a session auto starts, PHP will call the open and read session save handlers.

What is PHP session_start () and Session_destroy () function?

session_destroy() destroys all of the data associated with the current session. It does not unset any of the global variables associated with the session, or unset the session cookie. To use the session variables again, session_start() has to be called. Note: You do not have to call session_destroy() from usual code.

Do I need to call session_start on every page?

It must be on every page you intend to use. The variables contained in the session—such as username and favorite color—are set with $_SESSION, a global variable. In this example, the session_start function is positioned after a non-printing comment but before any HTML.

Can PHP session work without browser cookies appending session id in URL?

You can also login without Cookies only by Session Id and Time, but you have to write them both in your Database direct after Successful Login. I have in index. php something like this that will always generate a new session id based on time and the old session id if conditions are not verified. if ($_SESSION['id'] !=


1 Answers

I would like to know if there is a way to prevent PHP from sending a cookie when calling session_start().

Yes there is, by telling PHP to not use cookies for sessions. The PHP setting is session.use_cookies:

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

By default cookies are enabled because they are considered more safe then using URL parameters (see Sessions and security­Docs).

(2) Finally I have a post-page rendering process (for stats) that requires a write access to the session. The session is closed, I cannot call session_start() again since it sends a cookie and it's to late for that. This is a computation-heavy process, so I have to do it after the page is sent to the client.

It's probably possible to tell PHP that the cookie is already set by adding it into the $_COOKIE superglobal array­Docs. I never experimented with it, but in case you use session_start() and PHP sees that the session cookie has been already set (by the browser, not PHP, $_COOKIE represent the browser cookies), it won't send the headers (again) to set the cookie (which as I understand you is what you want).


Edit: Some test script to play around with:

<?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();

You need to call it with a web-browser (and PHP sessions must be configured to work).

like image 120
hakre Avatar answered Sep 27 '22 19:09

hakre