php.net says:
Session support in PHP consists of a way to preserve certain data across subsequent accesses.
A visitor accessing your web site is assigned a unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL.
I'm trying to see the second option in action, i.e., php passing the session id via query string. I'm doing this solely for educational purposes. I'm aware this is not recommended.
Reproducing my experiment:
I have the following script stored in /var/www/html/script.php:
<?php
session_start();
if (isset($_SESSION["accesses"])) ++$_SESSION["accesses"];
else $_SESSION["accesses"] = 1;
echo "This page has been accessed ", $_SESSION["accesses"], " times";
?>
With the default php settings in php.ini, that is:
session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0
everything works fine. That is, when I go to localhost/script.php in my browser and refresh the page few times, the counter works as it suppose to.
When I disabled cookies in my browser the counter no longer works when I refresh the page multiple times (it stays at 1 all the time). Then I read online that maintaining php session via query string is turned off by default. I then went and modified php.ini as follows:
session.use_cookies = 0
session.use_only_cookies = 0
session.use_trans_sid = 1
After reloading the apache2 with
service apache2 reload
the counter in the script does not work anyway. I tried few more combinations of settings in php.ini but with no luck.
I use PHP 5.5.9 and Apache 2.4.7.
Question:
My understanding is that when cookies are disabled and passing session id via query string is enabled in php.ini, after the first GET, php should see that there was no session id in query string. Then php would initialize a session id for a user and send a response that would redirect the client to the same URL with with session id in the query string. All this is happening without writing any code -- it is done by the php module to maintain session.
This is at least what I was expecting would happen. How much of this is actually true? Am I assuming to much about things that PHP does automatically? But if I do, then what is this "This is either stored in a cookie on the user side or is propagated in the URL." on php.net about? If the _SESSION does not work when cookies are disabled, shouldn't it simply say so?
EDIT:
Additional comments to answer below:
Mystery solved. Maintaining session via query string works as in the starred answer below. To see it in action, I modified the script in /var/www/html/script.php to:
<?php
session_start();
if (isset($_SESSION["accesses"])) ++$_SESSION["accesses"];
else $_SESSION["accesses"] = 1;
echo "This page has been accessed ", $_SESSION["accesses"], " times";
echo '<br><a href="script.php">revisit</a>';
?>
You can see that simply refreshing the page is treated by PHP as multiple attempts to initialize a new session. Only when you click the link "revisit" the session id is actually embedded (automatically by PHP) in the link and the counter starts to work (from that point on, it increments either by following the link again or refreshing).
One more word about settings in php.ini (Note: I did all the experiments below in Firefox 39.0. The behaviour may differ in other browsers.):
Option 1: If you want PHP to use cookies to maintain the session (if they are enabled in the client browser) and to use query string (if the cookies are disabled), make sure your php.ini has the following settings:
session.use_cookies = 1
session.use_only_cookies = 0
session.use_trans_sid = 1
The first one is enabled by default (at least in my version of PHP, see above). The remaining two are modified from default values. You need to modify both of them.
It's quite interesting how this works, because when you do a first GET request, you don't pass a session id in the query string and the cookie is not set, so PHP doesn't know whether it should rewrite the links (see the starred answer below) or set a cookie (which could potentially fail).
What it does is it attempts BOTH: you can see, that on one the first access, the "revisit" link in the example below was rewritten by php to contain session ID but also the first response from the server attempts to set a cookie.
Only after the second request, PHP knows whether cookie was successfully planted. If yes, it does not rewrite the link any more. If not, it keeps rewriting the links to contain session id in the query string.
Option 2: If you want PHP to use cookies to maintain the session (if they are enabled in the client browser) but NOT to resort to using query string if the cookies are disabled, stick with default settings, which are:
session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0
Option 3: If you want PHP to exclusively use query string to maintain session (which is NOT RECOMMENDED), even if the cookies are enabled, use:
session.use_cookies = 0
session.use_only_cookies = 0
session.use_trans_sid = 1
Note that those are the exact opposite from the default PHP settings. There is a good reason for that.
session id's into thequerystringcan lead tosession hijackingthough.