PHP会话变量随文件include而变化

时间:2011-10-13 03:14:21

标签: php session-variables

这个问题是基于之前的question I asked,但由于我不确定问题可能来自哪里,因此编辑工作变得混乱。 (请告知是否需要关闭此问题)

我在开发环境+ Apache 2上开发PHP 5.3.3(我的代码在那里工作) 生产服务器有PHP 5.2.6和相同的服务器(相同的代码在这里不起作用)

感谢Melsi在另一个问题上,我设法将问题缩小到几行代码。

问题是:在包含文件中,我启动会话并检查变量。 根据该会话变量,我包含一个语言文件。

结构是这样的:

-index.php
INCLUDE
    -menus.php
    -lang_fr.php
    -lang_en.php

文件如下:

的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和FR.PHP

<?php

$lang['test'] = "Test";

?>

当我点击链接时,我的本地服务器上的这个工作并显示正确的会话变量。

在生产服务器上我得到:

- 首次加载:数组([lang] =&gt; fr)(默认,正确)

- 点击英文链接:数组([lang] =&gt; Tn)

- 点击法语链接:数组([lang] =&gt; Tr)

如果我将语言文件'Test'更改为'Pest',则上面的结果为'Pn'和'Pr'

我想知道代码或配置生产服务器是否有问题(根据他们的支持,没有任何问题),如果是,那可能是什么问题。

注意:当我删除menus.php中的包含时,问题就消失了

2 个答案:

答案 0 :(得分:3)

您的代码中的问题是您在设置变量和在Index.php中设置但在Menu.php文件中启动会话。请改变一下:

的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;

?>

我认为这可以解决您的问题

答案 1 :(得分:2)

如果您在上一个问题中仔细查看我的answear,那么提到的第一件事(用粗体书写)就是这样:

也许会从包含的文件启动会话,这不应该发生!

Vineet是正确的,我会更多地扩展他的正确的衣服!

当你将文件child.php包含到father.php中时,你必须将child.php中的代码视为father.php的一部分你在father.php脚本中做的第一件事(比如index) .php)是一个会话开始。您不会在包含的脚本中启动会话,因为这可能会产生一些冲突,因为其他会话可能已经启动。

如果你有很多文件,(如果有一些文件被包含或直接执行,更糟糕的是没有单一的入口点)那么管理这一切有多容易?!

你这样说:

  

谢谢,但问题不是来自我网站的结构

这可能不完全正确!问题在于编写旧学校代码(没有mvc,没有单一入口点,不是真正的面向对象)具有非常容易学习的好处。 HOWEVER 虽然这样的代码很容易编写,但这样的代码需要更多的技巧来避免错误!

另一方面,面向对象的方法更难以入手,因为有更多的东西需要学习(对象,原型,界面,关系(属于,属于)等等)并且需要不同的行为。 HOWEVER 你定义会受益更多!

最后一件事!一个结构良好的网站会使会话管理成几行,只在一开始就写一次,就是这样。

我很高兴你是解决问题的两个人!