Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SESSION issues 1

Status
Not open for further replies.

lifelineamerica

Programmer
Aug 9, 2006
23
US
This seems so silly but its driving me nuts!
I redirect people who reached a page they shouldn't have. So if the session I am looking for is not there, they are redirected back to the page with variable ks=1 set (ks as in kill session)

I have this condition in the home page where if they have been redirected to it as above with the ks set to 1 I want to destroy all session, so...
Code:
//keep the session going
//but I condition it otherwise got error that it exists
if(!isset($_SESSION))
{
session_start();
}

if ((isset($ks))&&(isset($_SESSION)))
{
session_destroy();
}

Doing that, I get the error :
Warning: session_destroy(): Trying to destroy uninitialized session


So I add session_start(); to the condition as so...

Code:
//keep the session going
//but I condition it otherwise got error that it exists
if(!isset($_SESSION))
{
session_start();
}

if ((isset($ks))&&(isset($_SESSION)))
{
[b]session_start();
[/b]session_destroy();
}

and I get the following error: Notice: A session had already been started - ignoring session_start()

What the #$%^%&? Does it find a session or does it not? Its not happy either way with me !!!!
 
you don't say what version of php you are using, and things have changed a little over the 5.x branch.

but a reasonable way of starting a session is like this
Code:
if(session_id() == '') session_start();

you say you redirect people with the $ks variable set. I assume that a redirect is to another page and thus is done like this

Code:
header('Location: ' . '[URL unfurl="true"]http://domain.com/path/to/some/script.php?ks=1');[/URL]
exit();

which is fine (but almost certainly unnecessary). But then the ks variable would not be in $ks but would be in $_GET['ks']. Unless you have register_globals turned on, in which case you have bigger issues and should go back and read the manual on security before doing anything else.

lastly, to destroy a session the call to session_destroy is only part of the process. This is the normal way to kill the session fully

Code:
if(session_id() == '') session_start();
$_SESSION = array();
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}
session_destroy();

on the second code snip the error occurs because you are testing for the existence of the $_SESSION superglobal as an AND to the existence of $ks. If the $_SESSION superglobal has been instantiated then a session has started. Thus trying to start the session again (without first stopping it) will raise a notice.

Note that a notice is NOT an error. it is just information for you as a developer. You can choose to develop whilst ignoring (most) notices. They are most useful for debugging as often they point out small faults (like forgetting to enquote array keys) which you can fix before sending your code to the production server. On the production server, notices and all other error messages will be turned off so your users will not see them.
 
Thanks jpadie for your response.
I'll answer in chronological order.

I'm running on PHP Version 5.4.14

You assumed correctly the way I'm doing the redirect, but you state that it is
almost certainly unnecessary
Why do you think so?

Next, I have superglobals set to off of course (I've been coding PHP for ten years so I know that much). So yeah, I have on top of the page preceeding our code :

Code:
if (isset($_REQUEST["ks"]))$ks=$_REQUEST["ks"];

(I use REQUEST there because sometimes its GET and sometimes POST. That'll catch me both in one shot.)

I never worried about any notices until now, I never pre declared variables etc., and hence my error logs were extremely long. Lately the general sentiment has been that this is laziness and can also lead to vulnerabilities so I decided to redo a whole website. It took me hours and hours to go through every page and fix Notice by Notice and Warning by Warning.

Next. Forgive me, but I don't see what you added in your lengthy way to kill a session. It looks as if you are building more into your session there, rather than taking it apart. Additionaly, PHP's documentation simply states you can use session_destroy();


Finally, back to my problem.

So I removed the double condition ($ks and isset session). I'll go by the following code:

Code:
if (isset($_REQUEST["ks"]))$ks=$_REQUEST["ks"];

if(!isset($_SESSION))
{
session_start();
}

if (isset($ks))
{
session_destroy();
}

SO why do I get the following error:

Warning: session_destroy(): Trying to destroy uninitialized session


I figure that the session was initialized for sure in one of two ways as in beginning of this code.
What's more, if remove the condition in the begining to check if the session is set, and I just do session_start(), I get the error:
Code:
A session had already been started - ignoring session_start
, so I know the session is definitely here.

So it appears to me that the session is started but not initialized?
 
to kill a session you should zero the superglobal send a timeout on the session cookie and then call session_destroy. I am surprised that the php manual says otherwise. in my country it does not and takes pains to point out what I had posted.

instead of testing for the presence of a superglobal please do as I suggested and check for a non zero length session id.

I have not tested this (it is late where I am) but I suspect that the sessions super global always exists whether or not the session has been started. but it is not accessible until session_start is called. so testing for the existence of $_SESSIONS may be sending you the wrong way. as said, I have always instantiated a session by first checking the value session_id() and that has always worked fine.

as to why it is unnecessary to redirect externally; when the browser is already connected to your server why send it away unless you need more information from the user? set whatever variables you want in whatever scope you need and then go to the next place in your script by including a particular file or calling a function or whatever flow control process you use. there is seldom a need to introduce bandwidth overhead and the latency of a redirect. particularly in a well crafted despatch based app.
 
You were correct jpadie (as always), about zeroing the super global and sending a timeout on the session cookie and you were also correct about PHP mentioning it right there on the php.net session documentation page.
So now I have it like this and my problems have all been solved:
PHP:
if ((isset($ks))||(isset($lo)))
{
$_SESSION = array();
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
// Finally, destroy the session.
session_destroy();
session_write_close();
//I am however having an issue with the following:
session_start();
$_SESSION["reserving"]=1;
}
}

But I'm having an issue of starting a new session after I kill the old one. (see note in the code above).
It appears the new session is not being set. Is it not possible to start a new session right after an old session was killed?
 
it's a little counter-intuitive to destroy the session completely (including setting cookies etc) and then restart it again in the same transaction.

since the session cookie would be called the same you would essentially be sending the following headers in pseudo code

setcookie session expire in the past
setcookie session value something expire at browser close

the browser is likely to ignore the first (thus not expiring the old cookie) and process the second.

I wonder whether this is what you want? if you are still looking to session-track users but are worried that they might have the wrong data in the session store why not

1. regenerate the session_id
2. unset the session key that tracks login, and any other associated keys

(and even item 1 is not necessary).

but going back to your question, there is no reason why a session cannot be started right after one was destroyed. However the session key may not be being saved with the browser due to the cookie clash I mentioned above - it could be that the browser processes the first and not the second directive - I don't know whether there is a standard behaviour that would/should apply.

So perhaps recast the code a bit to zero all the server side information and then recreate it with a new session_id and keep the cookie live (thus keeping the session live but not the session data)

Code:
<?php
if ((isset($ks))||(isset($lo))):
	$_SESSION = array();
	
	/*
	if (ini_get("session.use_cookies")):
		$params = session_get_cookie_params();
		setcookie(session_name(), '', time() - 42000,
		$params["path"], $params["domain"],
		$params["secure"], $params["httponly"]
	);
	endif;
	*/
	// Finally, destroy the session.
	session_destroy();
	session_write_close();

	session_start();
	session_regenerate_id();
	$_SESSION["reserving"]=1;
        session_write_close();
endif;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top