Page 1 of 1

Brain Taxing Session Problem

Posted: Thu Dec 16, 2004 4:59 pm
by deusiah
Hi,

I'm posting here as a last resort. This problems quite a long one and to answer it your going to have to either spot something obvious I have over looked or have written PHP lol. I have discussed this problem with a fellow coder to no avail. This is really getting at me. It's never good enough for me to fix something I have to know why it was broken.

The problem I have is not so much of a problem as it is a question. I have fixed my problem but it's not good enough, I want to know it's cause.

I'll explain more. I have build (and still am building) my own CMS (http://lostheaven.co.uk) for an example of it. Sessions have never been a problem until I created some code to read some session variables.

I normally read variables like this:

Code: Select all

variable($session_username, 'users_username', 'session', NULL);
variable($session_user_id, 'users_user_id', 'session', NULL);
This works perfectly fine for most people. The code above uses the function below:

Code: Select all

function variable(&$variable, $name, $type, $define_as) {

	if (phpversion() <= "4.1.0") {
		$GET = &$GET_VARS;
		$POST = &$POST_VARS;
		$SESSION = &$HTTP_SESSION_VARS;
		$COOKIE = &$COOKIE_VARS;
		$SERVER = &$HTTP_SERVER_VARS;
		$ENV = &$HTTP_ENV_VARS;
	} else {
		$GET = &$_GET;
		$POST = &$_POST;
		$SESSION  = &$_SESSION;
		$COOKIE  = &$_COOKIE;
		$SERVER = &$_SERVER;
		$ENV = &$_ENV;
	}

	if (eregi('get', $type)) {
		$type = $GET;
	} elseif (eregi('post', $type)) {
		$type = $POST;
	} elseif (eregi('session', $type)) {
		$type = $SESSION;
	} elseif (eregi('cookie', $type)) {
		$type = $COOKIE;
	} elseif (eregi('server', $type)) {
		$type = $SERVER;
	} elseif (eregi('env', $type)) {
		$type = $ENV;
	}

	if (isset($type[$name])) {
		// Escape those damn quotation marks!
		if (!get_magic_quotes_gpc()) {
			$variable = addslashes($type[$name]);
		} else {
			$variable = $type[$name];
		}
	}
	else { $variable = $define_as; }
}
Pretty simple stuff. Here's the problem. When I use that method for getting the session details sometimes it dosn't always work on users PC. It either does work for you or it dosn't. It dosn't work one time and not the other. For some people it works for others it dosn't.

If I get the session variables this way:

Code: Select all

$session_username = $_SESSION['users_username'];
$session_user_id = $_SESSION['users_user_id'];
It works all the time for everyone. So that's the problem fixed but why does it do this?

Posted: Thu Dec 16, 2004 5:20 pm
by rehfeld
im not positive, but dont dont you need to call global on the $HTTP_*_VARS

they arent superglobals, so they dont exist inside the functions scope unless you call global on them. also i didnt know $GET_VARS existed, i though all of them were $HTTP_*

btw- obviously you must use that function a whole lot. i would get those slow regular expressions out of there, they arent needed.

Code: Select all

$name = strtolower($name);

if ($name == 'get') {

}
although i dont know why your having the problem w/ just session vars(i would think that you would be having problems w/ get, cookie, and post too), im thinking your not accounting for having to use session_register and the like in older versions

Posted: Fri Dec 17, 2004 3:58 am
by deusiah
Thank you for your reply rehfeld.

Yes your right about the $HTTP vars, I assumed it was a superglobal. Well you learn something new everyday. I also set register globals to off so it sounds like a likely cause however... There is one problem with your conclusion however I'm running PHP 4.3.9 and so should be using the super globals anyway. Sorry for not mentioning this earlier.

Even if the php version was being reported back incorrectly. As you said nothing else should be working at all. Also why will work all the time for me yet never work for someone else?

Yes I use that "variable" function a lot and as soon as I posted it I thought to myself "hmm I'm probably going to get picked up on this one", you must have very keen eyes ;). I was too lazy to edit my post, but did fixe the code.

I didn't think of using the strtolower function, it didn't spring to mind so thank you very much for the suggestion of it's use. It'll no doubt save a few errors when one of my fellow site admins is developing code for the system . It makes you wonder why I had a regex in there in the first place? Coding plus tiredness can equal some odd results as I keep finding out.

The session register thing did spring to spring to mind but I shouldn't be using it with register globals off and if I'm using $_SESSION or $HTTP_SESSION_VARS.

What can I say, this problem is odd! I told you it was brain taxing lol. I don't mind code throwing up an error but this is just confusing.

Posted: Fri Dec 17, 2004 2:02 pm
by rehfeld
i havent used less than 4.1 for a long time, and when i did i was a complete newbie, so my knowledge of versions less than 4.1 is extremely limited. same goes for back before _SESSION existed(i never used sessions before that point)

