2011-03-20 234 views
1

我在PHP中遇到了一个'setcookie'的问题,我无法解决它。PHP setcookie警告

因此我收到此错误“警告:无法修改头文件信息 - 头文件已经发送(C:\ Program Files \ VertrigoServ \ www \ vote.php:14开始输出)在C:\ Program Files \ VertrigoServ \ www \ vote.php on line 86“

并且这里是文件..第一行86是setcookie($ cookie_name,1,time()+ 86400,'/','',0); 有没有其他方法可以做到这一点?

<html> 
<head> 
<title>Ranking</title> 
<link href="style.css" rel="stylesheet" type="text/css"> 
</head> 
<body bgcolor="#EEF0FF"> 
<div align="center"> 
<br/> 
<div align="center"><div id="header"></div></div> 
<br/> 
<table width="800" border="0" align="center" cellpadding="5" cellspacing="0" class="mid-table"> 
    <tr><td height="5"> 
     <center> 
      </tr> 
      </table> 
     </center> 
    </td></tr> 
    <tr><td height="5"></td></tr> 
</table> 
<br/> 
<?php 
    include "conf.php"; 

    $id = $_GET['id']; 
    if (!isset($_POST['submitted'])) 
    { 
     if (isset($_GET['id']) && is_numeric($_GET['id'])) 
     { 

        </div></td></tr> 
        <tr><td align="center" valign="top"><img src="images/ads/top_banner.png"></td></tr> 
       </table> 
      </form> 
      <?php 
     } 
     else 
     { 
      echo '<font color="red">You must select a valid server to vote for it!</font>'; 
     } 
    } 
    else 
    { 
     $kod=$_POST['kod']; 
     if($kod!=$_COOKIE[imgcodepage]) 
     { 
      echo "The code does not match"; 
     } 
     else 
     { 
      $id = mysql_real_escape_string($_POST['id']); 
      $query = "SELECT SQL_CACHE id, votes FROM s_servers WHERE id = $id"; 
      $result = mysql_query($query) OR die(mysql_error()); 
      $row = mysql_fetch_array($result, MYSQL_ASSOC); 
      $votes = $row['votes']; 
      $id = $row['id']; 
      $cookie_name = 'vote_'.$id; 
      $ip = $_SERVER['REMOTE_ADDR']; 
      $ltime = mysql_fetch_assoc(mysql_query("SELECT SQL_CACHE `time` FROM `s_votes` WHERE `sid`='$id' AND `ip`='$ip'")); 
      $ltime = $ltime['time'] + 86400; 
      $time = time(); 

      if (isset($_COOKIE['vote_'.$id]) OR $ltime > $time) 
      { 
       echo 'You have already voted in last 24 hours! Your vote is not recorded.'; 
      } 
      else 
      { 
       $votes++; 
       $query = "UPDATE s_servers SET votes = $votes WHERE id = $id"; 
       $time = time(); 
       $query2 = mysql_query("INSERT INTO `s_votes` (`ip`, `time`, `sid`) VALUES ('$ip', '$time', '$id')"); 
       $result = mysql_query($query) OR die(mysql_error()); 
       setcookie ($cookie_name, 1, time()+86400, '/', '', 0); 
      } 
     } 
    } 
