0

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
    <a href="/index.php?lang=en">English</a>&nbsp;&nbsp;
    <a href="/index.php?lang=fr">French</a>
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

Community
  • 1
  • 1
龚元程
  • 417
  • 1
  • 5
  • 14
  • 1
    Once in a while duplicates are allowed, and the code here is distinct enough from your first question. -- First thing you should fix is your sloppy formatting and/or curly braces (omitting is usually bad). It's not clear how your first snippet behaves. -- Second, your problem might be that $_SESSION variables get mapped into the global scope. Thus the `$lang['text']=` assignment actually overwrites the first `[0]` character of the shared session/global `$lang` variable. – mario Oct 13 '11 at 03:24
  • 1
    possible duplicate of [PHP session side-effect warning with global variables as a source of data](http://stackoverflow.com/questions/175091/php-session-side-effect-warning-with-global-variables-as-a-source-of-data) – mario Oct 13 '11 at 03:29
  • there is a lot of mess in here, like mario mentioned, but I would also advice on changing your flow - if you deal with the lang settings in the index, why not do the lang checks *before* the menus include, so instead of a (annoying) redirection you could have everything set up to include the correct file in the first view? This will also clean up some of the clutter in your code, and instead of checking again on $_SESSION you could check on one variable you define on the top of your index.php. Do that and you won't wonder "what comes from where". – Dvir Oct 13 '11 at 03:30
  • I see no mess here. I just replaced the tabs (which apparently don't work on SO) by spaces. Looks pretty clean to me. @mario: Looks like it was a duplicate variables problem... I can't believe that. How can it happen on 2 machines with same server?? Dvir: Thanks for the redirection tip, I changed it too. – 龚元程 Oct 13 '11 at 04:12
  • 1
    Okay, take it back, code looks excellent. -- Investigate if `register_globals` are enabled and the compatibility flag in PHP 5.2.x as mentioned in the duplicate. It's certainly a rubbish configuration on your production server then, if the exact same code is working fine on your development system. – mario Oct 13 '11 at 05:35
  • @mario: The host wouldn't let me change (even look at) the server or php config. Though changing the session variable name fixed my problem and codes work on both sides. Thanks a lot. – 龚元程 Oct 13 '11 at 05:59
  • 1
    Look into `phpinfo()`. Or `print_r(ini_get_all());`. That should tell you the exact configuration pertaining to register_globals and the session bug. That's in fact one of the few dangerous settings where you should talk to the hosting service - if it's there. – mario Oct 13 '11 at 06:02
  • @mario: register_globals is OFF on my server, but it's ON on the host. Does it need to be changed? Do I need to worry about the host's security or other? (because I asked about my session variables and he said there's nothing wrong on the server and that he knows what he is doing...) – 龚元程 Oct 13 '11 at 07:04
  • 1
    Yes, it should ring alarm bells. http://php.net/manual/en/security.globals.php – mario Oct 13 '11 at 07:06

2 Answers2

3

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
    <a href="/index.php?lang=en">English</a>&nbsp;&nbsp;
    <a href="/index.php?lang=fr">French</a>
EOT;

?>

I Think this would resolve your problem

Vineet1982
  • 7,730
  • 4
  • 32
  • 67
2

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!

Community
  • 1
  • 1
Melsi
  • 1,462
  • 1
  • 15
  • 21
  • I noted the different approaches in your other answer. It would be overkill to rewrite this project from scratch but I will definitely take it into account for the next one, although I prefer the old school approach for php since it is clean and straight forward (note that my code works fine as it is and the problem comes from the production server as explained in the comments above). Thanks for the help Melsi. – 龚元程 Oct 13 '11 at 10:10