Предупреждение PHP setcookie

У меня проблема с setcookie в PHP, и я не могу ее решить.

поэтому я получаю эту ошибку «Предупреждение: невозможно изменить информацию заголовка — заголовки уже отправлены (вывод начался в C:\Program Files\VertrigoServ\www\vote.php:14) в C:\Program Files\VertrigoServ\www\vote. php в строке 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> 

Большое спасибо!


person Ranking    schedule 20.03.2011    source источник
comment
Взрыв из прошлого: cellpadding, bgcolor и т. д.   -  person fredley    schedule 20.03.2011


Ответы (5)


У вас не может быть какого-либо вывода до вызовов header() и setcookie().

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

Любой вывод включает любые <html> перед открывающим маркером <?php или любые print или echo содержания. Другим виновником является спецификация UTF-8 http://en.wikipedia.org/wiki/Byte_Order_Mark - который не отображается в большинстве текстовых редакторов, но сбивает с толку PHP в начале файлов.

person mario    schedule 20.03.2011
comment
@Чарльз: Действительно. Поиск показывает, что это худший преступник. (Настоящая проблема, однако, заключается в текстовых редакторах. К счастью, мой показывает это визуально как ‹FEFF›.) - person mario; 20.03.2011

Установка файла cookie требует отправки заголовка клиенту, и вы не можете отправлять заголовки, если вывод уже начался.

Вы должны поместить PHP-код перед HTML-разметкой, чтобы вы могли вызвать setcookie до того, как будут отправлены какие-либо выходные данные, а также отделить PHP-код от представления, что вы должны сделать в любом случае.

person Matteo Riva    schedule 20.03.2011
comment
Маттео, я новичок в PHP, как мне разделить код? Если вы не возражаете, можете ли вы показать мне пример? - person Ranking; 20.03.2011
comment
@Ranking здесь я разместил полный пример того, как это сделать, а также несколько причин, почему вы должны делать это именно так, а не использовать ob_start в качестве уродливого костыля: stackoverflow.com/questions/5183163/ - person Your Common Sense; 20.03.2011

Вы должны поместить код cookie вверху страницы. Лучшей компоновкой было бы что-то вроде этого:

<?php
//include config

//check posted data (included settings cookies)


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

Вы также можете разделить код php и html. Это обычно то, что я делаю. Мое использование обычно связано с классом представления или (в прошлом) smarty. но быстрым примером может быть добавление этого кода в нижнюю часть приведенного выше php-кода и избавление от html:

<?php               

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

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

?>

ВАМ нужно будет создать каталог под названием «templates» и добавить html-код к файлам, которые заканчиваются расширением .tpl.php. На самом деле это просто php-страницы, но .tpl. Часть поможет вам вспомнить, что это просто разметка. Сделайте их php-страницами (не html), чтобы вы могли выводить переменные

Затем в различных частях вашего кода выше вы должны установить $tpl в качестве шаблона, который вы хотите загрузить.

Это всего лишь базовый фрагмент кода, но он должен дать вам общее представление о том, как разделить эти данные. Основная идея заключается в том, что весь html и текст будут выводиться "после" выполнения всего программного кода.

person dbers    schedule 20.03.2011

Что вам нужно сделать, так это создать хороший буфер для хранения всех заголовков, пока вы не прекратите обработку. ob_start сделает всю работу за вас, и вот ссылка на него. http://php.net/manual/en/function.ob-start.php

Когда вы закончите загрузку всех разных заголовков, используйте ob_get_contents, например this $text = ob_get_contents(); echo($text); ob_end_clean();

Надеюсь, это поможет.

person tinymark    schedule 20.03.2011
comment
+1 Это обходной путь, но он предназначен именно для этого и, вероятно, хорошо подходит для OP. Команды последнего примера, вероятно, эквивалентны только ob_end_flush();, я думаю. - person mario; 20.03.2011
comment
На самом деле это уродливый костыль, и цель его далека от решения таких глупых проблем. Единственное правильное решение — использовать правильный макет страницы. - person Your Common Sense; 20.03.2011

Вы не можете использовать PHP для установки файла cookie после того, как что-либо было выведено, и html перед первым тегом php считается выводом. чтобы придерживаться чисто php-метода, вам нужно переместить всю часть определения того, что помещать в файл cookie, и настроить его на самый верх. или то, что я делаю в ситуациях, когда для этого потребуется много дополнительной работы, чтобы сделать так, чтобы php вывел код JavaScript для установки файла cookie. теперь, если вы создадите или получите хорошую функцию настройки файлов cookie JS и либо встроите ее, либо свяжете с ней на странице. тогда все, что вам нужно сделать, это заставить php повторить вызов функции с правильными данными в нем в этот момент. затем, когда страница загружается, а php все равно не будет устанавливать cookie, но когда браузер запускает код js, он будет. и поэтому вы получаете то, что хотите, чтобы файл cookie был установлен. и вам не нужно было перемещать вещи наверх.

person Kit Ramos    schedule 19.04.2012