?> 
<p><a href="index.php">[Click here if you don't want to vote]</a></p><br/> 
<p><a href="index.php">Ranking.net</a> &copy; 2010-2011<br> </p> 
</div> 
</body> 
</html> 

非常感谢!

+0

从过去的爆炸:'cellpadding','bgcolor'等 – fredley 2011-03-20 00:07:25

+1

可能重复[警告:无法修改标头信息 - 标头已发送...](http://stackoverflow.com/questions/3190833/warning -cannot-modify-header-information-headers-already-sent) – mario 2011-03-20 00:10:36

回答

4

在调用header()setcookie()之前,您不能有任何输出。

https://stackoverflow.com/search?q=+headers+already+sent+by
https://stackoverflow.com/tags/php/info

任何输出包括openeing <?php标记之前的任何<html>,或内容的任何printecho ING。另一个罪魁祸首是UTF-8 BOM http://en.wikipedia.org/wiki/Byte_Order_Mark - 大多数文本编辑器都没有明显显示,但在文件开始时会混淆PHP。

+0

好的,谢谢...... – Ranking 2011-03-20 00:08:50

+1

将Unicode BOM添加到罪魁祸首列表中。这是偷偷摸摸的。 – Charles 2011-03-20 01:49:37

+0

@Charles:确实。搜索表明这是最严重的罪犯。 (真正的问题是文本编辑器,幸运的是我的**显示为** **。) – mario 2011-03-20 01:53:48

2

设置cookie需要向客户端发送标头,并且如果输出已经启动,则无法发送标头。

你必须把PHP代码之前的HTML标记,以便在发送之前的任何输出和演示文稿,你应该反正你也单独PHP代码,你可以调用的setcookie。

+0

Matteo,我是PHP新手,我如何区分代码?如果你不介意你能告诉我一个例子吗? – Ranking 2011-03-20 00:10:07

+0

@Ranking here我发布了一个完整的示例如何做到这一点,还有一些原因,你应该这样做,而不是使用ob_start作为一个丑陋的拐杖︰http://stackoverflow.com/questions/5183163/using-php- include-to-separate-site-content/5183401#5183401 – 2011-03-20 00:26:20

0

你需要做的是创建一个漂亮的缓冲区来保存所有标题,直到你处理完。 ob_start为你完成这项工作,这里是对它的参考。 http://php.net/manual/en/function.ob-start.php

当你装完所有的不同的页眉使用ob_get_contents这样 $text = ob_get_contents(); echo($text); ob_end_clean();

我希望这有助于。

+0

谢谢,我会尝试:P – Ranking 2011-03-20 00:20:32

+0

+1这是一种解决方法,但其目的正是为了这一点,并且可能非常适合OP。最后一个示例命令可能仅仅是'ob_end_flush();'我想。 – mario 2011-03-20 00:22:47

+0

事实上,它是一个丑陋的拐杖,它的目的远离解决这些愚蠢的问题。唯一适当的解决方案是使用适当的页面布局。 – 2011-03-20 00:27:40

1

您应该将cookie代码放在页面顶部。一个更好的布局会是这样的:

<?php 
//include config 

//check posted data (included settings cookies) 


//set needed variables 
?> 
<html> 
..... 

你也可以分开的PHP代码和HTML。这通常是我所做的。我的用途通常涉及视图课程或(过去)聪明。但一个简单的例子是在上面的PHP代码的下方添加以下代码,并摆脱的HTML:

<?php    

    if(empty($tpl)) { 
    $tpl = 'index'; 
    } 

    if(file_exists("template/{$tpl}.tpl.php")) { 
    include("template/{$tpl}.tpl.php"); 
    } 
    else { 
    header('Location: /'); 
    } 

?> 

你需要创建一个名为“模板”目录和HTML代码添加到文件以.tpl.php扩展名结尾。 真的,他们只是php页面,但.tpl。部分帮助你记住它的标志。 使它们成为php页面(不是html),所以你可以输出变量

然后在你的代码的varios部分上面,你会设置$ tpl为你想要加载的模板。

这只是一段代码,但它应该给你一个关于如何分离这些数据的一般想法。主要思想是所有的HTML和文本都将在所有编程代码完成后“输出”。

0

在输出任何东西之后,您无法使用PHP设置cookie,并且第一个php标记之前的html确实会计为输出。为了保持纯粹的PHP方法,您必须移动整个部分,以确定如何放置Cookie,并将其设置到最顶端。 或者我在做那种需要额外工作的情况下所做的事情,就是让php回应JavaScript代码来设置cookie。现在,如果你制作或获得一个不错的JS cookie设置功能,并嵌入它或链接到页面。那么你所要做的就是让php在这个时候回调函数调用,并在其中包含正确的数据。那么当页面加载时,php仍然不会设置cookie,但是当浏览器运行js代码时它会。所以你得到你想要的cookie设置。你不必将这些东西移动到顶端。