...

View Full Version : $_SESSION vars vs. "normal" vars ???



Tyree
12-20-2006, 11:31 PM
Okay, I'm looking for a php guru to clear something up for me.

I was helping a guy on another forum figure out his login script. He was having a hard time getting his old sessions to end so he could log in with a new username.

He had 3 pages, a page that did nothing but end the current session (index.php), a page to login (login.php), and a page to display the username if logged in (members.php).

We tried a few things and then he replied and said that he had to add unset($username) to index.php before it worked.

What baffles me about that is this:
It is my impression that normal vars such as, $username, are only useable on the current page. So, why in the world did it matter to login.php and members.php if he unset the var $username on index.php? He had already done a session_unset(), session_destroy(), $_SESSION = array() AND unset($_SESSION['username']). None of them worked, apparently, but adding unset($username) did.

I'm so confused! :confused:

Thanks for any clarification you can provide! Help cure my ignorance! :D

marek_mar
12-20-2006, 11:52 PM
There shouldn't be such a relation.
Check the source for extract($_SESSION) or assignments to variables from $_SESSION.

koyama
12-20-2006, 11:54 PM
sounds strange... I cannot exactly follow all the steps...

Could it be that he had Register Globals (http://www.php.net/register_globals) on in his php settings? In that case variables are created automatically so that if we were sending e.g. POST data with a name/value pair: (username=someone) we get created the variable $username = 'someone' in addition to $_POST['username'] = 'someone'.

Tyree
12-20-2006, 11:58 PM
I didn't think there should be either. Glad I'm not that stupid! :)

This was his final code:


index.php



session_start();
unset($_SESSION['username']);
unset($username);
session_destroy();
$_SESSION = array();


then the rest of the page including a log-in form posting data to login.php

login.php



if (!$_POST['username'] || !$_POST['password']) { include("badUser.php"); exit; }
else {
include("mysql.php");
$result = mysql_query( "SELECT * FROM fotoUsers WHERE username='$username' && password='$password'");
$num_rows = mysql_num_rows( $result );
if ($num_rows != "1") { include("badUser.php"); exit; }
else {
session_start();
$_SESSION["username"] = $username;
mysql_close( $link );
include("main.php");
}
}


main.php (the page i want to display to members) is called if the log-in is successful.

main.php



print "<p class=menu>Logged in as: $username | <a href=\"index.php\">LOG OUT</a></p>";


this line is in main.php at the top. It shows who you are logged in as. you can also log-out (which takes you back to index.php and clears the session and var).

and finally you need to authenticate every page that is to be protected:

validate.php



session_start();
if ( isset( $_SESSION[ 'username' ] ) && ( $_SESSION[ 'username' ] = $username ) )
{
}
else
{
include("badUser.php");
exit;
}


This is called as an include at the beginning of every new page.


Can you see why "unset($username);" would have done anything at all?

Tyree
12-21-2006, 12:01 AM
sounds strange... I cannot exactly follow all the steps...

