2011-03-20 129 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設置。你不必將這些東西移動到頂端。