故障排除“警告:session_start():无法发送会话缓存限制器 - 标头已发送”

Posted

技术标签:

【中文标题】故障排除“警告:session_start():无法发送会话缓存限制器 - 标头已发送”【英文标题】:Troubleshooting "Warning: session_start(): Cannot send session cache limiter - headers already sent" 【发布时间】:2012-05-23 15:20:39 【问题描述】:

我收到警告:session_start() [function.session-start]:无法发送会话缓存限制器 - 标头已发送(输出开始于错误

如果我将表单数据提交到不同的文件进行处理,它可以工作。但是,如果我将表单数据提交到同一页面,则会出现此错误。

请推荐

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="style.css" rel="stylesheet" type="text/css" />
<title>Welcome</title>


<script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
$(document).ready(function ()  

    $('#nav li').hover(
        function () 
            //show its submenu
            $('ul', this).slideDown(100);

        , 
        function () 
            //hide its submenu
            $('ul', this).slideUp(100);         
        
    );

);
    </script>

</head>

<body>
<table  border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td class="header">&nbsp;</td>
  </tr>
  <tr>
    <td class="menu"><table align="center" cellpadding="0" cellspacing="0" >
    <tr>
    <td>

    <ul id="nav">
    <li><a href="#">Catalog</a>
    <ul><li><a href="#">Products</a></li>
        <li><a href="#">Bulk Upload</a></li>
        </ul>
        <div class="clear"></div>
        </li>


    <li><a href="#">Purchase  </a>

    </li>
    <li><a href="#">Customer Service</a>
    <ul>
        <li><a href="#">Contact Us</a></li>
        <li><a href="#">CS Panel</a></li>

    </ul>           
        <div class="clear"></div>
    </li>
    <li><a href="#">All Reports</a></li>
    <li><a href="#">Configuration</a>
    <ul> <li><a href="#">Look and Feel </a></li>
         <li><a href="#">Business Details</a></li>
         <li><a href="#">CS Details</a></li>
         <li><a href="#">Emaqil Template</a></li>
         <li><a href="#">Domain and Analytics</a></li>
         <li><a href="#">Courier</a></li>
         </ul>
    <div class="clear"></div>
    </li>
    <li><a href="#">Accounts</a>
    <ul><li><a href="#">Ledgers</a></li>
        <li><a href="#">Account Details</a></li>
        </ul>
         <div class="clear"></div></li>

</ul></td></tr></table></td>
  </tr>
  <tr>
    <td valign="top"><table  border="0" align="center" cellpadding="0" cellspacing="0">
      <tr>
        <td valign="top"><table  border="0" cellspacing="0" cellpadding="2">
          <tr>
            <td   valign="top"><table  border="0" cellspacing="0" cellpadding="2">
              <tr>
                <td>&nbsp;</td>
                </tr>
              <tr>
                <td ><strong>-&gt; Products</strong></td>
                </tr>
              <tr>
                <td ><strong>-&gt; Categories</strong></td>
                </tr>
              <tr>
                <td ><strong>-&gt; Sub Categories</strong></td>
                </tr>
            </table></td>
            <td  valign="top"><table  border="0" cellpadding="0" cellspacing="0">
              <tr>
                <td>&nbsp;</td>
                </tr>
              <tr>
                <td>
                  <table  border="0" cellspacing="0" cellpadding="0">
                    <tr>
                      <td >&nbsp;</td>
                      <td ><h2>Manage Categories</h2></td>
                    </tr>
                  </table></td>
                </tr>
              <tr>
                <td >&nbsp;

                </td>
                </tr>
              <tr>
                <td>


</td>
                </tr>

                <tr>
                <td>
                <table  align="center" cellpadding="0" cellspacing="0">
                <tr><td>




<?php


                if (isset($_SESSION['error']))

                

                    echo "<span id=\"error\"><p>" . $_SESSION['error'] . "</p></span>";

                    unset($_SESSION['error']);

                

                ?>

                <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">

                <p>
                 <label class="style4">Category Name</label>

                   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="text" name="categoryname" /><br /><br />

                    <label class="style4">Category Image</label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

                    <input type="file" name="image" /><br />

                    <input type="hidden" name="MAX_FILE_SIZE" value="100000" />

                   <br />
<br />
 <input type="submit" id="submit" value="UPLOAD" />

                </p>

                </form>




                             <?php

session_start();

require("includes/conn.php");


function is_valid_type($file)



    $valid_types = array("image/jpg", "image/jpeg", "image/bmp", "image/gif", "image/png");



    if (in_array($file['type'], $valid_types))

        return 1;

    return 0;


function showContents($array)



    echo "<pre>";

    print_r($array);

    echo "</pre>";



$TARGET_PATH = "images/category";

$cname = $_POST['categoryname'];

$image = $_FILES['image'];

$cname = mysql_real_escape_string($cname);

$image['name'] = mysql_real_escape_string($image['name']);

$TARGET_PATH .= $image['name'];

if ( $cname == "" || $image['name'] == "" )



    $_SESSION['error'] = "All fields are required";

    header("Location: managecategories.php");

    exit;



if (!is_valid_type($image))



    $_SESSION['error'] = "You must upload a jpeg, gif, or bmp";

    header("Location: managecategories.php");

    exit;






if (file_exists($TARGET_PATH))



    $_SESSION['error'] = "A file with that name already exists";

    header("Location: managecategories.php");

    exit;




if (move_uploaded_file($image['tmp_name'], $TARGET_PATH))





    $sql = "insert into Categories (CategoryName, FileName) values ('$cname', '" . $image['name'] . "')";

    $result = mysql_query($sql) or die ("Could not insert data into DB: " . mysql_error());

  header("Location: mangaecategories.php");

    exit;



else







    $_SESSION['error'] = "Could not upload file.  Check read/write persmissions on the directory";

    header("Location: mangagecategories.php");

    exit;



?> 

这是显示的代码

<?php  
                  require("includes/conn.php"); 



                $sql = "select CategoryID, CategoryName, FileName, Status from Categories";

                $result = mysql_query($sql) or die ("Could not access DB: " . mysql_error());



                while ($row = mysql_fetch_assoc($result))

                

                     echo "<table border='0' cellpadding='10'>";


                                        echo "<tr><td>  </td><td>Category ID</td><td>Category Name</td><td>Status</td><td>Edit</td><td>Delete</td></tr>";

                                        echo "<tr><td> <img src=\"images/" . $row['FileName'] . "\" alt=\"\" /> </td>";
                                        echo "<td>". $row['CategoryID'] . "</td>";
                                            echo "<td>". $row['CategoryName'] . "</td>";
                                            echo "<td>". $row['Status']. "</td>";
                                            echo "<td> <a href= 'edit.php?CategoryID=" .$row['id']. "'> Edit </a></td>";
                                            echo "<td> <a href= 'delete.php?CategoryID=" .$row['id']. "'> Edit </a></td>";
                                         echo "</tr> </table>";

                



            ?>

这里什么都没有发生。请推荐

【问题讨论】:

会话开始前不应有任何回声。基本上在更改标题或会话开始之前不应该产生/打印任何输出字符。所以,如果你有回声。或者,如果您的包含文件中的 php 标记(或 html 或任何输出)后有空格,则会出现此错误。 Rahul bhai, session_start(); 应该是 php 页面的第一行以避免此类错误。建议您处理表单数据的所有 php 代码都应该在顶部 在我的情况下,我必须设置没有 BOM 的文件编码。 【参考方案1】:

你会发现我在页面的最顶部添加了 session_start()。我还在页面后面删除了 session_start() 调用。此页面应该可以正常工作。

<?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="style.css" rel="stylesheet" type="text/css" />
<title>Welcome</title>


<script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
$(document).ready(function ()  

    $('#nav li').hover(
        function () 
            //show its submenu
            $('ul', this).slideDown(100);

        , 
        function () 
            //hide its submenu
            $('ul', this).slideUp(100);         
        
    );

);
    </script>

</head>

<body>
<table  border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td class="header">&nbsp;</td>
  </tr>
  <tr>
    <td class="menu"><table align="center" cellpadding="0" cellspacing="0" >
    <tr>
    <td>

    <ul id="nav">
    <li><a href="#">Catalog</a>
    <ul><li><a href="#">Products</a></li>
        <li><a href="#">Bulk Upload</a></li>
        </ul>
        <div class="clear"></div>
        </li>


    <li><a href="#">Purchase  </a>

    </li>
    <li><a href="#">Customer Service</a>
    <ul>
        <li><a href="#">Contact Us</a></li>
        <li><a href="#">CS Panel</a></li>

    </ul>           
        <div class="clear"></div>
    </li>
    <li><a href="#">All Reports</a></li>
    <li><a href="#">Configuration</a>
    <ul> <li><a href="#">Look and Feel </a></li>
         <li><a href="#">Business Details</a></li>
         <li><a href="#">CS Details</a></li>
         <li><a href="#">Emaqil Template</a></li>
         <li><a href="#">Domain and Analytics</a></li>
         <li><a href="#">Courier</a></li>
         </ul>
    <div class="clear"></div>
    </li>
    <li><a href="#">Accounts</a>
    <ul><li><a href="#">Ledgers</a></li>
        <li><a href="#">Account Details</a></li>
        </ul>
         <div class="clear"></div></li>

</ul></td></tr></table></td>
  </tr>
  <tr>
    <td valign="top"><table  border="0" align="center" cellpadding="0" cellspacing="0">
      <tr>
        <td valign="top"><table  border="0" cellspacing="0" cellpadding="2">
          <tr>
            <td   valign="top"><table  border="0" cellspacing="0" cellpadding="2">
              <tr>
                <td>&nbsp;</td>
                </tr>
              <tr>
                <td ><strong>-&gt; Products</strong></td>
                </tr>
              <tr>
                <td ><strong>-&gt; Categories</strong></td>
                </tr>
              <tr>
                <td ><strong>-&gt; Sub Categories</strong></td>
                </tr>
            </table></td>
            <td  valign="top"><table  border="0" cellpadding="0" cellspacing="0">
              <tr>
                <td>&nbsp;</td>
                </tr>
              <tr>
                <td>
                  <table  border="0" cellspacing="0" cellpadding="0">
                    <tr>
                      <td >&nbsp;</td>
                      <td ><h2>Manage Categories</h2></td>
                    </tr>
                  </table></td>
                </tr>
              <tr>
                <td >&nbsp;

                </td>
                </tr>
              <tr>
                <td>


</td>
                </tr>

                <tr>
                <td>
                <table  align="center" cellpadding="0" cellspacing="0">
                <tr><td>




<?php


                if (isset($_SESSION['error']))

                

                    echo "<span id=\"error\"><p>" . $_SESSION['error'] . "</p></span>";

                    unset($_SESSION['error']);

                

                ?>

                <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">

                <p>
                 <label class="style4">Category Name</label>

                   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="text" name="categoryname" /><br /><br />

                    <label class="style4">Category Image</label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

                    <input type="file" name="image" /><br />

                    <input type="hidden" name="MAX_FILE_SIZE" value="100000" />

                   <br />
<br />
 <input type="submit" id="submit" value="UPLOAD" />

                </p>

                </form>




                             <?php


require("includes/conn.php");


function is_valid_type($file)



    $valid_types = array("image/jpg", "image/jpeg", "image/bmp", "image/gif", "image/png");



    if (in_array($file['type'], $valid_types))

        return 1;

    return 0;


function showContents($array)



    echo "<pre>";

    print_r($array);

    echo "</pre>";



$TARGET_PATH = "images/category";

$cname = $_POST['categoryname'];

$image = $_FILES['image'];

$cname = mysql_real_escape_string($cname);

$image['name'] = mysql_real_escape_string($image['name']);

$TARGET_PATH .= $image['name'];

if ( $cname == "" || $image['name'] == "" )



    $_SESSION['error'] = "All fields are required";

    header("Location: managecategories.php");

    exit;



if (!is_valid_type($image))



    $_SESSION['error'] = "You must upload a jpeg, gif, or bmp";

    header("Location: managecategories.php");

    exit;






if (file_exists($TARGET_PATH))



    $_SESSION['error'] = "A file with that name already exists";

    header("Location: managecategories.php");

    exit;




if (move_uploaded_file($image['tmp_name'], $TARGET_PATH))





    $sql = "insert into Categories (CategoryName, FileName) values ('$cname', '" . $image['name'] . "')";

    $result = mysql_query($sql) or die ("Could not insert data into DB: " . mysql_error());

  header("Location: mangaecategories.php");

    exit;



else







    $_SESSION['error'] = "Could not upload file.  Check read/write persmissions on the directory";

    header("Location: mangagecategories.php");

    exit;



?> 

【讨论】:

谢谢,但它仍然在 if (file_exists($TARGET_PATH)) $_SESSION['error'] = "A file with that name already exists"; header("位置:managecategories.php");出口; 并且默认情况下显示具有该名称的文件已存在消息 我发现您没有检查表单是否已提交或首次加载。因此,您在 $TARGET_PATH 中准备图像文件名的代码始终在执行 - 当第一次正常加载页面或发布页面时。您可以通过以下方式检查页面是否首次发布或加载: if ($_SERVER['REQUEST_METHOD'] == 'POST') /* 将代码放在这里 */ 您好,已解决。正如您所建议的错误是因为重复的标头重定向。我删除了重定向标头语句并且它起作用了..非常感谢您 请建议我如何将图像与数据库中的其他图像一起显示在同一页面中【参考方案2】:

我遇到了同样的问题,但我的解决方案不像建议的那样明显。原来我的 php 文件是用 UTF-8 编写的,这导致了问题。我将整个文件的内容复制/粘贴到一个新的 php 文件中(Notepad++ 告诉我这是用 ANSI 而不是 UTF-8 编写的),现在它可以完美运行了。

【讨论】:

我将编码设置为 UTF-8(这是正确的...数据库连接设置为 UTF-8 以用于 SVG)但 PHP 会话停止工作 @JulianB:确保编码设置为“UTF-8 without BOM”。 感谢上帝。没有意识到切换文本编辑器会发生这种情况。非常感谢!【参考方案3】:

上面是罗斯的答案。

首先,将 session_start() 作为第一行代码将意味着您无法将任何对象正确反序列化为会话变量。

出现此问题的原因是 99% 的可能是包含文件末尾的尾随空格(是的 - 我知道这听起来不太可能,但请尝试一下)。有问题的文件在错误消息中。我想支持对我有用的罗斯答案,但这个网站是反直觉的。

忽略无意义的答案。删除尾随空格,换行符等......一切都会好起来的。罗斯知道他在说什么。 将 session_start() 放在文件顶部确实有效,但这不是正确的解决方案。

【讨论】:

只需完全删除关闭的?&gt;,这将永远不会发生。不需要也不推荐 哇,谢谢。从来没有注意到这个简单的错误发生在我身上......非常感谢你【参考方案4】:

在您的代码中将 session_start(); 替换为 @session_start();

【讨论】:

这是一个不错的解决方案。但是,这只是忽略警告而不是修复它。【参考方案5】:

这应该可以解决您的问题。 session_start() 应该在任何字符被发送回浏览器之前调用。在您的情况下,在您调用 session_start() 之前发送了 HTML 和空行。 Documentation here.

为了进一步解释您提交到不同页面时为什么它会起作用的问题,该页面要么不使用 session_start() ,要么在将任何字符发送回客户端之前调用 session_start() !另一方面,当大量 HTML 被发送回客户端(浏览器)时,该页面很晚才调用 session_start()。

更好的编码方法是有一个通用的头文件,它调用连接到 MySQL 数据库、调用 session_start() 并对所有页面执行其他通用操作,并将该文件包含在每个页面的顶部,如下所示:

include "header.php";

这将阻止您遇到的问题,因为还允许您拥有一组通用代码来管理整个项目。在查看您的代码后,我会建议您考虑一些绝对值得您考虑的事情。

<?php
session_start();

                if (isset($_SESSION['error']))

                

                    echo "<span id=\"error\"><p>" . $_SESSION['error'] . "</p></span>";

                    unset($_SESSION['error']);

                

                ?>

                <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">

                <p>
                 <label class="style4">Category Name</label>

                   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="text" name="categoryname" /><br /><br />

                    <label class="style4">Category Image</label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

                    <input type="file" name="image" /><br />

                    <input type="hidden" name="MAX_FILE_SIZE" value="100000" />

                   <br />
<br />
 <input type="submit" id="submit" value="UPLOAD" />

                </p>

                </form>




                             <?php



require("includes/conn.php");


function is_valid_type($file)



    $valid_types = array("image/jpg", "image/jpeg", "image/bmp", "image/gif", "image/png");



    if (in_array($file['type'], $valid_types))

        return 1;

    return 0;


function showContents($array)



    echo "<pre>";

    print_r($array);

    echo "</pre>";



$TARGET_PATH = "images/category";

$cname = $_POST['categoryname'];

$image = $_FILES['image'];

$cname = mysql_real_escape_string($cname);

$image['name'] = mysql_real_escape_string($image['name']);

$TARGET_PATH .= $image['name'];

if ( $cname == "" || $image['name'] == "" )



    $_SESSION['error'] = "All fields are required";

    header("Location: managecategories.php");

    exit;



if (!is_valid_type($image))



    $_SESSION['error'] = "You must upload a jpeg, gif, or bmp";

    header("Location: managecategories.php");

    exit;






if (file_exists($TARGET_PATH))



    $_SESSION['error'] = "A file with that name already exists";

    header("Location: managecategories.php");

    exit;




if (move_uploaded_file($image['tmp_name'], $TARGET_PATH))





    $sql = "insert into Categories (CategoryName, FileName) values ('$cname', '" . $image['name'] . "')";

    $result = mysql_query($sql) or die ("Could not insert data into DB: " . mysql_error());

  header("Location: mangaecategories.php");

    exit;



else







    $_SESSION['error'] = "Could not upload file.  Check read/write persmissions on the directory";

    header("Location: mangagecategories.php");

    exit;



?> 

【讨论】:

在表单开始之前,我有大约 40 行 html 代码。我应该在开始时使用 session_data() 吗?因为即使在 isset 之前使用 session_start 之后,我也会遇到同样的错误。我已经用 html 编辑了代码。请看一下 如果我在第 1 行使用它,我仍然会得到同样的错误。而且我得到一个同名的文件已经存在,没有任何逻辑的消息【参考方案6】:

在页面顶部使用ob_start(); 之前的session_start();,如下所示

<?php
ob_start();
session_start();

【讨论】:

也需要在页面末尾调用 ob_end_flush()。 link 谢谢,但它仍然在 if (file_exists($TARGET_PATH)) $_SESSION['error'] = "A file with that name already exists"; header("位置:managecategories.php");出口; 并且默认情况下显示具有该名称的文件已存在消息 如果我使用 ob_start();和 ob_end_flush(),文件没有打开,但它显示“打开时发生了太多重定向..”【参考方案7】:

对于可能遇到此问题的其他人 - 如果有人不小心从 php 包含文件中留下尾随空格,也会发生这种情况。示例:

 <?php 
    require_once('mylib.php');
    session_start();
 ?>

在上述情况下,如果 mylib.php 在其结束 ?> 标记后有空格,这将导致错误。如果您包含/需要许多文件,这显然会很烦人。幸运的是,错误会告诉您哪个文件有问题。

HTH

【讨论】:

【参考方案8】:

通常当我们在回显或打印后发送标题时会出现此错误。如果此错误出现在特定页面上,请确保该页面在调用 start_session() 之前没有回显任何内容。

不可预测的错误示例:

 <?php //a white-space before <?php also send for output and arise error
session_start();
session_regenerate_id();

//your page content

再举一个例子:

<?php
includes 'functions.php';
?> <!-- This new line will also arise error -->
<?php
session_start();
session_regenerate_id();

//your page content

结论:在调用 session_start() 或 header() 函数之前不要输出任何字符,甚至是空格或换行符

【讨论】:

这发生在我身上,我的 php 代码的 MS Code 格式前导空格。它在我的家庭 DEV 系统上运行良好,但是当我在我的托管站点上安装时,我得到了错误。【参考方案9】:

只需用这个替换 session_start。

if (!session_id() && !headers_sent()) 
   session_start();
  

你可以把它放在任何地方,甚至放在最后 :) 对我来说很好。 $_SESSION 也可以访问。