Could it be that he had Register Globals (http://www.php.net/register_globals) on in his php settings? In that case variables are created automatically so that if we were sending e.g. POST data with a name/value pair: (username=someone) we get created the variable $username = 'someone' in addition to $_POST['username'] = 'someone'.

But, would that matter on another page altogether? Especially when the unset-ing page delivered no post data? I don't know...I'm lost! :D

koyama
12-21-2006, 12:50 AM
Well, you are right... this would not be the explanation. I can't figure it out either. It would be nice if he had added a 'var_dump($username);' statement on the index.php page to see what value it actually had.

I have another theory then:

The unset($username) statement on the index.php does nothing. Couldn't he have been wrong?
I noticed that the login.php page outputs text and isn't just redirecting (the main.php). This might be a weakness. After clicking logout, how did he actually know that he wasn't logged out?---Since in either case he would just be seeing the login form (Am I right?). My theory is that at some point after logging out he has clicked the back button loading login.php again. At this point POST data would be sent again---in effect logging him in again without going through the form!

What do you think?

koyama
12-21-2006, 01:59 AM
Well, I just realized that having register_globals on also affects session variables, so that my original explanation holds anyway. Where is the variable $username in index.php being used?

In fact, he must be having register_globals on since otherwise it would not be possible to have in login.php (since $username and $password wouldn't be set):


...
$result = mysql_query( "SELECT * FROM fotoUsers WHERE username='$username' && password='$password'");
...

I think that the weakness I'm talking about in my previous post should still be examined, though.:)

Tyree
12-21-2006, 02:12 AM
I actually have register_globals turned on for my site too. I use a similar login scenario but I don't have to unset normal vars. A simple session_unset() and session_destroy() does the trick and all session vars are gone. It's an interesting thought, but I really can't say for sure that's the reason for this. (Yes, I know I need to turn register_globals off, but I have ALOT of recoding to do before I do that! :) )

He MAY have changed something else at the same time that he added that line. Or maybe he hadn't uploaded the file after he made a particular change so the browser was still using an old file. There are numerous little things like that that may have happened that made it APPEAR the unset() did the trick.

As far as $username and $password having to be set by register_globals...While I'm sure you're right that he has register_globals turned on...he's also not showing us all his code. He doesn't show the form on the login page, etc.

Still, I don't think register_globals registers a normal var from one page to the next. So, unset-ing $username on index.php STILL does nothing for the other pages.

I tend to think perhaps he was mistaken about that being what fixed it. It's not hurting anything to be there, so, it's not like it's going to cause an error and PROVE it doesn't nee to be there.

At any rate, I guess it doesn't matter that much. We all know that the unset() doesn't do anything. I mostly just wanted that confirmation so I'd know I wasn't nuts! :D

marek_mar
12-21-2006, 06:56 AM
$_SESSION is not affected by register_globals, only the EGPCS variables are ($_ENV, $_GET, $_POST, $_COOKIE, $_SERVER).

koyama
12-21-2006, 08:26 AM
...thank you marek_mar for correcting me on this one. I guess Tyree's case will remain a mystery then.

Tyree
12-21-2006, 12:47 PM
The best test for me would be to take his code, take that line out and then make it work without it. I'll see if I have time for that today. :)

Thanks for all the great input!

Tyree
12-21-2006, 02:24 PM
Well, that was pretty painless. I took his code, changed only enough to make it work with my own users table and then axed the unset($username) bit. Works like a charm:
http://tyreeonline.com/tests/rupert-login
I've included some sample user criteria so that it can be tested.

Here's the code:

index.php:


<?php
session_start();
//TYREE - Added session_unset() and removed unset($username)
session_unset();
session_destroy();
//TYREE - Removed $_SESSION = array()
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Session Ender</title>
</head>

<body>
Sample users to try with:<br />
user1/user1pass<br />
user2/user2pass
<form name="login" action="login.php" method="post" >
<table width="300" border="0" cellspacing="0" cellpadding="3">
<tr>
<td>Username:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type="submit" name="Submit" value="Submit" /></td>
</tr>
</table></form>
</body>
</html>


login.php:


<?php
if (!$_POST['username'] || !$_POST['password']) {
//TYREE - I made an assumption as to what badUser.php had in it
include("badUser.php");
exit;

} else {

//TYREE - Changed so that I can connect to my own db
include("../../php-bin/include.php");
//TYREE - Added md5 to the password so that I could match my db
$result = mysql_query( "SELECT * FROM users WHERE UserName='$username' AND Password='".md5($password)."'");
$num_rows = mysql_num_rows( $result );
if ($num_rows != "1") {
include("badUser.php");
exit;

} else {
session_start();
$_SESSION["username"] = $username;
//TYREE - Removed this line so I didn't have to recode my include file: mysql_close( $link );
include("main.php");
}
}
?>


main.php


<?php print '<p>Logged in as: '.$username.' | <a href="index.php">LOG OUT</a></p>'; ?>


badUser.php:


<?php print 'Login Failed. <a href="index.php">Please try again.</a>'; ?>


I had to assume what badUser.php had in it. :)

So, I'm not sure what he ended up changing to make his code work. But, it wasn't the unset($username)! :D



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum