Reputation: 45
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.
Upvotes: 1
Views: 1665
Reputation: 477
Because session ID's in query strings are absolutely not recommended but possible in PHP 4.2.0+, most hosters disable them in your apache configuration by default. Just check your apache/vhost/htaccess configuration for this line:
php_flag session.use_trans_sid off
Update (thanks to IMSoP): To check whether session.use_trans_sid
is disabled somewhere or not, you can just add phpinfo();
to your script and check the setting's value.
If you are using a PHP version older than 4.2, you have to compile PHP using the --enable-trans-sid
parameter, see PHP manual:
Unless you are using PHP 4.2.0 or later, you need to enable it manually when building PHP. Under Unix, pass --enable-trans-sid to configure. https://www.php.net/manual/en/session.idpassing.php
If you did so, you can enable session.use_trans_sid
as you already did and PHP will care about the ID.
Otherwise, you have to keep the ID manually, e.g., like this:
<?php echo 'mypage.php?'.htmlspecialchars(SID); ?>
Upvotes: 1
Reputation: 97898
Am I assuming too much about things that PHP does automatically?
Yes, this part doesn't happen:
Then php would ... send a response that would redirect the client to the same URL with with session id in the query string.
What PHP does with that option is rewrite links in the page so that when you click through to the next page, the session ID will be maintained. There is nothing which forces you away from a page without a session ID, that's just seen as a sign to create a new session.
So when you test by refreshing the same page, it's like refreshing a login form rather than submitting it - you are telling PHP to start a new session each time.
(Note: I've never actually used this feature, so I may be completely wrong, and am open to polite corrections.)
Upvotes: 2