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

9
  • 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. Commented Oct 13, 2011 at 3:24
  • 1
    possible duplicate of PHP session side-effect warning with global variables as a source of data Commented Oct 13, 2011 at 3:29
  • 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. Commented Oct 13, 2011 at 5:35
  • 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. Commented Oct 13, 2011 at 6:02
  • 1
    Yes, it should ring alarm bells. php.net/manual/en/security.globals.php Commented Oct 13, 2011 at 7:06

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

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!

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.