为什么这个PHP代码不起作用?

时间:2015-12-19 13:21:55

标签: php html error-handling

我不能为我的生活弄清楚为什么这段代码不起作用!

出于某种原因,当我提交表单时,标题不会将我重定向到./index?succes#generalSet。但是,它适用于此页面的旧版本。使用完全相同的代码。

代码:

<span>
    <?php
    if (isset($_GET['success']) === true && empty($_GET['success']) === true) {
        echo 'Details have been updated!<br>
              Please allow up to 7 minutes for changes to take effect.';
    } else {
    if (empty($_POST) === false && empty($errors) === true) {
        $update_data = array(
            'first_name'     => $_POST['first_name'],
            'last_name'      => $_POST['last_name'],
            'email'          => $_POST['email'],
            'description'    => $_POST['description']
        );

        update_user($session_user_id, $update_data);
        header('Location: index?success#generalSet');
        exit();

    } else if (empty($errors) === false) {
        echo output_errors($errors);
    }
    ?>
</span>
<form action="" method="post">
    <ul style="list-style-type:none;padding-top:50px;margin-left:-40px;">
        <li>
            First Name*:<br>
            <input type="text" name="first_name" value="<?php echo $user_data['first_name']; ?>"><br>
        </li>
        <li>
            Last Name:<br>
            <input type="text" name="last_name" value="<?php echo $user_data['last_name']; ?>"><br>
        </li>
        <li>
            Email*:<br>
            <input type="text" name="email" value="<?php echo $user_data['email']; ?>"><br>
        </li>
        <li>
            Description:<br>
            <textarea type="text" rows="7" cols="42" value="<?php echo $user_data['description']; ?>" name="description"></textarea><br>
        </li>
        <li>
            <input type="submit" class="btn btn-primary" value="Save"><br>
        </li>
    </ul>
</form>
<?php }?>

2 个答案:

答案 0 :(得分:2)

您的标题代码:

header('Location: index?success#generalSet');

需要在任何 HTML输出之前出现。但是在文档的前面(至少):

<span>

您需要在发送任何HTML输出之前将标头输出和所有关联的逻辑移动到文件中的某个位置。这是因为HTTP规范不允许在发送内容后调整标头 - 标头必须在开头。

要解决这个问题,可以对结构页面进行评论:

<?php

// Logic here, including redirects

?>
<!DOCTYPE html>
<html>
    <!-- content here -->
</html>

如果您之前已经开始使用它,那么PHP可能会将一些内容存储在输出缓冲区中,然后再将其刷新到Web服务器。如果是这样,这将允许PHP在发送内容之前将标头注入连接。但是,如果您发现这有效,我建议您不要依赖它:标题应始终在内容之前发送。

更新:下面一位有用的评论者指出了这段代码:

   if (isset($_GET['success']) === true && empty($_GET['success']) === true) {
        echo 'Details have been updated!<br>
          Please allow up to 7 minutes for changes to take effect.';
   } else {

这也算作HTML输出,并且很可能阻止标头工作。无论如何,如果您打算立即重定向,为什么要写入屏幕?通常,如果希望消息在HTTP操作中持久存在,则应使用会话。

答案 1 :(得分:1)

关于为什么这可能以前工作但现在不能正常工作的答案可能存在于PHP配置中。 PHP有一个output_buffering指令,它允许PHP在尝试将此输出发送到客户端之前将输出缓冲到一定长度。这意味着如果您在代码运行之前的任何时候都有足够高的指令,那么您将无法获得现在可能获得的 Py_TPFLAGS_HEAPTYPE 错误。如在另一个答案中所提到的,您应该始终尝试在发送任何输出之前设置标题。

相关问题