【讨论】:

【参考方案10】:

在页面顶部使用session_start()

更多详情请阅读链接session_start

【讨论】:

【参考方案11】:

我可以通过删除&lt;?php 标记前面的空格来解决类似的Warning: session_start(): Cannot send session cache limiter - headers already sent

成功了。

【讨论】:

这也发生在我身上,我与这个错误斗争了好几天。我所要做的就是删除 【参考方案12】:

我有一个网站从一台主机转移到另一台主机,它似乎在旧主机上运行良好,但在新主机上的一些页面引发了错误

警告:session_start():无法发送会话缓存限制器 - 标头已发送
虽然我一直保留
 &lt?php
session_start(); 

页面顶部没有空格,之前没有插入任何内容

当我在会话打开时盯着每一页看,这真的让我很烦恼,它在某些页面上工作,在其他页面上运行错误 我选择了有问题的页面,将它们备份,创建新的空白页面,然后简单地复制和粘贴代码,保存并上传,然后繁荣,问题消失了!

这是你们可能需要考虑的问题,可能是页面的编码,或者其他问题,不确定问题的确切来源,但这里有一个修复方法,以防你们遇到类似的问题

干杯!

【讨论】:

【参考方案13】:

在我的情况下,我必须在没有 BOM 的情况下设置文件编码。

【讨论】:

【参考方案14】:

当我将我的网站重定向到 https://(用于 SSL 证书)时,这对我来说就开始了。根据我对这个问题的经验,session_start() 必须在浏览器看到任何 HTML 代码之前。对于我的示例,我在 nav.php 中使用session_start() 来确定导航栏的选项。我最终将session_start() 放在index.php 文件中的php cmets 和每个调用nav.php 的页面之后。我能够在session_start() 之前保留 php cmets,但无法将 HTML cmets 保留在 php 之上。

【讨论】:

【参考方案15】:

检查 php 标签前的多余空格。

【讨论】:

以上是关于故障排除“警告:session_start():无法发送会话缓存限制器 - 标头已发送”的主要内容,如果未能解决你的问题,请参考以下文章

如何用路由器日志快速定位及排除故障

常见系统故障排除

电脑故障排除

Linux常见的系统故障排除

交换机故障排除的方法与步骤

linux命令:常见的系统故障排除