but i did spot this

$type = $COOKIE;

your making a copy of it, i _think_ you should make that a reference


also, your comparing if less than or equal to 4.1, use the old style vars. starting w/ 4.1 the new style existed, so it should be just less than 4.1, not inclusive. you should also use version_compare() or another method of identifying in case the version is 4.x.RC2 etc...

you really should download an older version of php and install it.
thats the only way your going to make this project work well w/ older versions of php





sessions werent even built in until 4.0, and i doubt your willing to write your own session module :) and 4.1 is so close to 4.0, to me it just seems like a lot of work and disadvantages just to support an extremely small range of customers. espescially since theres VERY few host that still run such old versions of php.

personally, i wouldnt even try and support less than 4.1. but thats me :)

but if i had to, i think my approach would be to just exclusively use the $HTTP_*_VARS instead of the new superglobals. yes you now need to call global on everything inside a function, or pass it directly into the function, but no matter what other solution you come up with, your going to HAVE to do that anyway if you want to support older versions. theres no way to make a user_defined superglobal. so you might as well just use the old vars...


put this at the top of the script in the global scope(not inside a function)

Code: Select all

<?php

if (!function_exists('session_start')) {
   exit('no session support, you must upgrade');
}

session_start();


// check if they are using a NEWER version of php. if so, we need to make sure the $HTTP_*_VARS exist
// in newer versions, although default is to still populate the $HTT_* vars, php recomends turning
// it off in php.ini for performance reasons. if they did, we must create them.

if (isSet($_SESSION)) { // since 4.1

    if (!isSet($HTTP_GET_VARS)) {
        $HTTP_GET_VARS =& $_GET;
    }
    if (!isSet($HTTP_POST_VARS)) {
        $HTTP_POST_VARS =& $_POST;
    }
    if (!isSet($HTTP_COOKIE_VARS)) {
        $HTTP_COOKIE_VARS =& $_COOKIE;
    }
    if (!isSet($HTTP_SERVER_VARS)) {
        $HTTP_SERVER_VARS =& $_SERVER;
    }
    if (!isSet($HTTP_ENV_VARS)) {
        $HTTP_ENV_VARS =& $_ENV;
    }
    if (!isSet($HTTP_POST_FILES)) {
        $HTTP_POST_FILES =& $_FILES;
    }
    if (!isSet($HTTP_SESSION_VARS)) {
        $HTTP_SESSION_VARS =& $_SESSION;
    }

}


if (!get_magic_quotes_gpc()) {

    // array_map is since 4.06, so you may need to write your own version of it.
    function addslashes_deep(&$value) {
       is_array($value) ? array_map('addlashes_deep', $value) : addslashes($value);
    }

    addslashes_deep($HTTP_GET_VARS);
    addslashes_deep($HTTP_POST_VARS);
    addslashes_deep($HTTP_COOKIE_VARS);

}





?>

Posted: Fri Dec 17, 2004 5:36 pm
by deusiah
Thanks again for your reply rehfeld.

Did you write all of that code just for my benefit? I'm sorry you went to all that trouble I was only after an answer as to why the code worked for some and not others yet your focusing on pre 4.1 compatibility and I believe it's my fault for not explaining myself correctly.

I have never used 4.1 ever I have only been working with PHP for several months and when you read up on how things work and examine what the manual says it gives you the impression that you have to use $HTTP vars for previous versions and everything will be fine. I was also beginning to wonder why I tried to support 4.1. That code was written quite a long time ago and I have learned much since then. When I wrote it I wasn't too sure if there were many servers using that version, you never know it could be considered the most stable release or something. Now I see it's an old version which is probably only installed on very few servers I plan to drop the "limited" support I had tried to provide for it.

When I said it works for me but not others I am referring to the code being used on the same site. I had not run into this problem till I wrote another piece of script. Perhaps I best briefly explain what the script is and how it works. In the downloads area of my site there is one particular download that you must pay "Bank Notes" for (a fictional site currency). Normally when you click download on your selected file the script sets a header location to the file to be downloaded but in this case it directs you to the URL of the pay page whilst passing on the download id. It's at this very page the problem "sometimes" occurs when I try to use my function to retrieve the needed session variables. I say sometimes because for me it works every time without fail, also for another one of my staff it works however two more of my staff I have spoken to have reported errors. I traced the error down to the session variables not being picked up by my function. The session variables are set up correctly before they are taken to that page I have verified this. If I don't use my function then everything works fine for everyone.

So I don't have a problem with getting my code to work but more of a problem understand what caused the code to fail when using my variables function?

Thanks for all your help rehfeld. Hopefully you will be able to shed some light on this matter. Sorry I didn't explain myself better the first time around.