与 $_SESSION 和对象缓冲的意外交互


unexpected interaction with $_SESSION and object buffering

编辑:发送标头重定向后我没有退出。

在包含文件的输出缓冲区内回显会话值时,如果稍后在脚本中更改了该值,则后面的值是回显的值。

我们的网站使用内部框架,其中每个页面都在自己的文件中,该文件包含在index.php中。索引文件在缓冲区中捕获包含文件的输出,并将其存储到变量中。它执行一些其他操作,然后回显页眉、页脚和捕获的包含文件。

问题是,在遵循 POST to GET 模式时,$_SESSION的行为出乎意料:

发布到表单,它会在会话中设置某些内容,然后执行 get 重定向到另一个页面。在重定向的页面上,如果您从会话中回显某些内容,然后在 echo 语句之后对其进行操作,最终结果是 echo'd 的任何内容都反映了以后的更改。unset也是如此;从会话中回显某些内容,然后unset它,结果是它回显并空字符串。

下面是一个基本示例:

形式.php

if (!empty($_POST['string'])) {
    $_SESSION['message'] = $_POST['string'];
    header("Location: ./index.php?page=formHandler");
    //EDIT - This was not in the original code
    //exit;
} else {
    ?>
    <form action="index.php?page=form" method="post">
        <input type="text" name="string"><input type="submit" />
    </form>
    <?php
}

表单处理程序.php

if (isset($_SESSION['message'])) {
    echo $_SESSION['message'];
    $_SESSION['message'] = "changed";
}

索引.php

session_start();
ob_start();
include $_GET['page'] . ".php";
$page = ob_get_clean();
echo $page;

那么,会发生什么:

从表单开始.php(包含在索引中(

输入一个值,发布它。

始终显示文本"changed",即使它是在 echo 语句之后设置的。

为了

举例起见,这被简化;标头是由重写触发的,而不是获取参数和其他一些东西,但想法就在那里。

所以我的问题是是什么导致了这种意外行为,我该怎么做才能解决它?

使用 PHP 5.4

更新:我要冒昧地猜测代码中的某个地方有一个你没有共享的双重重定向。这将导致浏览器显示"已更改"而不是输入的字符串,因为在页面的第二次加载时,$_SESSION["消息"]已经设置为"已更改">

原答案:

你的代码给了我一个 $_POST['string'] 未定义的错误,所以我改变了

if ($_POST['string']) {

在形式上.php到

if (isset($_POST['string']) {

它运行正常,回显出我在表单中输入的字符串。

编辑:我已经如上所述在没有isset的情况下进行了测试,虽然我仍然在index.php?page=form上收到"未定义的索引:字符串"错误,但页面索引.php?page=formHandler确实回显出输入到表单中的文本而不是"更改">

代码中是否有其他未共享的内容导致了问题?