Issue persisting session variables across pages - php

First of all a little bit of background on my setup:
I have a local domain name set up, projects.lumesse.com.
PHP version is 5.4.16 running on IIS 7.
Testing in Chrome (latest stable build).
The problem is as follows:
I have a function called 'getVariable' as follows:
function getVariable($name, $default = "") {
if(isset($_POST[$name])) return $_POST[$name];
if(isset($_GET[$name])) return $_GET[$name];
if(isset($_SESSION[$name])) return $_SESSION[$name];
return $default;
}
Going through this function line by line it returns the post variable if it exists, followed by the get variable, followed by the session variable followed by the default (if none of the others exist).
In another include, which is included directly after the functions include, I have the following line:
$_SESSION["Language"] = getVariable("Language", "FR");
This works fine if I put ?Language=DE - the site displays in German as expected. However from the line above I'd expect that the language is persisted if I strip off the querystring.
The first time this page is hit, with ?Language=DE, it should return the get variable. The line above then sets the session variable. Any calls to this function after this would therefore return the session variable, right?
It is actually returning FR, the default, in the case that no language parameter exists, even if I've set the language beforehand.
Any ideas on what I'm missing would be much appreciated.

Found the answer - I'm used to coding in classic ASP and .net which don't need a line to initialise the session. Solution was to put session_start() in the main includes file.

Related

php main file not seeing included file variable

OK most the answers on S.O. are BACKWARDS from what I am having an issue with. My variable is not seen FROM the included file. I have never ran into this, and it is messing everything up. I was using smarty, but since it cant see the var, I went back to old fashion php templating, and still cannot see the var.. here is the scripts in question (a gaming site ofc).
INCLUDED FILE: prep_feature_game.php
foreach($games->gamexml->game as $game){
$d = parseDate($game['releasedate']);
$game['date_month'] = $d['month'];
$game['date_day'] = $d['day'];
$game['date_year'] = $d['year'];
$game['image_60x40'] = showImage($game['foldername'],'60x40');
$game['genrelist'] = displayGenreList($game['gameid']);
//debugPrint($game);die();
$game_list[] = $game;
}
CONTROL PAGE:
switch ($page) {
default:
include('includes/prep_feature_game.php');
// NOTE $GAME_LIST HAS THE ARRAY ^
display('feature_game');
break;
AND THE DISPLAY FILE: FEATURE_GAME.PHP
<h1><?=SITE_NAME;?>'s Featured Games!</h1>
<table>
<?PHP
// TEST FOR $GAME_LIST
foreach($game_list as $field=>$data){
echo $data['gamename'];
}
/*
this produces the error:
Notice: Undefined variable: game_list in C:\xampp\htdocs\ix2\themes\missingpiece\feature_game.php on line 7
*/
}// end switch page
I have many variations over the years of these templates, and the "included" files have never produced this kind of error. I know that included files act as though the script contained is inserted where the include is at.
why is the receiving script unable to see the variable produced from the included script. These are all included, so it should not be an issue
PS
I noticed this started happening when I upgraded from php v5 - php v7, doubt it has anything to do with that, I havent checked that yet since include files are pretty standard.
Your question is not showing the definition of the display function, but unless you declare $game_list as a global within that function it is out of scope. If you include the template it'll work.
include('includes/prep_feature_game.php');
include('feature_game.php');
Or add parameters to your display function.
display('feature_game', $game_list);
Or if you're using smarty you must assign the variable first.
$smarty->assign('game_list', $game_list);
$smarty->display('feature_game.tpl');

What is function 'sv' in php?

