首页 > 解决方案 > 标头已经发送,php mvc

问题描述

所以我对php有点陌生,我在一个必须使用模型视图控制器结构的项目上工作。我的文章页面上有一个问题,人们可以在其中发表评论。当他们发布它时,脚本必须使用新发布的评论重新加载页面,但我弹出了这个“标题已发送”错误。我阅读了关于这个问题的几乎所有现有主题(编辑:包括“如何修复已发送错误的标头”),我尝试了很多东西,包括在我的 php.ini 上设置“output_buffering = on”,我的代码被编码在没有 BOM 的 UTF-8...

我找到了绕过它的解决方案,但我很想知道为什么我会遇到这个问题以及如何以更好的方式纠正它。我找到的解决方案是放置一个 ob_start() 和 ob_get_contents() 包装我的模板。

这是我的文章页面代码:

<?php ob_start();
$title = htmlspecialchars($article['title']);
?>
<!-- Display de l'article -->
<article class="articleBox mx-auto border border-white m-3">
    <h2 class="display-3 mb-4"><?=htmlspecialchars(ucfirst($article['title']));?></h2>
    <div class="text-justify">
        <p><?=nl2br(htmlspecialchars($article['content']));?></p>
        <p class="text-right mt-5">Publié le <?=htmlspecialchars($article['date_posted']);?>, par
            <?=htmlspecialchars($article['author']);?></p>
        <?php if ($article['date_updated']) {
    echo '<p class="text-right">Mis à jour le ' . htmlspecialchars($article['date_updated']) . '</p>';
}?>
    </div>
</article>
<hr>
<!-- Display des commentaires -->
<section id="comments" class="d-flex flex-lg-row flex-column justify-content-around m-5">
    <div id="getComments" class="col-12 col-lg-6">
        <h3 class="h2">Commentaires</h3>
        <?php
if ($comments->rowCount() > 0) {
    while ($comment = $comments->fetch()) {?>
        <div class="commentBox m-4">
            <div>
                <p><strong><?=htmlspecialchars($comment['author'])?></strong>, le
                    <?=htmlspecialchars($comment['date_posted'])?> : </p>
            </div>
            <p><?=nl2br(htmlspecialchars($comment['comment']))?></p>
            <form method="POST" action="signalComment.php?id=<?=$comment['id']?>&amp;postId=<?=$article['id']?>">
                <?php if ($comment['signaled'] === 'yes') { 
                            echo '<p class="signaled small text-left text-lg-right">Ce commentaire a été signalé.</p>'; } 
                            else if($comment['signaled'] === 'ok') {
                             echo '<p class="signaled small text-left text-lg-right">Ce commentaire a été validé.</p>';} 
                            else { echo '<input class="signalButton" type="submit" value="Signaler">';}?>
            </form>
        </div>
        <?php
    }
} else {?>
        <h4 class="h3">Aucun commentaire</h4>
        <?php
    } ?>
    </div>
    <!-- Poster un commentaire -->
    <div id="postComment" class="col-12 col-lg-6 mt-5 mt-lg-0">
        <form class="box" method="POST" action="article.php?action=addComment&amp;id=<?=$article['id']?>">
            <h3 class="h2">Laisser un commentaire</h3>
            <p class="text-left"><input maxlength="15" class="input mt-3" type="text" name="author" id="author"
                    placeholder="votre nom" required></p>
            <textarea class="textarea m-4" name="comment" id="comment" cols="40" rows="5"
                placeholder="votre commentaire" required></textarea><br>
            <p><input type="submit" value="Envoyer"></p>
        </form>
    </div>
</section>
<?php
$content = ob_get_clean();
require 'template.php';

我的模板代码(带有 ob_start 和 ob_get_contents):

<?php ob_start();?>
<!DOCTYPE html>
<html lang="fr">
<head>
    <title>Jean Forteroche - <?=$title?></title>
    <link rel="icon" type="image/png" href="public/images/logoJF.png">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit = no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- CSS Animate -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css">
    <!-- CSS Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <!-- CSS -->
    <link rel="stylesheet" href="public/css/style.css">
    <!-- GOOGLE FONTS -->
    <link href="https://fonts.googleapis.com/css?family=Dancing+Script&display=swap" rel="stylesheet">
</head>
<body>
    <header>
        <?php include 'header.php';?>
    </header>
    <main class="text-center mb-5">
        <?=$content;?>
    </main>
    <footer>
        <?php include 'footer.php';?>
    </footer>

    <!-- JS Bootstrap -->
    <script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous">
    </script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous">
    </script>
</body>
</html>
<?php ob_get_contents();

我在前端控制器上的功能:

public function addComment($postId, $author, $comment)
{
    try {
        if (isset($_POST['author']) && !empty($_POST['author']) && isset($_POST['comment']) && !empty($_POST['comment']))
        {
            $commentManager = new CommentManager;    
            $input = $commentManager->postComment($postId, $author, $comment);
            header('Location: article.php?id='.$postId.'#comments');
        }
        else
            throw new Exception('emptyInputs');
    } catch(Exception $e) {
        $this->error($e);
    }
}

这是消息错误,说问题来自第 24 行,在这里我将变量 $content 称为我的文章页面。当我尝试将所有 html 放在同一页面上时,它说错误来自我调用变量 $article['content'] 的行

Warning
: Cannot modify header information - headers already sent by (output started at /opt/lampp/htdocs/tests/projet4/view/frontend/template.php:24) in
/opt/lampp/htdocs/tests/projet4/controller/frontend/frontend.php
on line
123

谢谢你的帮助 !

标签: php

解决方案


header()虽然从您的示例中不是 100% 清楚,但是当初学者在进行调用之前尝试输出页面的一部分时,最常发生此错误。

一旦你有echo任何东西出来,标题就会被发送,所以你需要确保header()在任何页面生成代码之前发生任何调用,无论是对标签echo之外的 HTML的调用<?php ?>

这里的一个常见问题是无意中包含了一些空格,通常在<?php文件顶部之前或在关闭之后?>

当您使用 MVC 方法时,良好的做法将规定只有您的模板/视图文件应该包含 HTML,并且任何 PHP 脚本的第一个字符应该是<?php,并且您不应该?>在文件末尾关闭以确保任何尾随空格不会包含在您的页面视图中。


推荐阅读