PHP Sessions not keeping values - php

I have a problem with my PHP (version 5.6) session. They are not being kept between pages, or even when I refresh my page.
On top of all my files I have :
<?php
session_start();
(there is no space or anything before).
When the user click on link, it's calling a function to set the website language to English or French. After some verification on the $_GET["lang"] value, I create the session like that :
$_SESSION["lang"] = $_GET["lang"];
If I do
var_dump($_SESSION["lang"]);
the server return string(2) "fr" or string(2) "en" regarding to which language the user select. Until there, everything is working great ;)
Problem is if I refresh the page, or go to another one, and try to return the session value, it's always NULL...
I know i could user other ways to translate the website, but I need the sessions to work for other functionality of my application (login, ...)
Because it was working few days ago, I first supposed it was a changed on the server, so I've contact my server administrator, but they told me they didn't change anything.
I have the PHP error reporting set to E_ALL but no errors are displayed...
If someone could help me with that, it would be great, i'm stuck on this bug since 3 days now ^^.
Thanks !
EDIT :
session_start();
var_dump($_SESSION["lang"]);
if(!isset($_SESSION["lang"]) || $_SESSION["lang"] == null){
$_SESSION["lang"] = "fr";
}
if(isset($_GET["lang"]) && ($_GET["lang"] == "fr" || $_GET["lang"] == "en")){
$_SESSION["lang"] = $_GET["lang"];
}
var_dump($_SESSION["lang"]);

from the limited code you're providing, my guess is that the $_GET argument isn't always set, which would then set the session to null.
try this...
if(isset($_GET["lang"])) {
$_SESSION["lang"] = $_GET["lang"];
} else {
echo 'lang not set';
}
EDIT: OP provided additional code.
This will return 'fr' if no value, or if an acceptable value hasn't been provided in the URL arguments. it's similar to what you have, however, I've wrapped the argument check in parentheses to make it a little tighter and changed the order. Your code was returning 'en' if nothing was provided.
session_start();
if(isset($_GET['lang']) && ($_GET['lang'] == 'fr' || $_GET['lang'] == 'en')) {
if($_GET['lang'] == 'fr') {
$_SESSION['lang'] = 'fr';
}
elseif($_GET['lang'] == 'en') {
$_SESSION['lang'] = 'en';
}
} else {
$_SESSION['lang'] = 'fr';
}
var_dump($_SESSION['lang']);

I found it !
My index.php file was encoded in UTF-8, i changed it to UTF-8 without BOM and it worked !
Really weird bug, I hope it will help someone ;)

Related

Combine php cookie check with request uri

I'm looking for a way to combine this working script with another check: request uri ?=en or ?=nl. I need this because a php include according to the active language cookie (nl or en) doesn't change immediately after you press the language button. The buttons bring you to [].php?=en - which in fact just refreshes the page. To see the php include in the correct language, you need to refresh the page one more time. Thats a problem. Can anybody help me?
<?php
if( $_COOKIE['lang'] == "nl"){
include ('statement_nl.php');
}
else{
include ('statement_en.php');
}
?>
EDIT:
After a few hours of puzzling I found a way to make it work:
<?php
if( $_COOKIE['lang'] == "nl"){
include ('statement_nl.php'); }
else if (isset($_GET["lang"]) AND ($_GET["lang"]=="nl")) {
include ('statement_nl.php'); }
else if (isset($_GET["lang"]) AND ($_GET["lang"]=="en")) {
include ('statement_en.php'); }
else{
include ('statement_en.php'); }
?>

Is it possible to override a page with another include?