I'm studying a code from CMSimple 3.0 framework, with this line:
if (eregi('login.php', sv('PHP_SELF')))die('Access Denied');
So, it's suppose to display "Access Denied" if the char "login.php" is present in sc('PHP_SELF').
I know that PHP_SELF is the name of the running script (i-e the name of the page being called). But after some research I was not able to find out the role of function sc.
Any idea why?
The documentation for CMSimple tells me:
Returns the server variable $name, if it's set, the empty string otherwise.
The function sv in the version of CMSimple you're working on is defined on line 190 of cmsimple/cms.php (you'll notice that is the only script that does not throw a fatal error when called directly). Although the documented definition is quite brief you'll notice sv does a couple of things:
It creates a global variable array named $_SERVER consisting of the variables in $GLOBALS['HTTP_SERVER_VARS'], unless the array $_SERVER already exists.
The HTTP_SERVER_VARS array contains information such as headers, paths, and script locations. You will find some familiar elements in these arrays, like; PHP_SELF (which is the file name of the current executing script), REMOTE_ADDR, QUERY_STRING, and PHP_AUTH_USER. All variables that you will see sv queries for in this code base.
If/When $_SERVER exists it queries the array for a variable and returns it, unless the variable isn't set; then it returns ''.
The code you posted
if (eregi('login.php', sv('PHP_SELF')))die('Access Denied');
Is comparing the expression 'login.php' to the name of the script that is being executed and exiting with message 'Access Denied' if they match.

How to know if a script was included inside another script

I am new to PHP and very likely I am using the incorrect approach because I am not used to think like a PHP programmer.
I have some files that include other files as dependencies, these files need to have global code that will be executed if $_POST contains certain values, something like this
if (isset($_POST["SomeValue"]))
{
/* code goes here */
}
All the files will contain this code section, each one it's own code of course.
The problem is that since the files can be included in another one of these files, then the code section I describe is executed in every included file, even when I post trhough AJAX and explicitly use the URL of the script I want to POST to.
I tried using the $_SERVER array to try and guess which script was used for the post request, and even though it worked because it was the right script, it was the same script for every included file.
Question is:
Is there a way to know if the file was included into another file so I can test for that and skip the code that only execute if $_POST contains the required values?
Note: The files are generated using a python script which itself uses a c library that scans a database for it's tables and constraints, the c library is mine as well as the python script, they work very well and if there is a fix for a single file, obviously it only needs to be performed to the python script.
I tell the reader (potential answerer) about this because I think it makes it clear that I don't need a solution that works over the already existant files, because they can be re-generated.
From the sounds of it you could make some improvements on your code structure to completely avoid this problem. However, with the information given a simple flag variable should do the trick:
if (!isset($postCodeExecuted) && isset($_POST["SomeValue"]))
{
/* code goes here */
$postCodeExecuted = true;
}
This variable will be set in the global namespace and therefore it will be available from everywhere.
I solved the problem by doing this
$caller = str_replace($_SERVER["DOCUMENT_ROOT"], "", __FILE__);
if ($_SERVER["REQUEST_METHOD"] === "POST" and $caller === $_SERVER["PHP_SELF"])
performThisAction();

Smarty internal error

Looking through the server PHP error log has revealed that a certain type of PHP Notices comes up as the most frequent, and it has to do with Smarty. I've found a question which seems to describe the same error, but there is actually no answer.
The notice is the following (there are different variables stated as undefined):
PHP Notice: Undefined variable: is_admin in /usr/share/php/Smarty/sysplugins/smarty_internal_data.php on line 291
I wonder how I can possibly debug this one since no data (like template name) is provided.
Below I'm gonna give you some idea of the code (which you can read in full detail here since it's all open-source).
So there is one global smarty object which is created in a file called header.php, and further in the same file some global smarty variables are set, including the one from the notice above:
//init Smarty
require_once('Smarty.class.php');
$smarty = new Smarty();
...
$smarty->assign('is_admin', is_admin() ? 1 : 0);
This header.php is then included in every file that needs to show some HTML by calling $smarty->display(...). So I presume that in any file where the $smarty object is present this object has a variable called is_admin. However, it doesn't seem to be the case.
Additionally, "normal" Smarty warnings about unset variables look differently:
PHP Notice: Undefined index: sent_id in /var/www/smarty_dir/templates_c/a5aab2c66c44442365a39981ba9be18e0a1f11ad.file.history.tpl.cache.php on line 123
Any ideas?
Upd.
I've read some logs and I see that such warnings seemingly arise when a user enters a page and gets 302 HTTP status. This may be due to the following code (which is placed after smarty constructor call but before the variables are assigned:
//cookie check
if (!is_logged() && isset($_COOKIE['auth'])) {
if ($user_id = check_auth_cookie()) {
if (user_login('', '', $user_id, $_COOKIE['auth'])) {
header("Location:".$_SERVER['REQUEST_URI']);
return;
}
}
}
So I guess I should move $smarty initialisation after this block and it is likely to help. Still I'm curious about how it relates to the issue.
I think I got it. The issue is really in the piece of code including
header("Location:".$_SERVER['REQUEST_URI']);
return;
My error is that return does not act like exit in this case, because when you call return from a file which is required or incuded into another one, you just return the control to that another file. I wasn't aware of this feature.
'is_admin', is_admin() you are trying to assign the function is_admin() as a variable {$is_admin} to the Smarty template, which according to me, is impossible.
Assign the return result to a variable i.e.:
$var = is_admin();
$smarty->assign('is_admin', $var);