THE PROBLEM
The problem I've having is I can't override the current page with include.
if ($LS::getUser('clan') || isset($_GET['clan']) && !isset($_GET['search'])) {
include("res/templates/clan-overview.php");
} else {
include("res/templates/clan-search.php");
}
I don't get why I can't change the page with clan-search.php because I said that if $_GET['search'] is NOT set execute the else statement. But for some weird reason I'm still getting true even though I said that if the user has a CLAN || $_GET['clan'] AND $_GET['search'].
What I've Tried
That code I put at the top is actually the modified version of my original code which I thought would fix the problem. If you are interested in looking at the original code which I don't think will help you here it is:
if ($LS::getUser('clan') || isset($_GET['clan'])) {
include("res/templates/clan-overview.php");
} else if (isset($_GET['search'])) {
include("res/templates/clan-search.php");
}
#Drew pierce gave you first response as you need to wrap the OR parts as a group. try this:
if (($LS::getUser('clan') || isset($_GET['clan'])) && !isset($_GET['search'])) {

$_SESSION based language selection is not working properly

My website has two languages: English and Russian. These languages' database names are EN and RU.
I use an old php+smarty script. This script's default language selection codes like this:
if(!isset($_SESSION)){
define('LANGUAGE_ID', 'EN');
} else if ($_SESSION['language'] == '')
{
define('LANGUAGE_ID', 'EN');
}
When I want to see a page in Russian, I visit any page with language phrase (?language=RU) like this:
http://www.example.com/index.php?language=RU
But these pages doesn't load in Russian firstly. When I clicked another link or refresh the page, then page loading in Russian. After saved the cookies, then I can see the pages in Russian when first visit. But If I delete the cookies in browser, then I couldn't see in Russian when first visit.
I tried lots of combinations but I couldn't find any solution. Do you have any idea?
Thank you very much...
Edit:
I found some codes in main.class.php:
function __construct($dbh,$smartyBuild) {
$this->dbh = $dbh;
$this->sitevar = #$smartyBuild->FetchSiteVar();
$this->smartybuild = #$smartyBuild;
if($_REQUEST['language'] !='')
{
$_SESSION['language'] = $_REQUEST['language'];
}
else
{
$langaugeAlready = mysql_fetch_array(mysql_query("select value from ".TABLE_PREFIX."sitevars where array_key = 'default_language_feed'"));
if($_SESSION['language'] == '')
{
$_SESSION['language'] = $langaugeAlready['value'];
}
}
if($_SESSION['language'] !='' )
{
define('LANGUAGE_ID', $_SESSION['language']);
}
else
{
define('LANGUAGE_ID', 'EN');
$_SESSION['language'] = 'EN';
}
}
Is the problem related with these codes?
Like I say, without all the code we are guessing a bit at what the problem is but, here goes...
It seems like you're only checking the $_SESSION variable for the language and not the $_GET variable (which gets the language from the URL). Therefore the value only changes after you refresh the page.
Try this. I am assuming your intention is to show English as a default and only Russian if it is defined in the url, but once defined to keep that language until it is put in the URL again.
//start a session. must be called first on all pages you want it to work on
session_start();
//first check if there's a new language coming from the URL
if(isset($_GET['language']))
{
// if we have a new language setting from the URL, check which one and save it in the session.
// we check it is EN or RO before saving into the session since I don't know what you're using it for later. eg part of a DB query which would be a security risk if it is anything other than EN or RO.
if($_GET['language'] == 'EN')
{
$_SESSION['language'] = 'EN';
}
if($_GET['language'] == 'RO')
{
$_SESSION['language'] = 'RO';
}
}
//now check the session variable, which will have been updated above if changed
if(isset($_SESSION['language']))
{
// already have a language saved, so let's use it
define('LANGUAGE_ID', $_SESSION['language']);
}
else
{
// no language from URL and no language saved, so default to english
define('LANGUAGE_ID', 'EN');
}

PHP language detection script

After I read some stuff on-line I came up with this PHP script to detect the browser's language and redirect the user to the correct website's version. Short said, if the user has a browser in Swedish, then the script should redirect to index.php, if not, then it should redirect the user to en.php.
It works fine in some computers and mobile phones and in others it blocks the website. I suppose that the script is not OK and is causing some conflict in older browsers.
So, could you please take a look at my script and tell me if I am doing anything wrong and how can I fix it?
Cheers!
<?php
include ('administration/fonts.php');
?><?php
$lc = ""; // Initialize the language code variable
// Check to see that the global language server variable isset()
// If it is set, we cut the first two characters from that string
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
$lc = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
}
// Now we simply evaluate that variable to detect specific languages
if($lc == "sv"){
header("location: index.php");
exit();
}
else if($lc == "en"){
header("location: en.php");
exit();
}
?>
P.S. - Yes, the script is before the tag and there are no spaces between the "?>" tag and tag.
New answer after added details from the OP.
English users should be redirected, but Swedish user should stay on this site, so we'll rewrite the code like this (I added comments with // Reeno):
<?php
include ('administration/fonts.php');
$lc = ""; // Initialize the language code variable
// Check to see that the global language server variable isset()
// If it is set, we cut the first two characters from that string
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
// Reeno: I added strtolower() if some browser sends upper case letters
$lc = strtolower(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2));
}
// Now we simply evaluate that variable to detect specific languages
// Reeno: Redirect all non-Swedish users to the English page (they can have "en", but also "dk", "de", "fr"...
if($lc != "sv"){
header("location: http://www.domain.com/en.php");
exit();
}
// Reeno: Swedish users stay on this site
?>
HTML code...
Old answer
You check for $lc == "sv" and $lc == "en" but you forgot the third case: $lc could be empty!
Rewrite the if at the end like this, so everybody with a non Swedish browser will get to en.php:
if($lc == "sv"){
header("location: index.php");
exit();
}
else {
header("location: en.php");
exit();
}
?>
btw header("location: ..."); requires an absolute URI like header("location:http://www.domain.com/en.php"); (some clients also accept relative URIs)