PHP Based session variable not retaining value. Works on localhost, but not on server

I've been trying to debug this problem for many hours, but to no avail. I've been using PHP for many years, and got back into it after long hiatus, so I'm still a bit rusty.
Anyways, my $_SESSION vars are not retaining their value for some reason that I can't figure out. The site worked on localhost perfectly, but uploading it to the server seemed to break it.
First thing I checked was the PHP.ini server settings. Everything seems fine. In fact, my login system is session based and it works perfectly. So now that I know $_SESSIONS are working properly and retaining their value for my login, I'm presuming the server is setup and the problem is in my script.
Here's a stripped version of the code that's causing a problem. $type, $order and $style are not being retained after they are set via a GET variable. The user clicks a link, which sets a variable via GET, and this variable is retained for the remainder of their session.
Is there some problem with my logic that I'm not seeing?
<?php
require_once('includes/top.php'); //first line includes a call to session_start();
require_once('includes/db.php');
$type = filter_input(INPUT_GET, 't', FILTER_VALIDATE_INT);
$order = filter_input(INPUT_GET, 'o', FILTER_VALIDATE_INT);
$style = filter_input(INPUT_GET, 's', FILTER_VALIDATE_INT);
/*
According to documentation, filter_input returns a NULL when variables
are undefined. So, if t, o, or s are not set via URL, $type, $order and $style
will be NULL.
*/
print_r($_SESSION);
/*
All other sessions, such as the login session, etc. are displayed here. After
the sessions are set below, they are displayed up here to... simply with no value.
This leads me to believe the problem is with the code below, perhaps?
*/
// If $type is not null (meaning it WAS set via the get method above)
// or it's false because the validation failed for some reason,
// then set the session to the $type. I removed the false check for simplicity.
// This code is being successfully executed, and the data is being stored...
if(!is_null($type))
{
$_SESSION['type'] = $type;
}
if(!is_null($order))
{
$_SESSION['order'] = $order;
}
if(!is_null($style))
{
$_SESSION['style'] = $style;
}
$smarty->display($template);
?>
If anyone can point me in the right direction, I'd greatly appreciate it. Thanks.
Unbelievable!
After three hours of debugging, I've figured out the problem
HostGator, my no-longer-beloved host, runs their default ini with register_globals ON
I can't believe this.
So my variables of $type was being overwritten with $_SESSION['type'] and they were being treated as the same. So it was a server issue causing the problem, not my coding. That's great to know, but I want my 5 hours of pulling my hair out back.
I hope this helps someone down the road whose using HostGator and is confused as hell.
You need to call the session_start() function . Before accessing the $_SESSION variable.
Then It will retain all SESSION variables to you..
I think you pointed out you have made a call to session_start() in the top.php right? And another thing I notice is that you are validating Integer fields through the PHP Filter. Be sure that they are integer values or you are bound to end up with null values. Do a test to see if the TYPE,ORDER and STYLE values are set before validating. Do keep in mind that, using the php filter is to validate for a certain type and not to store. I dont think that $type would store your data, it would rather be a boolean check. Try assigning the $_GET[] variables to the SESSION VARIABLES. Hope this helps.

Categories