PHP session variables change with file include

This question is based on a previous question I asked but is getting messy with edits as I was not sure where the problem could come from. (Please advise if this question needs to be closed)
I develop with PHP 5.3.3 on development environment + Apache 2 (my code works there)
The production server has PHP 5.2.6 and the same server (same code doesn't work here)
Thanks to Melsi on the other question I managed to narrow down the problem to a few lines of code.
The problem is: In an include file I start a session and check for a variable.
Depending on that session variable I include a language file.
The structure is like this:
-index.php
INCLUDE
-menus.php
-lang_fr.php
-lang_en.php
The files are as follows:
INDEX.PHP
<?php
//SET LANGUAGE
if (isset($_GET['lang']) && $_GET['lang'] == 'fr') {
$_SESSION['lang'] = 'fr';
}
else if (isset($_GET['lang']) && $_GET['lang'] == 'en') {
$_SESSION['lang'] = 'en';
}
else {
$_SESSION['lang'] = 'en';
}
include_once 'include/menus.php';
?>
<html>
<head>
<title>building...</title>
</head>
<body>
<?php
echo($links);
?>
<br><br>
print_r($_SESSION);
<br><br>
<?php
print_r($_SESSION);
?>
</body>
</html>
MENUS.PHP
<?php
session_start();
if(isset($_SESSION['lang']) && $_SESSION['lang'] == 'en') {
include_once('lang_en.php');
}
else if(isset($_SESSION['lang']) && $_SESSION['lang'] == 'fr') {
include_once('lang_fr.php');
}
else {
$_SESSION['lang'] = 'fr';
include_once('lang_fr.php');
}
$links = <<<EOT
English
French
EOT;
?>
LAN_EN and FR.PHP
<?php
$lang['test'] = "Test";
?>
This on my local server works and displays the correct session variables when I click on the links.
On the production server I get:
-First load: Array ( [lang] => fr ) (default, correct)
-Click on English link: Array ( [lang] => Tn )
-Click on the French link: Array ( [lang] => Tr )
If I change in the language file 'Test' to 'Pest', the results above are 'Pn' and 'Pr'
I would like to know if there's something wrong with the code or with the configuration production server (according to their support there is nothing wrong) and if so what could be the problem.
Note: The problem disappears when I remove the includes in menus.php
The problem in your code is that you as setting the Setting variables and in Index.php but Starting the Session in Menu.php file. Kindly change thing to:
Index.php
<?php
ob_start();
session_start();
//SET LANGUAGE
if (isset($_GET['lang']) && $_GET['lang'] == 'fr') {
$_SESSION['lang'] = 'fr';
}
else if (isset($_GET['lang']) && $_GET['lang'] == 'en') {
$_SESSION['lang'] = 'en';
}
else {
$_SESSION['lang'] = 'en';
}
include_once 'include/menus.php';
?>
<html>
<head>
<title>building...</title>
</head>
<body>
<?php
echo($links);
?>
<br><br>
print_r($_SESSION);
<br><br>
<?php
print_r($_SESSION);
?>
</body>
</html>
MENUS.PHP
<?php
if(isset($_SESSION['lang']) && $_SESSION['lang'] == 'en') {
include_once('lang_en.php');
}
else if(isset($_SESSION['lang']) && $_SESSION['lang'] == 'fr') {
include_once('lang_fr.php');
}
else {
$_SESSION['lang'] = 'fr';
include_once('lang_fr.php');
}
$links = <<<EOT
English
French
EOT;
?>
I Think this would resolve your problem
If you look closely to my answearin your previous question the very first thing mentioned (written in bold) was exactly this:
Maybe a session is started from a file that is included and this should not happen!
Vineet is correct and I will expand his right answear a bit more!
When you include the file child.php into the father.php you must think of the code found in child.php as being part of father.php One of the first things you do in a father.php script (like index.php) is a session start. You do not start a session in an included script because this might create some conflict as an other session could have been started already.
And if you have many files, (even worse if some of them are both included or executed directly cause of no single entry point) then how easy is to manage all this?!
You said this:
Thanks but the problem doesn't come from the structure of my site
Well this might not be entirely true! The thing is that writing old school code (no mvc, no single entry point, not really object oriented) has the benefit that has a very easy learning curve. HOWEVER while such code is easy to write the thing is that such code requires more skills to avoid errors!
On the other hand the object oriented aproach has more difficulty to get started cause there are more things to learn (objects, prototypes, interface, relatinships (belong-to, is part of) etc etc ) and requires a different behaviour. HOWEVER you definetely will benefit more!
A last thing! Well a well structred-site makes the session manage a thing of a few lines, writen only once at the very begining and that's it all.
I am glad that you are twoards solving you problem!

Categories